отправка xml в конечную точку REST-пружины не приводит к разбивке в соответствующем Java-объекте - PullRequest
3 голосов
/ 14 марта 2011

У меня есть проект, где даны xsd.Я использую компилятор xjc для генерации классов Java.И затем я аннотирую класс с атрибутом XmlRootElement.Я сконфигурировал sevlet с bean-компонентом Jaxb2 для маршаллинга / демаршаллинга в AnnotationMethodHandlerAdapter.когда я отправляю xml без пространств имен, я получаю ошибку 415.

Исходный код выглядит следующим образом: 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>

Использовал эту команду для генерации классов Java для вышеуказанного xsd.

xjc -p com.test.users ..\xsd\user.xsd

Вывод этой команды:

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

Аннотированный User.java с @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;
    }
}

Протестировал API REST с помощью этой команды curl

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

Вывод

The request sent by the client was syntactically incorrect ()

Может кто-нибудь указать мне, где я иду не так.

Спасибо

Ответы [ 3 ]

3 голосов
/ 12 июля 2011

Я тоже столкнулся с той же проблемой. Вот как выглядел мой метод Controller:

@RequestMapping(method=RequestMethod.POST, value="/users/create",
        headers="Accept=application/xml")
public @ResponseBody User createUser(@RequestBody User user) {
    return user;
}

По сути, я просто собирался вернуть пользовательский объект в качестве подтверждения концепции, чтобы убедиться, что мой POST работает правильно. Однако я продолжал сталкиваться с «синтаксически некорректным» сообщением. Как только я действительно обновил свой код, чтобы получить действительный объект User, например, так:

@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;
}

он начал работать правильно.

Я протестировал мой REST API с помощью следующей команды CURL:

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

Используя другой API для составления списка пользователей, я смог проверить, правильно ли был создан мой новый пользователь.

Опять же, не уверен, что это точно такая же проблема, как у вас, но это решило ее для меня

Спасибо, Quinn

1 голос
/ 14 марта 2011

Вы можете попробовать изменить @RequestMapping для класса с:

@RequestMapping("/users")

до:

@RequestMapping("/users/*")

А затем измените объявление метода на:

@RequestMaqpping(method=RequestMethod.POST)
@ResponseBody
public void  create(@RequestBody User user) {

В этом случае URL станет: http://localhost:8080/rest/users/create,, потому что spring будет брать последнюю часть URL из имени метода.

0 голосов
/ 14 марта 2011

Попробуйте изменить строку скручивания на

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

Это были кавычки в XML, которые могли помешать вводу

...