Use spring reactive webclient to pass protobuff request - java

I am using spring framework reactive webclient to make a call like below
webClient.post()
.uri("/v/score/$model")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(gson.toJson(request))
.accept(MediaType.APPLICATION_JSON)
.header("Client-Id", clientId)
.awaitExchange()
.awaitBody<ScoringResponse>()
which is working fine. Now I wan to pass the request as a protobuff object instead of json. How can I do that ?

Set the media type to application/octet-stream and pass your proto model in a byte array form by using the .toByteArray() method. On the receiving end you can use the static method {proto generated class}.parseFrom({your bytes come here}) to rebuild the proto object.
Do not forget the POST method request is basically a body content ;)

Related

openapi-generator-maven-plugin doesnt generate response headers for library - webclient

I have model in open-api v.3 spec. I use openapi-generator-maven-plugin to generate java client for library webclient (spring 5 - webflux). I want to send back to client file and http headers. Generated code doesn't have method to get response headers.
Generated code for client doesn't contains code which provide access to response headers. For example if I use library resttemplate there is method public MultiValueMap getResponseHeaders() . Is there a way how to get response headers with library -webclient ?
template for resttemplate library contains this:
private MultiValueMap responseHeaders;
link: github
code for webclient is here: github
OpenAPI generator was extended since 5.2 and now the webclient library has two methods for each endpoint one with suffix WithHttpInfo and with a return type Mono<ResponseEntity<T>> . See PR #9327. So if you have for example an endpoint getUser it generates:
Mono<UserDTO> getUser();
Mono<ResponseEntity<UserDTO>> getUserWithHttpInfo();
Then you can call a method with WithHttpInfo which returns ResponseEntity and call ResponseEntity#getHeaders
getUserWithHttpInfo().getHeaders()

Obtain object and header simultaneously with spring

I am requesting a object to a external api service using getForObject() of the class RestTemplate and I will like to change the url for the service to also sent me a header with relevant information, I have been reading and found headForHeaders() with will return the header but will force me to make 2 calls to the service.
There is any way to be able to retrive the header data and the object in the same call?
getForObject() does not support setting headers. You can use the exchange() method and pass headers. And then use getBody() method. You can also use getForEntity() which providesgetHeaders() and getBody().
I have implemented it using getForEntity() as already mentioned, I leave my particular solution in case is useful for someone.
HttpEntity<Object> responseEntity = new RestTemplate().getForEntity(url, Object.class);
HttpHeaders header = responseEntity.getHeaders();
String headInformation = header.getFirst("headerValue");
Object newObject = responseEntity.getBody();

Is there a standard way in Spring to pass a body with a DELETE request to a REST endpoint?

I am implementing a Spring client for an existing REST API and I need to invoke a DELETE while, at the same time, passing an access token in the request body, like this:
{
"access_token": "..."
}
The problem is that, using the method that works for POST, the transmitted body is empty (I have intercepted the request body and made sure) and I cannot be authorised without this access token. This is what I am doing:
RestTemplate restTemplate = new RestTemplate();
UserRequest ur = new UserRequest(access_token);
HttpEntity<UserRequest> entity = new HttpEntity<>(ur);
restTemplate.delete(url, entity);
I have no control over the API itself, so I don't have the option of passing the token as url parameter.
Is there a way to do this in Spring, or do I have to build my own HttpUrlConnection like described for instance in this SO answer?
In the RestTemplate object in Spring there's an exchange method.
The parameters are :
the url
the method, in your case HttpMethod.DELETE
the entity (with the body you have to transmit)
the response type
some object you could pass
Hope this help

Restful web service call with input parameter as Java Object

Am using rest call for my spring application. I need to send Java objects as input parameter for the rest methods. Once i have tried using requestentity for inputstream. is it suitable for that?
the code i used for inputstream is
HttpEntity<byte[]> entity = new HttpEntity<>(IOUtils.toByteArray(in));
RestTemplate restTemplate=new RestTemplate();
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
restTemplate.postForObject("http://localhost:9070/EXTJS4FileUpload_Rest/rest/fileUpload/send/"+filename+"/"+filesize,entity,String.class);
If you read Java objects as stream in REST method you need to Deserailize the stream to object ( I dont know why and how u managed to do so). Instead try sending java object as JSON or XML and after consuming in REST method convert into object using by parsing XML/JSON . If you use frameworks like Jersey it fairly simple by specifying request mime-type

Any simple way to test a #RequestBody method?

If I have a #Controller method whose parameter is a #RequestBody param, I usually have to write some jQuery script or something similar to perform an AJAX request with JSON object in order to call that method. If I tried calling that method via a web browser directly, it returns with a Error 415 Unsupported Media Type.
Is there any alternative to just quickly call such method using browser without having to write some jQuery code? Like perhaps a way to write the JSON object in the URL/address bar?
code:
#RequestMapping("testCall")
#ResponseBody
public List<TestObject> getTestCall (#RequestBody TestParams testParams) {
return stuff;
}
public class TestParams {
private Integer testNumber;
//getter/setter for testNumber
}
I thought maybe I could just do:
http://localhost/testCall?testNumber=1
maybe Spring would auto populate a new TestParams instance with that property set to 1 but that didnt work...
maybe I need to do something extra for that?
The whole point of a #RequestBody annotated parameters is for the Spring MVC stack to use the HTTP request body to produce an argument that will be bound to the parameter. As such, you need to provide a request body. Sending a request body is very atypical for a GET request. As such, browsers don't typically support it, at least not when simply entering an address in the address bar and submitting the request.
You'll need to use a different HTTP client, like jQuery. I typically have a small Java project in Eclipse that's setup with an Apache HTTP components client which can send HTTP requests to whatever server. It takes a few seconds/minutes to setup the correct request body and run.
I have spent the last year building a REST API, and by far the best way to exercise that API manually is using the Chrome Extension, Postman. I cannot recommend this tool enough.
https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en
To test your simple example you'll need to invoke a POST (I assume that as you have a request body, but your controller method doesn't define a HTTP Verb) using POSTMAN to your Url (like the following example):
POST /contextRoot/testCall
{
"testNumber": 1
}
If you want to test your API automatically (which I recommend), you can use the excellent Spring Mvc Test project. This allows your to call your API via a rest-like DSL and assert that the response is in the shape you want. More details can be found here:
http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/testing.html#spring-mvc-test-framework
you can add request params to the getTestCall method:
#RequestParam(value = "testNumber", required = false, defaultValue = "") String testNumber
There is a chrome app called Advanced REST client. You can pass the data in form of json to your controller using this chrome app. For eg. json data is
id:1,
name:"xyz"
whereas the controller can have #RequestBody Person form.
The Person class would be a POJO having id and name as instance variables. The Spring would automatically map the json data to the form.
I think this is the easiest and simplest way of checking your spring controller.
Check the extension Advanced REST client here
From what I know You can send JSON object to the webbrowser and it will be displayed without further need of AJAX.
useful tutorial:
http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/

Categories