posting xml to a spring REST endpoint is not getting unmarshalled into the relevant Java object
Solution 1
I was running across the same issue as well. Here's what my Controller method looked like:
@RequestMapping(method=RequestMethod.POST, value="/users/create",
headers="Accept=application/xml")
public @ResponseBody User createUser(@RequestBody User user) {
return user;
}
Basically, I was just going to return the user object as a proof-of-concept to make sure that my POST was working correctly. However, I kept running into the 'syntactically incorrect' message. Once I actually updated my code to retrieve a valid User object like so:
@RequestMapping(method=RequestMethod.POST, value="/users/create",
headers="Accept=application/xml")
public @ResponseBody User createUser(@RequestBody User user) {
userService.createUser(user);
// do work
User newUser = userService.getUserById(user.getId());
return newUser;
}
it started working correctly.
I tested my REST API using the following CURL command:
curl -X POST -HContent-type:application/xml -HAccept:application/xml --data "<user><username>Quinnster</username><password>password</password></user>" http://localhost:8080/api/users/create
Using a different API to list users, I was able to verify that my new user was created properly.
Again, not sure if this is the exact same problem you're having, but this solved it for me.
Thanks, Quinn
Solution 2
You might try change the @RequestMapping on the class from:
@RequestMapping("/users")
to:
@RequestMapping("/users/*")
And then change the method declaration to:
@RequestMaqpping(method=RequestMethod.POST)
@ResponseBody
public void create(@RequestBody User user) {
The url would then become: http://localhost:8080/rest/users/create, because spring will take the final portion of the url from the method name.
Uma Shankar
Updated on June 05, 2022Comments
-
Uma Shankar almost 2 years
I have a project where xsd are given. I use the xjc compiler to generate the Java classes. And then I annotate the class with XmlRootElement attribute. I have configured the sevlet with the Jaxb2 marshalling/unmarshalling bean in the AnnotationMethodHandlerAdapter. when I send an xml, without the namespaces, I get the 415 error.
The source code is as follows file - web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>Test</display-name> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app>
file - dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd" xmlns:oxm="http://www.springframework.org/schema/oxm"> <context:component-scan base-package="com.test.endpoints" /> <tx:annotation-driven /> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="marshallingHttpMessageConverter"/> </list> </property> </bean> <bean id="marshallingHttpMessageConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"> <constructor-arg ref="jaxb2Marshaller" /> </bean> <bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="classesToBeBound"> <list> <value>com.test.users.User</value> <value>com.test.users.Users</value> </list> </property> </bean> <!-- Should be defined last! --> <!-- <mvc:annotation-driven />--> </beans>
file - user.xsd
<element name="users"> <complexType> <sequence> <element name="user" type="tns:user" minOccurs="0" maxOccurs="unbounded" /> </sequence> </complexType> </element> <complexType name="user"> <sequence> <element name="id" type="int" /> <element name="email" type="string"></element> <element name="first_name" type="string"></element> <element name="last_name" type="string"></element> </sequence> </complexType> </schema>
Used this command to generate the Java classes for the above xsd.
xjc -p com.test.users ..\xsd\user.xsd
Output of this command is
parsing a schema... compiling a schema... com\test\users\ObjectFactory.java com\test\users\User.java com\test\users\Users.java com\test\users\package-info.java
Annotated User.java with @XmlRootElement(name="user").
file - UserService.java
package com.test.endpoints; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import com.test.users.User; @Controller @RequestMapping("/users") public class UserService { @RequestMapping(value="/new", method=RequestMethod.POST) @ResponseBody public User createUser(@RequestBody User user) { System.out.println(user.getFirstName()); return user; } }
Tested the REST api with this curl command
curl -X POST -HContent-type:application/xml -HAccept:application/xml --data "<?xml version="1.0" encoding="UTF-8"?><user><id>1</id><email>[email protected]</email><first_name>first_name</first_name><last_name>last_name</last_name></user>" http://localhost:8080/Test/rest/users/new
Output is
The request sent by the client was syntactically incorrect ()
Can somebody please point me where I am going wrong.
Thanks