Restful web service call with input parameter as Java Object - java

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

Related

Which RequestBody type should be used if using the same payload to make another request?

Background
We are consuming the API from a 3rd-party vendor
Problem Statement:
I am building a wrapper API around another API. The same exact JSON payload that I will be receiving from the client to the wrapper API will also be used to make an HTTP request to the original API.
Currently I'm converting JSON which deserializes to a String. Is this the right approach if the payload is just passing through the wrapper API to the original API? In other words, is the #RequestBody type String okay for my use case or do I still need to deserialize to a Java Object?
Use Case for wrapper
If multiple teams consumed the API from the 3rd-party vendor, all teams would have to make changes if we were to switch vendors. If we create a wrapper, only one team would have to make the changes. There is no processing in this wrapper.
Controller Code:
#RestController
#RequestMapping(value = FolderController.PATH, produces = MediaType.APPLICATION_JSON_VALUE)
public class PersonController(){
static final String PATH = "/person";
private final PersonService personService;
#Autowired
public PersonController(PersonService personService){
this.personService = personService
}
#PostMapping
#ResponseBody
public String createPerson(#RequestBody String requestBody){
return personService.createPerson(requestBody);
}
Whether you need to deserialize depends on what processing is necessary for your wrapper. If you just want to pass the request further without changing it, this should work.
However, if you just need to proxy the request, consider using Smiley's HTTP Proxy Servlet for this task.
Or if you are wrapping the API to implement security around it, then consider using Spring cloud gateway
It is always better to follow coding practices and convert the request body to a java POJO class instead of a string. Converting to POJO has several advantages :
You could provide additional validations for the request body.
Incase the request body changes or if there are any issues it could be identified easily.
Provides better control over the request structure.In future , if the API that you are consuming changes the request body structure, you could change it from your API instead of adapting it at every API that consumes your API.

Use spring reactive webclient to pass protobuff request

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 ;)

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

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/

How can i send object in HTTP request

I am creating a Web Service that will handle incoming request properly (I knew, it is a description) I found some sample code which present SOAP WS and looks like:
#SoapAction("some fine url")
#ResponsePayload
public CertResponse getCert(#RequestPayload Cert param)
{...}
It takes Cert object from request and manages it properly. I want to do it in the REST approach and I changed this class to look like:
#RequestMapping(value="getCert", method = RequestMethod.POST)
#ResponseBody
public CertResponse getCert(#RequestBody Cert param)
{...}
But I have no idea how or even if it is possible to write a client that can send object through HTTP Post.
Can anyone give me a hint how can i send object Cert? Or if i have to stay with #SoapAction what should I do to make it work? I guess removing #Controller is not enough.
In SOAP approach, there is a well defined way to convert each class object to SOAP formatted XML. Thus, there is no effort.
If you will use RESTful approach, you have to describe how your Cert or CertResponse objects will be written to/read from the response/request.
Basically you have three options:
Use JSON or XML or plain String. Convert your Web service descriptor so that the request and response are one of those (JSON, XML, String). Then your getCert method should convert the request to Cert object, prepare your response as CertResponse object and convert it to an appropriate response type.
Leave your getCert method as is. But you need to specify "how Cert objects are read from request" and "how CertResponse objects are written to response" You need to define classes that extend interfaces MessageBodyReader and MessageBodyWriter. In these classes a similar conversion logic should be implemented that converts your objects to/from JSON or XML or String.
In any of these two options you need to implement two things : A method that converts JSON/XML/String to Cert, a method that converts CertResponse object to JSON/XML/String.
You can do a text based implementation, which parses/constructs the request/response by text processing and uses String class only. Or you can use some library such as JSON library with JSONObject class, or Java SAX or DOM based XML libraries that come with the Java bundle.
Check out for application frameworks such as Spring. They might provide ways to automatically convert your objects to JSON or XML, reducing the programming effort necessary.
Spring allows you to pass JSON objects from the client as a request parameters, it will convert them into your objects automatically. This discussion have some examples.
SOAP services are not really compatible with REST semantics. And it's not clear what SOAP framework do you use. Typically most SOAP frameworks offer you one way or another to generate a SOAP client code for you WSDL. You can check cxf.apache.org.
For REST services use something like Jersey or Spring MVC

Categories