I have this piece of code:
#RequestMapping(value = "/test.json", method = RequestMethod.GET)
#ResponseStatus(HttpStatus.OK)
public #ResponseBody Object[] generateFile(#RequestParam String tipo) {
Object[] variaveis = Variavel.getListVariavelByTipo(tipo);
return variaveis;
}
As far as I know it should take a request to test.json?tipo=H and return the JSON representation of Variavel[], however when I make such request I get:
HTTP Status 406 -
type Status report
message
descriptionThe resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ()
By using the following function I can get the expected json:
#RequestMapping(value = "/teste.json")
public void testeJson(Model model, #RequestParam String tipo) {
model.addAttribute("data", Variavel.getListVariavelByTipo("H"));
}
What I'm doing wrong?
#RequestBody/#ResponseBody annotations don't use normal view resolvers, they use their own HttpMessageConverters. In order to use these annotations, you should configure these converters in AnnotationMethodHandlerAdapter, as described in the reference (you probably need MappingJacksonHttpMessageConverter).
Related
Sometimes we send a POST HTTP request with POST payload to an endpoint with URL variable, for example:
[POST] http://example.com/update-item?itemid=123456
To get the POST payload in the Spring controller class, I can do something this:
#RequestMapping(value = "/update-item", method = RequestMethod.POST)
public String updateItem(#RequestBody Item json) {
//some logics
return "/update-item-result";
}
However, at the same time, how can I get the variable from the URL (i.e. itemid in the above example) even for method = RequestMethod.POST?
I see a lot of Spring MVC examples on the web either get the GET variables from the URL or the POST variables from the payload, but I never see getting both in action.
You can use multiple HTTP requests by specifying the method attribute as an array in the #RequestMapping annotation.
#RequestMapping(value = "/update-item", method = {RequestMethod.POST,RequestMethod.GET})
public String updateItem(#RequestBody Item json) {
//some logics
return "/update-item-result";
}
I need to serve multiple file types using same endpoint ( zip,pdf,xml).
I needed to add error handling to those endpoints so in case of error they should return json (using controller advice) to indicate problem to user.
For example:
#GetMapping(value = "api/books", produces = {applicaton/zip, application/json}
public ResponseEntity<byte[]> getZipedBooks(){...}
#GetMapping(value = "api/books", produces = {applicaton/pdf, application/json}
public ResponseEntity<byte[]> getPdfBooks()(...}
Without application/json Spring was able to differentiate between those endpoints and call correct one based on accept header. But when I added json Spring is now throwing exception:
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
even if it can be deduced from accept: application/json,application/pdf header that getPdfBooks should be called.
Is there any way to configure spring to work with multiple content types on the same endpoint or I need to make special endpoints for every file type ?
I would reconsider this approach. If you want to return JSON on error do with exception handling
So that you would add something like
private class ErrorResponse {
String message;
public ErrorResponse(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
#ExceptionHandler(value = Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception e) {
return new ResponseEntity<ErrorResponse>(new ErrorResponse(e.getMessage()), HttpStatus.BAD_REQUEST);
}
I'm working with Facebook messenger app (chatbot) and I want to see what GET request I'm receiving from it. I'm using Spring Framework to start http server and ngrok to make it visible for facebook.
Facebook sending webhooks to me and i receive them, but i don't understand how to extract data from this request. Here what i get when I try HttpRequest to receive GET request. ngrok screenshot (error 500).
When I tried without HttpRequest, i had response 200 (ok).
What do i need to put to parameters of my find method to see GET request data?
My code:
#RestController
public class botAnswer {
#RequestMapping(method= RequestMethod.GET)
public String find(HttpRequest request) {
System.out.println(request.getURI());
String aaa = "222";
return aaa;
}
}
I guess HttpRequest will not help you here. For simplicity, just change HttpRequest to HttpServletRequest. You can access all query string parameters from it using request.getParameter("..."). Something like the following should work:
#RequestMapping(value = "/", method = RequestMethod.GET)
public String handleMyGetRequest(HttpServletRequest request) {
// Reading the value of one specific parameter ...
String value = request.getParameter("myParam");
// or all parameters
Map<String, String[]> params = request.getParameterMap();
...
}
This blog post shows how to use the #RequestParam annotation as an alternative to reading the parameters from HttpServletRequest directly.
I am trying to create a RESTful service and encounter a type conflict within the application. Right now, I deal with this problem by using two different URLs, but this leads to other problems and doesn't feel right.
// Controller to get a JSON
#RequestMapping(value = "/stuff/{stuffId}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public stuffDto getStuff(#PathVariable String stuffId) {
return //JSON DTO//
}
// Controller to get an HTML Form
#RequestMapping(value = "/stuff/{stuffId}/form", // <- nasty '/form' here
method = RequestMethod.GET)
public String getStuffForm(#PathVariable String stuffId, ModelMap model) {
// Prepares the model
return "JSP_Form";
}
And on the JavaScript side:
function loadStuffForm(url) {
$.ajax({
type : 'GET',
url : url,
success : function(response) {
showStuffForm(response);
}
});
}
How can I merge both controllers so it will return the right type of data based on what the client accepts? By default it would return a JSON. I want to add 'text/html' somewhere in the ajax query to get the Form instead. Any idea?
You can use Content Negotiation to communicate to the server and tell it what kind of a response you're expecting form it. In your particular scenario, you as a client using an Accept header tell the server to serve a text/html or application/json. In order to implement this, use two different produces with that same URL:
// Controller to get a JSON
#ResponseBody
#RequestMapping(value = "/stuff/{stuffId}", method = GET, produces = "application/json")
public stuffDto getStuff( ... ) { ... }
// Controller to get an HTML Form
#RequestMapping(value = "/stuff/{stuffId}", method = GET, produces = "text/html")
public String getStuffForm( ... ) { ... }
In your requests to /stuff/{id} endpoint, if you send Accept: text/html in headers, the HTML form would return. Likewise, you would get the JSON response by sending Accept: application/json header.
I'm not a JQuery expert but you can check this answer out on how to send an Accept header in $.ajax requests.
I have a request handler for which I would like to skip json processing and retrieve the request body as a string. Eg -
#RequestMapping(value = "/webhook", method = RequestMethod.POST)
public void webHook(#RequestBody String body) {
}
However, the above method definition doesnt work as Spring forcibly tries to parse the posted string as json and thus throws an exception.
How do i tell spring to skip json processing for this request?
use like this it'll work.
#RequestMapping(value = "/webhook", method = RequestMethod.POST)
public void webHook(HttpServletRequest request) {
String body = IOUtils.toString( request.getInputStream());
// do stuff
}
Not using #RequestBody is key here. When spring sees #RequestBody it tries to map the entire body as object.