ResponseEntity : HTTP Status 400 – Bad Request - json

I have a web service that returns JSON. I am trying to print the screen using this web service spring mvc. The code I wrote is getting 400 errors. How can I resolve it?
I use json object:
{"currencyRates":[{"currencyPair":"BGN/IRR","date":1519922870105,"askPrice":4.376,"bidPrice":2.162},{"currencyPair":"ROL/LKR","date":1519922870105,"askPrice":4.056,"bidPrice":2.132},{"currencyPair":"KES/MGF","date":1519922870105,"askPrice":4.067,"bidPrice":3.005}]}
Controller:
#RequestMapping(value = "/list", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String userList(ModelMap model) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<List<CurrencyRate>> rateResponse = restTemplate.exchange(
"http://localhost:8080/denemeDenemeDeneme/rates", HttpMethod.GET, null,
new ParameterizedTypeReference<List<CurrencyRate>>() {
});
List<CurrencyRate> rates = rateResponse.getBody();
model.addAttribute("list", rates);
return "list";
}
Thanks...

The problem is that the target class which cannot be a non-static inner class. It doesn't work embedded in the Controller class which I think is the problem.
The details are in here but it boils down to the way Java added inner classes means they don't have the default constructor that Jackson requires.
or Check if your class CurrencyRates does have constructor without any parameter.

Related

Method has too many Body parameters

I have the following requestMethod in a RestController class and it´s working fine:
#RequestMapping(path = "/api/v1/rest/websearcher/search/results", method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<WebResultResponse> getSavedAvailability(#RequestBody final WebResultRequest navigationRequest,
#CookieValue(value = "forceSupplier", defaultValue = "") final String forceSupplier)
I´ve also a feign client working fine as well. I added a new parameter called forceSupplier in both methods, but after adding it, I´m having the issue Method has too many Body parameters but I don´t really understand why I´m receiving this message because the param is the same.
This is the method in Feign:
#RequestMapping(path = "/api/v1/rest/websearcher/search/results", method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
ResponseEntity<WebResultResponse> getAndSavedAvailability(#RequestBody WebResultRequest webSearcherResultRequest, #CookieValue(value = "forceSupplier", defaultValue = "") String forceSupplier);
What am I doing wrong? Thanks
The annotation #CookieValue is not supported when using Spring Cloud OpenFeign. As a result, Feign sees your #RequestBody and #CookieValue parameters as the request entities, and since you only have one request entity, Feign throws the exception you are seeing.
There is currently no support for Cookies in Feign.

Converting Java object to JSONObject and transmit it at GET method.

I am working on an Android app, for which I am also working on a
Spring-MVC based server. Unfortunately before this, I have not done
that much work on JSONObjects. Currently, I am able to send Java
objects to the server from the Android app, and receive Java objects
too.
I am interested in using the Volley framework provided by Google,
which will avoid the hassle of Asynctask and is more efficient, but
it deals with JSONObject.
Unfortunately wherever I looked on the net, I found the code to
create JSOnObjects to save it in some file on Local Hard drive, but
no, I would like to transmit them in ResponseBody, can anyone help me
out with creating a JAVA object to JSOBObject and vice-versa. I have
all POM dependencies, and messageConvertors set in servlet-context.
Controller code current :
//Restaurant is just a plain Java class, I can give it as a JSONObject, but I dont know how to convert that JSONObject to java so I can save the restaurant in the server.
#RequestMapping(value = "/restaurant/add",method = RequestMethod.POST)
#ResponseBody
public String addRestaurantWebView(#RequestBody Restaurant restaurant){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("restaurant", new Restaurant());
modelAndView.addObject(restaurant);
this.restaurantService.addRestaurant(restaurant);
return "true";
}
//Similarly, here, I don't know how to convert the Restaurant's list to JSONObject when there is a get Request.
#RequestMapping(value = "/restaurant/listing", method = RequestMethod.GET)
public #ResponseBody List<Restaurant> listAllRestaurants(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("restaurant", new Restaurant());
List<Restaurant> restaurantList = this.restaurantService.listRestaurants();
modelAndView.addObject("listRestaurant", restaurantList);
return restaurantList;
}
I hope my question was clear, if there is any doubt, please let me know. Thanks a lot.
Take a look at Google's Gson. It's a pretty concise API for converting objects to JSON. You can easily specify properties by adding the #Expose annotation in your classes to the properties you need to include. Try it like this:
#RequestMapping(value = "/restaurant/listing", method = RequestMethod.GET)
public #ResponseBody String listAllRestaurants(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("restaurant", new Restaurant());
List<Restaurant> restaurantList = this.restaurantService.listRestaurants();
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String jsonString = gson.toJson(restaurantList);
return jsonString;
}
It's not necessary to annotate properties with #Expose but it will help if you end up having any circular references.
Good luck.

Spring MVC HTTP Status 405 - Request method 'POST' not supported - Backbone Request

I am new at Spring MVC and I am trying to build a Web Application from scratch using Spring MVC + Hibernate to serve something like a JSON Rest API, having this API consumed through Backbone at the client side. To do that I have started following this tutorial ( http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/ ) .
So I have a model Message which will have the following REST API Interface:
GET /api/messages ( working ok )
GET /api/messages/:id ( working ok )
DELETE /api/messages/:id ( working ok )
PUT /api/messages/:id ( working ok )
POST /api/messages ( error: (DefaultHandlerExceptionResolver.java:194) - Request method 'POST' not supported)
I expected this problem happens for PUT or DELETE requests when doing the request through a form, but not for a POST request. I am not even doing the request through a form. On the client side the request is done through Backbone like this:
new App.Models.Message({ attributeA : 'a', attributeB : 'b' }).save();
I have already tried to add the httpMethodFilter at web.xml as suggested in other Stackoverflow questions:
<filter>
<filter-name>httpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>httpMethodFilter</filter-name>
<servlet-name>mvc-dispatcher</servlet-name>
</filter-mapping>
Has anyone had the same problem?
I leave here my MessagesController:
#Controller
#RequestMapping("/api/messages")
public class MessagesController {
#Autowired
private MessageService messageService;
#RequestMapping(method = RequestMethod.GET)
public #ResponseBody List<Message> getMessagesInJSON(#RequestParam( value = "type", required = false ) String type) {
List<Message> messages = messageService.findAll();
return messages;
}
#RequestMapping( value = "/{id}", method = RequestMethod.GET )
public #ResponseBody Message getMessageInJson(#PathVariable Integer id ) {
Message message = messageService.findById(id);
return message;
}
#RequestMapping( value = "/{id}", method = RequestMethod.DELETE )
#ResponseStatus( value = HttpStatus.NO_CONTENT )
public void deleteMessage(#PathVariable Integer id ) throws NotFoundException {
messageService.delete(id);
}
#RequestMapping( value = "/{id}", method = RequestMethod.PUT )
#ResponseStatus( value = HttpStatus.NO_CONTENT )
public void editMessage( #PathVariable Integer id, #RequestBody Message message ) throws NotFoundException {
message.setId(id);
messageService.update(message);
}
#RequestMapping( value = "/", method = RequestMethod.POST )
#ResponseStatus(HttpStatus.CREATED)
public #ResponseBody Message createMessage( #RequestBody Message message ) {
return messageService.create(message);
}
}
Thanks a lot!
You have already mapped /api/messages to the getMessagesInJSON method which only allows a GET request. Your POST request is mapping to a different path.
I suggest to omit the value attribute on your request mapping for createMessage.
#RequestMapping(method = RequestMethod.POST )
I think the problem is that your #RequestMapping is located at the top of your class definition, and conflicts with the strings that you associated with the value argument in the other #RequestMapping annotations in front of each method. By contrast, I would start the class with the following:
#Controller
#SessionAttributes(types = SomeClassName.class)
public class SomeClassNameController {
Then you can use the value parameter in the #RequestMapping annotations that you have in front of each method.
It is also good to keep in mind that this error might happen if you are implementing /error endpoint for exception handling. If your /error endpoint has a method type and it doesn't match the method of the endpoint where the exception was thrown; you might end up getting 405. If that is the case, remove method type from the error endpoint to serve to all.

Issues with JSON processing using JAXBElement under Jersey 2.2 with MOXy

I extended the jersey-examples-moxy code to use an XML schema definition instead of the JAXB annotated beans. The xjc compiled XML schema produces XML and JSON encodings identical to the original example.
I followed the jersey instructions and used the ObjectFactory to generate the JAXBElement Customer object representation within CustomerResource.java. I also modified the client as described. I also incorporated the fix described in PUT issues with JSON processing using JAXB under Jersey 2.2 with MOXy
The MediaType.APPLICATION_XML functions perfectly, and MediaType.APPLICATION_JSON works for GETs, but the client is failing to marshall JSON on a PUT with "MessageBodyWriter not found". The following exception is thrown:
testJsonCustomer(org.glassfish.jersey.examples.jaxbmoxy.MoxyAppTest) Time elapsed: 0.113 sec <<< ERROR!
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/json, type=class javax.xml.bind.JAXBElement, genericType=class javax.xml.bind.JAXBElement.
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:191)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:139)
at org.glassfish.jersey.filter.LoggingFilter.aroundWriteTo(LoggingFilter.java:268)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:139)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1005)
at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:430)
at org.glassfish.jersey.client.HttpUrlConnector._apply(HttpUrlConnector.java:290)
Here is how I modified CustomerResource.java:
private static ObjectFactory factory = new ObjectFactory();
#GET
#Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public JAXBElement<Customer> getCustomer() {
return factory.createCustomer(customer);
}
#PUT
#Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
#Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public JAXBElement<Customer> setCustomer(Customer c) {
customer = c;
return factory.createCustomer(customer);
}
Here is how I am making the PUT request (same as for the functioning XML):
#Override
protected void configureClient(ClientConfig clientConfig) {
clientConfig.register(new MoxyXmlFeature());
}
#Test
public void testJsonCustomer() throws Exception {
ObjectFactory factory = new ObjectFactory();
final WebTarget webTarget = target().path("customer");
// Target customer entity with GET and verify inital customer name.
Customer customer = webTarget.request(MediaType.APPLICATION_JSON).get(Customer.class);
assertEquals("Tom Dooley", customer.getPersonalInfo().getName());
// Update customer name with PUT and verify operation successful.
customer.getPersonalInfo().setName("Bobby Boogie");
Response response = webTarget.request(MediaType.APPLICATION_JSON).put(Entity.json(factory.createCustomer(customer)));
assertEquals(200, response.getStatus());
// Target customer entity with GET and verify name updated.
Customer updatedCustomer = webTarget.request(MediaType.APPLICATION_JSON).get(Customer.class);
assertEquals(customer.getPersonalInfo().getName(), updatedCustomer.getPersonalInfo().getName());
}
Thank you for your help!
The issue you're facing is on this line:
Response response = webTarget.request(MediaType.APPLICATION_JSON).put(Entity.json(factory.createCustomer(customer)));
Basically you're passing JAXBElement to Entity#json method but the runtime doesn't have information about the generic type, you need to provide it. That's what GenericEntity<T> class is for:
webTarget
.request(MediaType.APPLICATION_JSON)
.put(Entity.json(new GenericEntity<JAXBElement<Customer>>(factory.createCustomer(customer)) {}));

JSON + Spring 3.1

Hi I am trying to write small app with REST Json. I have some method that returns ArrayList of entity objects. And I am doing that:
#RequestMapping(value="/workers/", method = RequestMethod.GET)
public #ResponseBody ArrayList<Workers> showAllEmployes() throws Exception
{
ArrayList<Workers> workers = new ArrayList<Workers>();
workers = (ArrayList<Workers>) spiroService.getAllWorkers();
return workers;
}
And after this I got:
HTTP Status 500. The server encountered an internal error that prevented it from fulfilling this request.
When I try to return primitive data type then all is ok. I have nothing in server logs. And I have necessary imports. Please some tip.
Seems you have issue in produce json format, try this.
#RequestMapping(value = "/workers/", method = RequestMethod.GET,
produces={MediaType.APPLICATION_JSON_VALUE})