I need help creating a POST request to my Java Spring Restcontroller.
This is my controller -
#RestController
#RequestMapping("hedgesimulator/")
public class HedgeSimulatorController {
#RequestMapping(value = "hedgesim/", method = RequestMethod.POST)
#ResponseBody
public HedgeSimulatorLog putHedgeSimulation(
#RequestBody HedgeSimulatorLog hedgeSimulatorLog) {
System.out.println(hedgeSimulatorLog.toJsonString());
return hedgeSimulatorLog;
}
}
I am using Chrome's "Advanced Rest Client" Plugin to POST my request to my URL (I am sure my localhost is running properly, etc.)
What do I need to add to my header?
I receive an error for "HTTP 400 - Status report: The request sent by the client was syntactically incorrect"
Please help!
To pass an object to controller you must configure HttpMessageConverter which helds serialization and deserealization of this object. For example, if you want to pass an object to controller as JSON, set a MappingJackson2HttpMessageConverter as parameter in your mvc declaration in spring config file.
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
If http message converter configured properly, maybe request was improperly formed.
#RequestMapping(value = "/hedgesim/", method = RequestMethod.POST)
Try with following, hope you might resolve the issue:
Since you are using #RestController annotation, so no need to use #ResponseBody annotation again, which is redundant.
If you are using spring boot, then make sure you have added the below dependency .
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
If the project is not spring boot, then add dependency for jackson : com.fasterxml.jackson.databind.ObjectMapper
Just to make sure the request body is correct, what you can do is, execute request method first, get the JSON response, pass the same JSON for POST, so this might avoid some typo/human error while creating JSON data.
Hope, it helps.
You can do the following checks.
Validate the request body you are sending through some online tool like
JSonLint.
Check whether MappingJackson2HttpMessageConverter is registered or not. By default, Spring registers this converter if you have the jar in the classpath.
No need to use #ResponseBody if you are using #RestController. So remove it.
For a complete example on creating and consuming REST Service using Spring 4.0, you can visit Techno Spots.
Related
I'm creating a new endpoint to upload and process excel and csv files.
I'm trying to create an endpoint using springs Multipart upload, but I cannot reach the endpoint from Postman or using curl in command line.
I have a RestController
#RestController
#RequestMapping("/v1/finance/ratecard")
public class RateCardController
and I am able to access other endpoints in this controller without a problem.
I added new endpoint to this controller.
#PostMapping(value = "/uploadFile")
#ResponseStatus(HttpStatus.OK)
public void uploadExcelFile(#RequestPart("file") MultipartFile file, #RequestPart("meta-data") UploadRateCardRequest uploadRateCardRequest) {
//Unrelated logic here
}
And I'm trying to send POST request using postman, I haven't touched Content-Type header, it's generated by Postman, but I have had no success reaching it. I always get 404 error. Postman Config
I have tried adding consumes = "multipart/mixed" and "multipart/form-data" to #PostMapping annotation, but those changes had no effect.
What am I doing wrong? Am I missing some obvious request parameter in Postman, or is my controller set up wrong?
I had problems in uploadExcelFile method, one of dependencies I was using could not detect valid beans for an autowired interface. That was causing this issue.
Nothing was wrong with Controller set up or postman config pictured in the post.
html file not returning in the Rest API and return the file name only like 'index' for the following code when used #RestController and working fine only for #Controller.
Here I am using spring boot REST application and index.html with bootstrap
If you know REST web services then you must know the fundamental difference between a REST API and a web application i.e. the response from a web application is generally view (HTML + CSS) because they are intended for human viewers.
REST API just returns data in form of JSON or XML because most of the REST clients are programs. This difference is also obvious in the #Controller and #RestController annotation.
#RestController = #Controller + #ResponseBody
When you use #Controller annotation then it corresponds to MVC workflow in Spring Boot and it renders the view. The key difference is that you do not need to use #ResponseBody on each and every handler method once you annotate the class with #RestController.
#ResponseBody is a Spring annotation which binds a method return value to the web response body. It is not interpreted as a view name. It uses HTTP Message converters to convert the return value to HTTP response body, based on the content-type in the request HTTP header. The content type can be JSON or XML.
It is the expected behaviour of #RestController. The main difference between #RestController and #Controller is #RestController will by-pass the view resolution but #Controller will not.
Technically , it is due to the presence of the #ResponseBody of the #RestController. #ResponseBody will enable RequestResponseBodyMethodProcessor to process the result return from the #RestController method and it will mark that the request has been fully handled within the controller method and by-pass the view resolution process (see this).
I am using:
Spring 4.1.1.RELEASE
Spring Security 3.2.5.RELEASE
spring-security-oauth2 1.0.0.RELEASE
I have created a two multipart request:
One is at Non-secure controller Second at a Secure controller.
Both are same, there is no change.
Non secured request works very fine but secured Multipart request not working
#RequestMapping(value="/profileimage", method=RequestMethod.POST)
public #ResponseBody String createProfilePicture(#RequestParam MultipartFile
file, #RequestParam String profileId){
}
Please reply if you require more information.
Please specify what exactly you are trying to achieve by implementing an oauth2 authorization server.
Do you plan to support various authentication providers e.g Facebook, Linkedin, Google?
Please specify the error message you get when trying to consume the API.
Please share your Security configuration classes i.e the class that extends WebSecurityConfigurerAdapter and any other configuration that you have.
You can review this article which details how to implement an oauth2 authorization server to make sure you haven't missed any part.
In regards to the code above, it seems corrent but can be simplified:
#PostMapping("/profileimage")
public #ResponseBody String createProfilePicture(#RequestParam MultipartFile
file, #RequestParam String profileId){
}
You can even drop the #ResponseBody annotation in case a #RestController
annotation is specified on the class.
Good luck!
I tried to generate a json response earlier using spring-mvc (annotation) . After so may failure i find out some check point :
I need to add <mvc:annotation-driven/> in my servelet mapper. although i don't know the reason.
Then I need to add #ResponseBody annotation which should bound the return value as http response as the documentation says.
And I also need add some jacson dependency.
Did i missed something?
Now i have bunch of questions
why we have to add that in my servelet xml and how this whole process is working?
As json response is most commonly used when why spring need jackson dependency to generate json?
some days ago i was doing Struts2 generating json response there was much simple.
Is there any way to do it more easily in spring-mvc .?
At first you should understand that <mvc:annotation-driven/> annotation used for many cases not only for generating json response in Spring. This annotation allow to use different annotations in Spring mvc classes like:#NumberFormat #DateFormat #Controller #Valid and of course #ResponseBody.
To generate json response you just need #ResponseBody annotation in your controller or servlet and import libraries for processing JSON.
Recently java has oun set of APIs for processing JSON as part of Java EE 7 JSR 353 actually it has clean Oracle tutorial. Also you can use third party libraries like Jackson. To process (parse, generate, transform, and query) JSON text it's necessarily to have one of this libs.
You can learn about most popular third party libraries and their performance in this article
Here you can see simple example.
If you are using jacson you can do something like:
Your Model
public class Shop {
String name;
String staffName[];
}
Your Controller
#Controller
#RequestMapping("/shop/list")
public class JSONController {
#RequestMapping(value="{name}", method = RequestMethod.GET)
public #ResponseBody Shop getShopInJSON(#PathVariable String name) {
Shop shop = new Shop();
shop.setName(name);
shop.setStaffName(new String[]{"mkyong1", "mkyong2"});
return shop;
}
}
mvc-dispatcher-servlet.xml
<context:component-scan base-package="com.example.mypackage" />
<mvc:annotation-driven />
Basically, you need check if:
Your Jackson library is existed in the project classpath
The mvc:annotation-driven is enabled
Return method annotated with #ResponseBody
I have a Spring rest service using Spring 3.1.0.RELEASE. Here is the relevant code for the service call in question:
#RequestMapping(value="/{var1}", method=RequestMethod.GET, produces="application/json")
#ResponseBody
public String getSomeStuff(#PathVariable final String var1) {
return myJsonString;
}
If I call this using the following curl command, it happily returns me my json string with a content-type of application/xml whereas I would expect a 406 based on the Spring 3.1 docs:
curl -v -H "Accept: application/xml" http://localhost:8080/MyServiceSite/myvalue
There is no extra configuration in my app for this service (no serialization), I am returning raw json with no post-processing for the service configured. I'm certain I have missed something, can anyone point out anything I may have missed?
Edit: Here is the documentation I was looking at when attempting to get this working. Specifically section 16.3.2.5. My code is very similar except that their code looks like it assumes config setup to let Spring handle serialization. Perhaps the produces does not work when bypassing the Spring serialization?
Edit: I changed my expectation for the response code. A 415 would indicate I was sending improper content in my request body whereas 406 is proper for having an accept header that doesn't jive with the content type of the server.
Anyway, I have changed this method do return a Map and added config for it to serialize to json and now if I send an invalid content type from the client I get the proper 406 response. It seems that maybe the "produces" setting is ignored when the output of the method is not being serialized.
The produces condition is new to Spring MVC 3.1 and is only supported with the RequestMappingHandlerMapping and related #MVC support classes, also new in Spring 3.1. My guess is that you're using the 3.0 #MVC support classes, which do not support the produces condition. Your code otherwise is correct and so are your expectations of what should happen.
The use of headers="Accept=application/json" is unnecessary in 3.1. That's exactly what the produces condition was introduced for.
What about the headers attribute for the #RequestMapping. You could set the Accept header in there. Something like:
#RequestMapping(value="/{var1}", method=RequestMethod.GET, produces="application/json", headers = "Accept=application/json")
#ResponseBody
public String getSomeStuff(#PathVariable final String var1) {
return myJsonString;
}
I don't know how Spring would handle a request to that path without a matching header. If it doesn't give what you want you might need to define a similar mapping without the headers and have it send back a ResponseEntity and set the response code or something, but I would hope it would handle it appropriately.