开发者

posting xml to a spring REST endpoint is not getting unmarshalled into the relevant Java object

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@email.com</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


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


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.


Try change the curl line to

curl -X POST -HContent-type:application/xml -HAccept:application/xml  \
     --data '<?xml version="1.0" encoding="UTF-8"?><user><id>1</id><email>email@email.com</email><first_name>first_name</first_name><last_name>last_name</last_name></user>' \
     http://localhost:8080/Test/rest/users/new

Their were quotation marks in the XML which may have interfered with the input

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜