In My controller i have a method below which is working well
#RequestMapping(value="/searchresults",method = RequestMethod.GET)
public SearchResponse searchResults(
#PathVariable("domain") String domain,
#RequestParam(value="rowCount" , defaultValue="0", required=false) Integer rowCount,
HttpServletRequest req){}
but the same thing is not working when adding headers,
#RequestMapping(value="/searchresults", method = RequestMethod.GET,headers = "application/json;charset=UTF-8")
public SearchResponse searchResults(
#PathVariable("domain") String domain,
#RequestParam(value="rowCount" , defaultValue="0", required=false) Integer rowCount,
HttpServletRequest req){}
Exception :
Representation: null org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException: No matching handler method found for servle
t request: path '/search/searchresults.json', method 'GET',
I tried as follows,
#RequestMapping(value="/searchresults", method = RequestMethod.GET,headers = {"content-type=application/json,charset=UTF-8"})
but it throws,
java.lang.IllegalArgumentException: "charset=UTF-8" does not contain '/'
How to resolve it
You forgot to add the headers names :|
application/json is the Content-Type, while UTF-8 is the Charset.
Take a look at the complete list of HTTP headers.
The correct mapping will then be :
#RequestMapping(value="/searchresults", method = RequestMethod.GET,
headers = {"content-type=application/json,charset=UTF-8"})
That said, it's worth knowing that the ContentType should be specified only for POST and PUT requests.
You need to specify the header name also, which is content-type. Change this:
headers ="application/json;charset=UTF-8"
to
headers = {"content-type=application/json,charset=UTF-8"}
Change headers to produces
#RequestMapping(value="/searchresults", method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
public SearchResponse searchResults(
#PathVariable("domain") String domain,
#RequestParam(value="rowCount" , defaultValue="0", required=false) Integer rowCount,
HttpServletRequest req){}
Ideally you should use #RestController if you are using Spring 4
Use ; instead of ,
#RequestMapping(value="/searchresults", method = RequestMethod.GET,headers = {"content-type=application/json;charset=UTF-8"})
There is a workaround for those who use WebLogic, while maybe other app servers an do the similar, here is what worked for me in weblogic.xml
<wls:charset-params>
<wls:input-charset>
<wls:resource-path>/restful</wls:resource-path>
<wls:java-charset-name>UTF-8</wls:java-charset-name>
</wls:input-charset>
</wls:charset-params>
My Request Mapping annotation looks like this:
#RequestMapping(method = RequestMethod.POST, value = "/echo", produces = "text/plain;charset=UTF-8", headers = "Accept=*/*")
adding
headers = {"content-type=application/json,charset=UTF-8"}
didn't help and I am puzzled why, but I got away somehow. HTH
I found this useful (being stuck with Spring 3.0.x):
#ResponseBody
public ResponseEntity<String> getResponse() {
String body = ...
MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.set("Content-Type", "application/json;charset=UTF-8");
return new ResponseEntity<String>(body, headers, HttpStatus.OK);
}
Related
I am new to web programming in general, especially in Java, so I just learned what a header and body is.
I'm writing RESTful services using Spring MVC. I am able to create simple services with the #RequestMapping in my controllers. I need help understanding how to get HTTP header information from a request that comes to my method in my REST service controller. I would like to parse out the header and get some attributes from it.
Could you explain how I go about getting that information?
When you annotate a parameter with #RequestHeader, the parameter retrieves the header information. So you can just do something like this:
#RequestHeader("Accept")
to get the Accept header.
So from the documentation:
#RequestMapping("/displayHeaderInfo.do")
public void displayHeaderInfo(#RequestHeader("Accept-Encoding") String encoding,
#RequestHeader("Keep-Alive") long keepAlive) {
}
The Accept-Encoding and Keep-Alive header values are provided in the encoding and keepAlive parameters respectively.
And no worries. We are all noobs with something.
You can use the #RequestHeader annotation with HttpHeaders method parameter to gain access to all request headers:
#RequestMapping(value = "/restURL")
public String serveRest(#RequestBody String body, #RequestHeader HttpHeaders headers) {
// Use headers to get the information about all the request headers
long contentLength = headers.getContentLength();
// ...
StreamSource source = new StreamSource(new StringReader(body));
YourObject obj = (YourObject) jaxb2Mashaller.unmarshal(source);
// ...
}
My solution in Header parameters with example is user="test" is:
#RequestMapping(value = "/restURL")
public String serveRest(#RequestBody String body, #RequestHeader HttpHeaders headers){
System.out.println(headers.get("user"));
}
You can use HttpEntity to read both Body and Headers.
#RequestMapping(value = "/restURL")
public String serveRest(HttpEntity<String> httpEntity){
MultiValueMap<String, String> headers =
httpEntity.getHeaders();
Iterator<Map.Entry<String, List<String>>> s =
headers.entrySet().iterator();
while(s.hasNext()) {
Map.Entry<String, List<String>> obj = s.next();
String key = obj.getKey();
List<String> value = obj.getValue();
}
String body = httpEntity.getBody();
}
I'm trying to write a rest endpoint which receives application/x-www-form-urlencoded. But the endpoint does not accept request parameters for #RequestBody or #RequestParam
I Have tried using MultiValueMap to grab the request parameters. But I always get 0 parameters.
Is there a way to get request values to the MultiValueMap or some other POJO class.
AD=&value=sometestvalue - This is the application/x-www-form-urlencoded requestbody. I'm trying to do the request using postman
#RequestMapping(value = "/test/verification/pay/{id}", method = RequestMethod.POST,
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
#ResponseBody
public Response testVerificationPay(#PathVariable("id") long id, #RequestParam MultiValueMap formData,
HttpServletRequest servletRequest, ServiceContext serviceContext){
log.info("!--REQUEST START--!"+formData.toString());
}
You need to use MultiValueMap<String, String>
#RequestMapping(value = "/test/verification/pay/{id}", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
#ResponseBody
public Response testVerificationPay(#PathVariable("id") long id, #RequestParam MultiValueMap<String, String> formData) {
System.out.println("!--REQUEST START--!" + formData.toString());
return null;
}
You do not use #RequestParam on a POST request as the data is not in the URL as in a GET request.
You should use #RequestBody (doc) along with registering appropriate HttpMessageConverter. Most likely you should use: FormHttpMessageConverter
Try #ResponseBody. Then, change to a String, not a MultiValueMap, to see if the body comes in to the request.
Am new to spring currently am trying to do HTTP POST request application/x-www-form-url encoded but when i keep this in my headers then spring not recognizing it and saying 415 Unsupported Media Type
for x-www-form-urlencoded
org.springframework.web.HttpMediaTypeNotSupportedException: Content
type 'application/x-www-form-urlencoded' not supported
Can any one know how to solve it? please comment me.
An example of my controller is:
#RequestMapping(
value = "/patientdetails",
method = RequestMethod.POST,
headers="Accept=application/x-www-form-urlencoded")
public #ResponseBody List<PatientProfileDto> getPatientDetails(
#RequestBody PatientProfileDto name
) {
List<PatientProfileDto> list = new ArrayList<PatientProfileDto>();
list = service.getPatient(name);
return list;
}
The problem is that when we use application/x-www-form-urlencoded, Spring doesn't understand it as a RequestBody. So, if we want to use this
we must remove the #RequestBody annotation.
Then try the following:
#RequestMapping(value = "/patientdetails", method = RequestMethod.POST,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public #ResponseBody List<PatientProfileDto> getPatientDetails(
PatientProfileDto name) {
List<PatientProfileDto> list = new ArrayList<PatientProfileDto>();
list = service.getPatient(name);
return list;
}
Note that removed the annotation #RequestBody
you should replace #RequestBody with #RequestParam, and do not accept parameters with a java entity.
Then you controller is probably like this:
#RequestMapping(value = "/patientdetails", method = RequestMethod.POST,
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public #ResponseBody List<PatientProfileDto> getPatientDetails(
#RequestParam Map<String, String> name) {
List<PatientProfileDto> list = new ArrayList<PatientProfileDto>();
...
PatientProfileDto patientProfileDto = mapToPatientProfileDto(mame);
...
list = service.getPatient(patientProfileDto);
return list;
}
The solution can be found here https://github.com/spring-projects/spring-framework/issues/22734
you can create two separate post request mappings. For example.
#PostMapping(path = "/test", consumes = "application/json")
public String test(#RequestBody User user) {
return user.toString();
}
#PostMapping(path = "/test", consumes = "application/x-www-form-urlencoded")
public String test(User user) {
return user.toString();
}
Remove #ResponseBody annotation from your use parameters in method. Like this;
#Autowired
ProjectService projectService;
#RequestMapping(path = "/add", method = RequestMethod.POST)
public ResponseEntity<Project> createNewProject(Project newProject){
Project project = projectService.save(newProject);
return new ResponseEntity<Project>(project,HttpStatus.CREATED);
}
The easiest thing to do is to set the content type of your ajax request to "application/json; charset=utf-8" and then let your API method consume JSON. Like this:
var basicInfo = JSON.stringify({
firstName: playerProfile.firstName(),
lastName: playerProfile.lastName(),
gender: playerProfile.gender(),
address: playerProfile.address(),
country: playerProfile.country(),
bio: playerProfile.bio()
});
$.ajax({
url: "http://localhost:8080/social/profile/update",
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: basicInfo,
success: function(data) {
// ...
}
});
#RequestMapping(
value = "/profile/update",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE,
consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseModel> UpdateUserProfile(
#RequestBody User usersNewDetails,
HttpServletRequest request,
HttpServletResponse response
) {
// ...
}
I guess the problem is that Spring Boot has issues submitting form data which is not JSON via ajax request.
Note: the default content type for ajax is "application/x-www-form-urlencoded".
replace contentType : "application/x-www-form-urlencoded", by dataType : "text" as wildfly 11 doesn't support mentioned contenttype..
You have to tell Spring what input content-type is supported by your service. You can do this with the "consumes" Annotation Element that corresponds to your request's "Content-Type" header.
#RequestMapping(value = "/", method = RequestMethod.POST, consumes = {"application/x-www-form-urlencoded"})
It would be helpful if you posted your code.
I have an endpoint using Spring:
#RequestMapping(value = {"/hello"}, method = RequestMethod.GET)
#ResponseBody
public String getContent(#RequestParam(value = "url", required = true) String url)
I would like this to return the exact same response I would get if I send a GET to url. I'm using the Apache library to do my GET, which returns me a CloseableHttpResponse. How do I return this response as my endpoint's response? My current code copies this response, which is not what I want. I would directly like to return the CloseableHttpResponse. The reason I want to do this is because some websites have really huge data, and I would like to avoid having to copy those in place.
#RequestMapping(value = {"/hello"}, method = RequestMethod.GET)
#ResponseBody
public String getContent(#RequestParam(value = "url", required = true) String url, HttpServletResponse response)
CloseableHttpResponse httpResponse = useApacheLibraryAndSendGetToUrl(url);
for (Header header : httpResponse.getAllHeaders()) {
response.addHeader(header.getName(), header.getValue());
}
response.setStatus(httpResponse.getStatusLine().getStatusCode());
return EntityUtils.toString(entity, "UTF-8");
}
You could write a custom HttpMessageConverter for the CloseableHttpResponse type, which would allow you to simply return #ResponseBody CloseableHttpResponse.
See Mapping the response body with the #ResponseBody annotation for details.
I'm using Spring Restful web service & having request body with request header as shown below:
#RequestMapping(value = "/mykey", method = RequestMethod.POST, consumes="applicaton/json")
public ResponseEntity<String> getData(#RequestBody String body, #RequestHeader("Auth") String authorization) {
try {
....
} catch (Exception e) {
....
}
}
I want to pass one more optional request header called "X-MyHeader". How do I specify this optional request header in Spring rest service?
Also, how do I pass this same value in response header??
Thanks!
UPDATE: I just found that I can set required=false in request header, so one issue is resolved. Now, the only issue remaining is how do I set the header in the response??
Use required=false in your #RequestHeader:
#PostMapping("/mykey")
public ResponseEntity<String> getData(
#RequestBody String body,
#RequestHeader(value = "Auth", required = false) String authorization) {}
This question is answered here:
In Spring MVC, how can I set the mime type header when using #ResponseBody
Here is a code sample from: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-ann-httpentity
#RequestMapping("/something")
public ResponseEntity<String> handle(HttpEntity<byte[]> requestEntity) throws UnsupportedEncodingException {
String requestHeader = requestEntity.getHeaders().getFirst("MyRequestHeader");
byte[] requestBody = requestEntity.getBody();
// do something with request header and body
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("MyResponseHeader", "MyValue");
return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED);
}