将 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
posting xml to a spring REST endpoint is not getting unmarshalled into the relevant Java object
提问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 中的引号,可能会干扰输入