I know this question has been asked before, and I've checked every message of Spring MVC with the 406 error message and I am beside myself not knowing how to fix this problem since I've tried just about everything put fourth by these previous answers.
This one web-service takes an email address, and returns back a user object in JSON. I can tell you the unit test works great. And I know we pass the Spring Security, we are executing the servlet ... the only problem now is the JSON output ... I don't get that, I get this error message.
So, to be exact:
Spring Core: 4.2.4.RELEASE
Spring Security: 4.0.3.RELEASE
Jackson Faster XML: 2.6.5 (core, databind, annotations)
2.7.0 doesn't seem to work yet ...
Here is the springmvc-servlet.xml:
<context:annotation-config />
<context:component-scan base-package="com.agmednet.server.controller" />
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.agmednet.server.HibernateAwareObjectMapper">
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss.SSS"></constructor-arg>
</bean>
</property>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
Here is the controller:
#Controller
#RequestMapping("/users")
public class UserAccountController
{
#Autowired
private UserAccountService userAccountService;
#RequestMapping(value = "/email/{email:.*}", method = RequestMethod.GET)
public #ResponseBody UserAccountEntity getByEmailAddress(#PathVariable("email") String email)
{
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
User user = null;
if (principal instanceof User)
{
user = ((User) principal)
}
UserAccountEntity userAccount = userAccountService.getByEmailAddress(email);
return userAccount;
}
}
As you can see, I have the Accept header setup, I have the #ResponseBody annotation.
I have a SimpleCORSFilter Code on top of this:
#Component
public class SimpleCORSFilter implements Filter
{
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
{
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type, Accept, If-Modified-Since, openam_token");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig){}
public void destroy(){}
}
As you can see, this accepts my custom header for an "openam_token", but is has
"Accept" and "Content-Type" as well.
I am calling this from a linux box behind a firewall, so I have to SSH into the machine, and execute this curl statement:
curl -v -i -X GET -H "openam_token: AQIC5wM2LY4Sfcxfw-GSBSndg-4DMEyrEqcBgiTE4b4e3aE.*AAJTSQACMDE.*" -H "Content-Type: application/json, text/html" -H "Accept: application/json, text/html" backend.spring.mycompany.net:8080/services/api/users/email/user4252002#mycompany.com
So, here is what I am sending via curl in the request:
* Trying 10.0.4.107...
* Connected to backend.spring.agmednet.net (10.0.4.107) port 8080 (#0)
> GET /services/api/users/email/user4252002#agmednet.com HTTP/1.1
> User-Agent: curl/7.40.0
> Host: backend.spring.agmednet.net:8080
> openam_token: AQIC5wM2LY4Sfcxfw-GSBSndg-4DMEyrEqcBgiTE4b4e3aE.*AAJTSQACMDE.*
> Content-Type: application/json, text/html
> Accept: application/json, text/html
And here is the response:
< HTTP/1.1 406 Not Acceptable
HTTP/1.1 406 Not Acceptable
< Server: Apache-Coyote/1.1
Server: Apache-Coyote/1.1
< Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS, DELETE
Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS, DELETE
< Access-Control-Max-Age: 3600
Access-Control-Max-Age: 3600
< Access-Control-Allow-Headers: x-requested-with, Content-Type, Accept, If-Modified-Since, openam_token
Access-Control-Allow-Headers: x-requested-with, Content-Type, Accept, If-Modified-Since, openam_token
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
Pragma: no-cache
< Expires: 0
Expires: 0
< X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; mode=block
< X-Frame-Options: DENY
X-Frame-Options: DENY
< X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
< Set-Cookie: JSESSIONID=76C4B28DD0B5D88EB9341944BDBCD045; Path=/services/; HttpOnly
Set-Cookie: JSESSIONID=76C4B28DD0B5D88EB9341944BDBCD045; Path=/services/; HttpOnly
< Content-Type: text/html;charset=utf-8
Content-Type: text/html;charset=utf-8
< Content-Language: en
Content-Language: en
< Content-Length: 1110
Content-Length: 1110
< Date: Wed, 20 Jan 2016 14:30:28 GMT
Date: Wed, 20 Jan 2016 14:30:28 GMT
<!DOCTYPE html>
<html><head>
<title>Apache Tomcat/8.0.30 - Error report</title>
</head>
<body>
<h1>HTTP Status 406 - </h1>
<div class="line"></div><p><b>type</b> Status report</p>
<p><b>message</b> <u></u></p>
<p><b>description</b>
<u>The resource identified by this request is only capable of generating
responses with characteristics not acceptable according to the request*
Connection #0 to host backend.spring.agmednet.net left intact
"accept" headers.</u></p>
<hr class="line"><h3>Apache Tomcat/8.0.30</h3></body></html>
Ultimately, this is the error message listed above:
The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request* Connection #0 to host backend.spring.mycompany.net left intact
"accept" headers.
So, I am using #ResponseBody, I am using the latest Jackson 2.x version. I am following all the suggestions from previous questions and I still can't get this to work.
Any help would be much appreciated.
The #EnableWebMVC wasn't the problem, and everything you see in the question is 100% correct. I have two other web-services that worked fine. The problem ultimately was with the curl statement itself:
curl -v -i -X GET -H /
"openam_token: AQIC5wM2LY4Sfcxfw-GSBSndg-4DMEyrEqcBgiTE4b4e3aE.*AAJTSQACMDE.*" /
-H "Content-Type: application/json, text/html" /
-H "Accept: application/json, text/html" /
backend.spring.mycompany.net:8080/services/api/users/email/user4252002#mycompany.com
If you notice, the URL and the path variable is not in quotes.
if you notice, the email address has an # symbol in it, which I found out means something to curl. So, what I did was change my curl to the following.
curl -v -i -X GET -H /
"openam_token: AQIC5wM2LY4Sfcxfw-GSBSndg-4DMEyrEqcBgiTE4b4e3aE.*AAJTSQACMDE.*" /
-H "Content-Type: */*" /
-H "Accept: */*" /
"backend.spring.mycompany.net:8080/services/api/users/email/user4252002%40mycompany%2Ecom"
1) I encoded the email address myself # to %40 and period-dot to %2E
You can use whatever tool you meant to encode the path variable.
2) Even though I am returning a java object transformed into JSON, I changed headers "Accept" and "Content-Type" to "/".
That was it. This worked and the 406 error message went away.
Related
When I run the Spring Application and then try to comunicate with
the REST API it allows me to GET but not to POST.
So this works:
curl -u user:a75fd7ea-9a6e-4943-bc0c-3b0a96bda51b http://localhost:5000/activity/getall
This does not work:
curl -u user:a75fd7ea-9a6e-4943-bc0c-3b0a96bda51b
-H "Accept: application/json"
-X POST
-d '{
"name":"Sleep",
"criteria":"Sleep at least 8 hrs",
"ini":"2022-08-30",
"periodicity":"DAY",
"periodicityCount":"1"
}'
http://localhost:5000/activity/post
If you notice is the same Username and Password.
This is the response I get:
HTTP/1.1 403
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json
Transfer-Encoding: chunked
Date: Mon, 29 Aug 2022 19:25:27 GMT
Connection: close
{
"timestamp": "2022-08-29T19:25:27.510+00:00",
"status": 403,
"error": "Forbidden",
"path": "/activity/post"
}
The reason why your API calls fail is due to the CSRF protection you enabled in your Spring Security configuration.
The way this works is that for each non-GET request (= POST, PUT, PATCH or DELETE), you need to include a CSRF token.
To obtain a CSRF token, you first need to fire a GET request (eg. http://localhost:5000/activity/getall). In the response headers, you should see a Set-Cookie header containing an XSRF-TOKEN cookie. For example:
Set-Cookie: XSRF-TOKEN=098b732a-282a-11ed-a261-0242ac120002
Now you need to copy the value of the XSRF-TOKEN cookie (should contain a UUID), and set it as the value of the X-XSRF-TOKEN header:
curl \
-u user:a75fd7ea-9a6e-4943-bc0c-3b0a96bda51b
-H "Accept: application/json"
-H "X-XSRF-TOKEN: 098b732a-282a-11ed-a261-0242ac120002"
-X POST \
-d '{
"name":"Sleep",
"criteria":"Sleep at least 8 hrs",
"ini":"2022-08-30",
"periodicity":"DAY",
"periodicityCount":"1"
}'
http://localhost:5000/activity/post
After that, your request should succeed. Be aware, the response of this POST-request will contain a new CSRF token that you will have to copy to your next request.
Alternatively, you can disable CSRF protection by setting .csrf().disable() in your Spring Security configuration.
I'm specifically trying to test the case where my application doesn't receive a Content-Length header from the server, so I've set up my code not to include that header, but for some reason Spring is including it anyway with a value of 0:
#RequestMapping(value = "/test", method = RequestMethod.HEAD)
public void headTest(HttpServletRequest request, HttpServletResponse response) {
response.addDateHeader("Date", System.currentTimeMillis());
response.addHeader("Accept-Ranges", "bytes");
response.addHeader("Content-Type", "video/mp4");
}
$ curl -I http://myserver.com:8600/test
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Date: Thu, 28 Jul 2022 01:05:11 GMT
Accept-Ranges: bytes
Content-Type: video/mp4
Content-Length: 0
How can I stop Spring from including this header?
Setting a header to null to effectively remove it from the response works for embedded Tomcat and might work for other servers:
response.setHeader("Content-Length", null);
I have read a lot about CORS, preflight etc, I know the problem is related to it, but couldn't figure out, what's going on here.
I'm using VueJs and SpringBoot with Spring Security and jsonwebtoken.
When I make a POST request /login on Postman:
{
"username":"admin",
"password":"password"
}
I got the right response with the expected token:
http 200 with headers:
{
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTYwODI5OTIxMn0.9oXFpm9DivR3DNPcBaoc_KgsqNdBJbkFq_oA4pBJbXF2iUwx7_XfBwv-Xcn-da9LS9M5zxd8oRslr_wdVyoQkA,
X-Content-Type-Options:nosniff
X-XSS-Protection:1; mode=block
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Pragma:no-cache
Expires:0
X-Frame-Options:DENY
Content-Length:0
}
However, when the front-End calls the service I got the following answer with the wrong header, there is no token:
http 200 with headers
{
cache-control: "no-cache, no-store, max-age=0, must-revalidate",
content-length: "0", expires: "0", pragma: "no-cache"
}
When I open the browser with security disabled it works fine as well, I got the expected token on the header...
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --user-data-dir="C://Chrome dev session" --disable-web-security
So it seems to be related to Cors indeed, but I don't get any Cors error message!
I used fiddler to track the requests and responses and I notice that the option method is happening, So my first question is, should the options response go up to the front-end? as far as I know the options stay within the browser boundary and then the browser makes the post request (if the server allowed).
Options Request:
OPTIONS http://ec2-52-4-252-232.compute-1.amazonaws.com:9090/login HTTP/1.1
Host: ec2-52-4-252-232.compute-1.amazonaws.com:9090
Connection: keep-alive
Accept: */*
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization
Origin: http://s3-sa-east-1.amazonaws.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36
Sec-Fetch-Mode: cors
Referer: http://s3-sa-east-1.amazonaws.com/
Accept-Encoding: gzip, deflate
Accept-Language: pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6
Options Response:
HTTP/1.1 200
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: http://s3-sa-east-1.amazonaws.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: authorization
Access-Control-Allow-Credentials: true
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 0
Date: Tue, 08 Dec 2020 14:58:56 GMT
Post Request:
POST http://ec2-52-4-252-232.compute-1.amazonaws.com:9090/login HTTP/1.1
Host: ec2-52-4-252-232.compute-1.amazonaws.com:9090
Connection: keep-alive
Content-Length: 42
Accept: application/json, text/plain, */*
Authorization: undefined
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Origin: http://s3-sa-east-1.amazonaws.com
Referer: http://s3-sa-east-1.amazonaws.com/
Accept-Encoding: gzip, deflate
Accept-Language: pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6
{
"username":"admin",
"password":"password"
}
Post Response:
HTTP/1.1 200
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: http://s3-sa-east-1.amazonaws.com
Access-Control-Allow-Credentials: true
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTYwODI5OTUzNn0.0UgsNHd9Aw9Ei5aq-k0y74BlxJ92-j7w-FrryZaDAwzLC1a2OpSH3rXhRWGIul3wqpWLbqJ7icNlM3d590UFWw
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 0
Date: Tue, 08 Dec 2020 14:58:56 GMT
Part of My front-end Code:
login({ commit }, user) {
const cors = require('cors')({
origin: true
});
const qs = require('querystring')
return new Promise((resolve, reject) => {
commit('auth_request')
axios({
url: process.env.VUE_APP_BACKEND_ENDPOINT + '/login', data: user, method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded'}
})
.then(resp => {
console.log(resp.headers)
const token = resp.headers["authorization"]
localStorage.setItem('token', token)
axios.defaults.headers.common['Authorization'] = token
commit('auth_success', token, user.username)
resolve(resp)
})
.catch(err => {
commit('auth_error')
localStorage.removeItem('token')
reject(err)
})
})
Part of my Back-End Code:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors().configurationSource(corsConfigurationSource()).and()
.csrf().disable().authorizeRequests()
.antMatchers("/home").permitAll()
.antMatchers(HttpMethod.POST, "/login").permitAll()
.anyRequest().authenticated()
.and()
// filtra requisições de login
.addFilterBefore(new JWTLoginFilter("/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
// filtra outras requisições para verificar a presença do JWT no header
.addFilterBefore(new JWTAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
}
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
List<String> allowOrigins = Arrays.asList("*");
configuration.setAllowedOrigins(allowOrigins);
configuration.setAllowedMethods(singletonList("*"));
configuration.setAllowedHeaders(singletonList("*"));
//in case authentication is enabled this flag MUST be set, otherwise CORS requests will fail
//configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// cria uma conta default
auth.inMemoryAuthentication()
.withUser("admin")
.password("{noop}password")
.roles("ADMIN");
}
}```
Anyone knows what's going on here ? Why the Post response isn't coming to the front-end ?
I spend many hours but couldn't solve it, so I appreciate any help.
I can reproduce your Postman request with curl:
curl -vv -H "Content-Type: application/x-www-form-urlencoded" http://ec2-52-4-252-232.compute-1.amazonaws.com:9090/login -d '{"username":"admin", "password":"password"}'
Returns a 200 with the Authorization header filled in.
Can you run the frontend code with the Network tab in Developer Tools open and see how the POST request looks?
And possibly right-click and "copy as cURL" and then compare it to the curl request above.
Actually my problem wasn't related to options method as I thought, the problem was that I was missing the Access-Control-Expose-Headers which should also be presented in the headers of server response.
I just set it on my springboot app and it worked fine !
List<String> exposedHeaders = Arrays.asList("Authorization");
configuration.setExposedHeaders(exposedHeaders);
I got the answer from this one: axios response headers missing data when running in vuejs app
I am in the context of a Rest API. As I am performing cross domain request, I need to send back the header "Access-Control-Allow-Origin".
I have a controller such:
#Controller
#RequestMapping("/api")
public class PackageManagerRestController {
#RequestMapping(method = RequestMethod.OPTIONS, value = "/test")
public void commonOptions(HttpServletResponse theHttpServletResponse) throws IOException {
theHttpServletResponse.addHeader("Access-Control-Allow-Headers", "origin, content-type, accept, x-requested-with");
theHttpServletResponse.addHeader("Access-Control-Max-Age", "60"); // seconds to cache preflight request --> less OPTIONS traffic
theHttpServletResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
theHttpServletResponse.addHeader("Access-Control-Allow-Origin", "*");
}
#RequestMapping(method = RequestMethod.GET, value = "/test")
public void getPtions(HttpServletResponse theHttpServletResponse) throws IOException {
theHttpServletResponse.addHeader("Access-Control-Allow-Headers", "origin, content-type, accept, x-requested-with");
theHttpServletResponse.addHeader("Access-Control-Max-Age", "60"); // seconds to cache preflight request --> less OPTIONS traffic
theHttpServletResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
theHttpServletResponse.addHeader("Access-Control-Allow-Origin", "*");
}
}
If I run a test with GET, the result is as expected:
$ curl -i -X GET http://localhost:8081/api/test
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Access-Control-Allow-Headers: origin, content-type, accept, x-requested-with
Access-Control-Max-Age: 60
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *
Content-Length: 0
Date: Wed, 16 Apr 2014 08:18:38 GMT
However, if I send the request with OPTIONS, the controller never handles the request:
$ curl -i -X OPTIONS http://localhost:8081/api/test
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Content-Length: 0
Date: Wed, 16 Apr 2014 08:19:56 GMT
Anyone has any clue of why I am receiving this "default response" and why I cannot customize it ?
For default Spring DispatcherServlet supports GET, HEAD, POST, PUT, PATCH and DELETE only; if you want to support TRACE and OPTIONS you have to put "dispatchOptionsRequest" and "dispatchTraceRequest" properties to "true"; check here docs.spring.io/spring/docs/4.0.3.RELEASE/javadoc-api
In order to support OPTIONS too in your web.xml you have to put this:
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>
By adding it I can handle OPTIONS:
~$ curl -i -X OPTIONS http://localhost:8180/sample/api/test
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Access-Control-Allow-Headers: origin, content-type, accept, x-requested-with
Access-Control-Max-Age: 60
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Content-Length: 0
Date: Wed, 16 Apr 2014 08:44:55 GMT
Angelo
according to the last answer
I resolve my problem
#RequestMapping(value = "/**",method = RequestMethod.OPTIONS)
public String getOption(HttpServletResponse response,Model model)
{
response.setHeader("Access-Control-Allow-Origin","*");
response.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
return "";
}
and we need to add something to the dispacherservlet
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>
and this is over
This is my curl method request maps to POJO that fails with 400:
CURL REQUEST:
curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"key":"XYZ","uniqueId":"ABCD"}' http://localhost:8080/api/rest/connect/tick/view.json
* Adding handle: conn: 0x1cb54c0
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x1cb54c0) send_pipe: 1, recv_pipe: 0
* About to connect() to localhost port 8080 (#0)
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> POST /api/rest/connect/tick/view.json HTTP/1.1
> User-Agent: curl/7.32.0
> Host: localhost:8080
> Accept: application/json
> Content-type: application/json
> Content-Length: 53
>
* upload completely sent off: 53 out of 53 bytes
< HTTP/1.1 400 Bad Request
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Content-Type: text/html;charset=utf-8
< Content-Length: 971
< Date: Thu, 19 Sep 2013 13:16:29 GMT
< Connection: close
APPLICATION-CONFIG.XML:
<context:annotation-config/>
<mvc:annotation-driven/>
followed by, Bean Definitions
CONTROLLER CLASS:
#RequestMapping(value="/tick/view.*", method = RequestMethod.POST, consumes=MediaType.APPLICATION_JSON_VALUE, produces=MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public IConnectResponse tickConnectPost(#RequestBody final ConnectServiceBean connectServiceBean) {
CONNECTSERVICEBEAN:
import java.io.Serializable;
public class ConnectServiceBean implements Serializable {
private static final long serialVersionUID = 1L;
private String key;
private String uniqueId;
//Getters and setters }
But is working for another method request maps to String:
curl -i -H "Content-Type: application/json" -X POST -d '{"JKL#user.com"}' http://localhost:8080/api/rest/connect/tick/XYZ/view.json
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Pragma: no-cache
Cache-Control: no-cache, no-store, max-age=0
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: application/json;charset=UTF-8
Content-Language: en-GB
Transfer-Encoding: chunked
Date: Thu, 19 Sep 2013 13:11:40 GMT
CONTROLLER:
#RequestMapping(value="/tick/{key}/view.*", method = RequestMethod.POST, consumes="application/json", produces = "application/json; charset=utf-8")
public IConnectResponse tickConnectPostString (
#PathVariable("key") String key, #RequestBody String uniqueId
) {}
I felt that there is something wrong with Jackson Mapping. But I have all the necessary POM dependencies also I read in some other stackoverflow post where I need only for Jackson configurations for bean mappings(not sure though)
org.codehaus.jackson
jackson-core-asl
1.9.7
org.codehaus.jackson
jackson-mapper-asl
1.9.7