Java &引用;406不可接受“;尝试为SpringWebMVC服务配置HTTP上的XML封送时
一个玩具的例子,抓住了我的问题是。简而言之,我有一个需要通过HTTP将XML封送回的服务。我正在尝试使用SpringWebMVC来设置它。需要封送回来的响应对象是从模式生成的JAXB2(因此缺少@XmlRootElement标记,但生成它的包有一个ObjectFactory,它提供了生成JAXBElement-s的方法,这使XML封送员感到高兴)。我尝试了不同的基于谷歌搜索的spring上下文配置,这些配置主要是在stack overflow上点击这里的帖子,但没有一个适合我 环境:Java &引用;406不可接受“;尝试为SpringWebMVC服务配置HTTP上的XML封送时,java,xml,spring,spring-mvc,xml-serialization,Java,Xml,Spring,Spring Mvc,Xml Serialization,一个玩具的例子,抓住了我的问题是。简而言之,我有一个需要通过HTTP将XML封送回的服务。我正在尝试使用SpringWebMVC来设置它。需要封送回来的响应对象是从模式生成的JAXB2(因此缺少@XmlRootElement标记,但生成它的包有一个ObjectFactory,它提供了生成JAXBElement-s的方法,这使XML封送员感到高兴)。我尝试了不同的基于谷歌搜索的spring上下文配置,这些配置主要是在stack overflow上点击这里的帖子,但没有一个适合我 环境: 弹簧4.
- 弹簧4.0.5
- Tomcat 7.0.5X
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="urn:io:github:gv0tch0:sotaro"
targetNamespace="urn:io:github:gv0tch0:sotaro"
version="0.0.1">
<xs:element name="say" type="tns:SayWhat" />
<xs:complexType name="SayWhat">
<xs:sequence>
<xs:element name="what" type="xs:string" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:schema>
因此,罪魁祸首是响应对象周围缺少的JAXBElement
-包装器和配置为支持JAXBElement
包装的响应的Jaxb2Marshaller
@Controller变为:
@Controller
public class Say {
private final static ObjectFactory JAXB_FACTORY = new ObjectFactory();
@RequestMapping(value = "/say/{what}",
produces = {MediaType.APPLICATION_XML_VALUE},
method = RequestMethod.GET)
public @ResponseBody JAXBElement<SayWhat> say(@PathVariable("what") String what) {
return echo(what);
}
private JAXBElement<SayWhat> echo(String what) {
SayWhat echo = new SayWhat();
echo.setWhat(what);
return JAXB_FACTORY.createSay(echo);
}
}
如果Jaxb2Marshaller实现发现JAXB注释类所在的包中包含一个ObjectFactory
,能够将响应包装在JAXBElement
-s中,并使用原始配置进行开箱即用,那就太好了。您尝试过返回吗JAXBElement
取而代之。我刚刚做了。没有解决这个问题。也使分支中的更改可用。几乎总是这样,没有什么可以替代读取某些代码。因此Jaxb2Marshaller
需要将其supportJaxbElementClass
属性配置为true
,才能支持编组JAXBElement
-s。一旦出现这种情况,响应对象当然被包装在JAXBElement
中,世界上一切都好。哇。。堆栈上此处的注释编辑规则为。。奇怪的总之,继续前面的评论:代码还揭示了如果响应不是JAXBElement
-包装的,则需要对其进行JAXB注释,并具有@XmlRootElement注释。除非编组实现(例如EclipseLink MOXy)支持并获得外部绑定源。我整天都在努力解决这个问题,我发现你的问题就在这里。这帮了大忙。这也适用于Github中的示例。非常感谢你。
@Controller
public class Say {
@RequestMapping(value = "/say/{what}",
produces = {MediaType.APPLICATION_XML_VALUE},
method = RequestMethod.GET)
public @ResponseBody SayWhat say(@PathVariable("what") String what) {
return echo(what);
}
private SayWhat echo(String what) {
SayWhat echo = new SayWhat();
echo.setWhat(what);
return echo;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SayWhat", propOrder = {"what"})
public class SayWhat {
@XmlElement(required = true)
protected String what;
public String getWhat() {
return what;
}
public void setWhat(String value) {
this.what = value;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="urn:io:github:gv0tch0:sotaro"
targetNamespace="urn:io:github:gv0tch0:sotaro"
version="0.0.1">
<xs:element name="say" type="tns:SayWhat" />
<xs:complexType name="SayWhat">
<xs:sequence>
<xs:element name="what" type="xs:string" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:schema>
@Controller
public class Say {
private final static ObjectFactory JAXB_FACTORY = new ObjectFactory();
@RequestMapping(value = "/say/{what}",
produces = {MediaType.APPLICATION_XML_VALUE},
method = RequestMethod.GET)
public @ResponseBody JAXBElement<SayWhat> say(@PathVariable("what") String what) {
return echo(what);
}
private JAXBElement<SayWhat> echo(String what) {
SayWhat echo = new SayWhat();
echo.setWhat(what);
return JAXB_FACTORY.createSay(echo);
}
}
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="supportJaxbElementClass" value="true"/>
<property name="packagesToScan">
<list>
<value>io.github.gv0tch0.sotaro</value>
</list>
</property>
</bean>