将 xml 发布到 spring REST 端点不会被解组到相关的 Java 对象中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5297893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 10:29:23  来源:igfitidea点击:

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

javamodel-view-controllerspringjaxbjaxb2

提问by Uma Shankar

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.

我有一个项目,其中给出了 xsd。我使用 xjc 编译器来生成 Java 类。然后我用 XmlRootElement 属性注释该类。我已经在 AnnotationMethodHandlerAdapter 中使用 Jaxb2 编组/解组 bean 配置了 sevlet。当我发送一个没有命名空间的 xml 时,我收到 415 错误。

The source code is as follows file - web.xml

源代码如下文件-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

文件 - 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

文件 - 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.

使用此命令为上述 xsd 生成 Java 类。

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").

使用 @XmlRootElement(name="user") 注释 User.java。

file - UserService.java

文件 - 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 命令测试了 REST api

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

谢谢

回答by Quinn

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:

基本上,我只是将用户对象作为概念验证返回,以确保我的 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;
}

it started working correctly.

它开始正常工作。

I tested my REST API using the following CURL command:

我使用以下 CURL 命令测试了我的 REST API:

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.

使用不同的 API 列出用户,我能够验证我的新用户是否正确创建。

Again, not sure if this is the exact same problem you're having, but this solved it for me.

同样,不确定这是否与您遇到的问题完全相同,但这为我解决了。

Thanks, Quinn

谢谢,奎因

回答by Kevin

You might try change the @RequestMapping on the class from:

您可以尝试将类上的 @RequestMapping 更改为:

@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.

该 url 将变为:http://localhost:8080/rest/users/create,因为 spring 将从方法名称中获取 url 的最后一部分。

回答by David Rabinowitz

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 protected]</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

它们是 XML 中的引号,可能会干扰输入