My service consumes a Json data. I want to bind this into a String. I tried the following code but unsuccessful:
#POST
#Path("file/save")
#Consumes(MediaType.APPLICATION_JSON)
public JsonResponse save(String content) {
}
I got the error: "Error 400 Can not deserialize instance of java.lang.String out of START_OBJECT token"
How could I fix this problem?
Try creating a container class for your request and then using that class as a parmeter in your resource method. For example:
Class MyRequest {
public String name;
public String address;
}
#POST
#Path("file/save")
#Consumes(MediaType.APPLICATION_JSON)
public JsonResponse save(MyRequest req) {
//req.name, req.address
}
If that doesn't work for you, can you give more details on what you are trying to achieve?
Related
I am trying to invoke a third-party API through REST call in Spring. Currently, I'm using postForObject. I am converting the request class to string and calling the post for object. The response is taken as string and then converted it into the class. I have defined the class with below parameters
Class responseDto {
private Arraylist < Response > response;
getResponse();
setResponse();
}
Response {
String code;
String trid;
Getters();
Setters();
}
I am using Jackson dependency to serialize and deserialize. This class is working fine for the below response:
{
"response":[
{
"code":"100",
"trid":"123"
}
]
}
However, in error scenario, the request returns a JSON class with the same name 'response' as given below
{
"response":{
"code":"700",
"trid":"123"
}
}
The deserialize fails for the class I defined with some JSON mapping exception:
com.fasterxml.jackson.databind.JsonMappingException: Can not
deserialize instance of java.util.ArrayList out of START_OBJECT token
How can I resolve this issue in Java and Spring?
SOLUTION 1: Using #JsonFormat ( > 2.6 version)
Just annotate your field with #JsonFormat as
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonFormat.Feature;
public class ResponseDto {
#JsonFormat(with = Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
private List<Response> response;
public List<Response> getResponse() {
return response;
}
public void setResponse(List<Response> response) {
this.response = response;
}
}
SOLUTION 2: Setting DeserializationFeature
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
// global setting, can be overridden using #JsonFormat in beans
// when using #JsonFormat on fields, then this is not needed
mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
ResponseDto dto = mapper.readValue(stringResponse, ResponseDto.class);
}
Now response node in json containing single object, single object array, multiple object array will be successfully parsed as list of Response object.
Am developing a rest webservice using Jersey.Am slightly new to webservices. I need to pass List of customer as input to rest webservice. having issue in achieving it.
Below is my customer object class
#Component
public class customer {
private String customerId;
private String customerName;
And my endpoint is as below. addCust is the method that will be called on calling the webservice
#Path("/add")
#Produces({MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_JSON})
public String addCust(#Valid customer[] customers){
//And json input is as below
{customers:{"customerId":"1","customerName":"a"},
{"customerId":"2","customerName":"b"}}
But jersey is not able to convert json array to Array of Customers. It is returning 400. And the logs shows "no viable alternative at c". How to pass Json array as input to webservice and convert into Array or ArrayList. Any help appreciated.
Your json is invalid, field names should be always double quotted, and arrays are placed inside [] for example:
{"customers":[{"customerId":"1","customerName":"a"},
{"customerId":"2","customerName":"b"}]}
thats why jackson cannot unmarshall it. But this json will never fit your api.
Here is an example of what You should send:
[{"customerId":"1","customerName":"a"},{"customerId":"2","customerName":"b"}]
Another thing is that You can use collections instead of arrays:
#Path("/add")
#Produces({MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_JSON})
public String addCust(#Valid List<Customer> customers){
If you want to send a json like this:
{"customers":[{"customerId":"1","customerName":"a"},
{"customerId":"2","customerName":"b"}]}
then you have to wrap everything into class with "customers" property:
class AddCustomersRequest {
private List<Customer> customers;
public void setCustomers(List<Customer> customers) {
this.customers = customers;
}
public void getCustomers() {
return this.customers;
}
}
And use it in Your API:
#Path("/add")
#Produces({MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_JSON})
public String addCust(#Valid AddCustomersRequest customersReq){
I have following jersey method declaration:
#POST
#Path("/fooPath")
#Produces({MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_JSON})
public Response isSellableOnline(#FormParam("productCodes") final List<String> productCodes,
#FormParam("storeName") final String storeName,
#Context HttpServletRequest request) {
In rest client I try to invoke following method like this:
When I debug method I see that received parameters are null:
How to rewrite method declaration?
It is because on the isSellableOnlie method you are expecting or trying to extract form parameters, but the incoming POST request is JSON.
Well if you want JSON you should make POJO Class to be able to serialize the JSON.
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Store {
private String storeName;
private List<String> productCodes;
public Store() {
}
public String getName() {
return name;
}
public List<String> getProductCodes() {
return productCodes;
}
}
And then in your method:
#POST
#Path("/fooPath")
#Produces({MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_JSON})
public Response isSellableOnline(Store store) {
store.getName();
...
}
I have a following jersey class .
#Path("/static1/static2")
public class DoStuff {
#POST
#Path("/static3")
#Consumes(MediaType.APPLICATION_XML)
#Produces("application/xml")
public Response validation(String inputXML){
so my url is localhost/static1/static2/static3 and I get a 200
my goal is to have a URL that is
localhost/static1/{variable}/static2/static3
I tried modifying my class in the following way
#Path("/static1/{variable}/static2")
public class DoStuff {
#POST
#Path("/static3")
#Consumes(MediaType.APPLICATION_XML)
#Produces("application/xml")
public Response validation(String inputXML){
but I keep getting a 404 , what am I doing wrong ?
The problem seems to be with the last path segment static3.{format}. Try the following:
#Path("/static1/{variable}/static2")
public class DoStuff {
#POST
#Path("/{segment3:static3.*}")
#Consumes(MediaType.APPLICATION_XML)
#Produces("application/xml")
public Response validation(#PathParam("variable") String variable,
#PathParam("segment3") String segment3,
String inputXML) {
...............
}
I'm just wondering how to modify the following
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response createObject(Object object) {
...
}
to also allow a path parameter? I was thinking something like
#POST
#Path("{server}")
#Consumes(MediaType.APPLICATION_JSON)
public Response createObjectOnServer(#PathParam("server") String url, Object object) {
...
}
but that either is just wrong or I don't know how the json should be structured.
The second block of code should work, in my project:
#POST
#Path("/{mode}")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.TEXT_PLAIN)
public String renderWidget(#PathParam("mode") String mode,RenderingRequest renderingRequest){
...
}
where 'mode' is a path param and 'RenderingRequest' is a pojo that maps the request body(a json).