Java &引用;406不可接受“;尝试为SpringWebMVC服务配置HTTP上的XML封送时

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.

一个玩具的例子,抓住了我的问题是。简而言之,我有一个需要通过HTTP将XML封送回的服务。我正在尝试使用SpringWebMVC来设置它。需要封送回来的响应对象是从模式生成的JAXB2(因此缺少@XmlRootElement标记,但生成它的包有一个ObjectFactory,它提供了生成JAXBElement-s的方法,这使XML封送员感到高兴)。我尝试了不同的基于谷歌搜索的spring上下文配置,这些配置主要是在stack overflow上点击这里的帖子,但没有一个适合我

环境:

  • 弹簧4.0.5
  • Tomcat 7.0.5X
下面是一个请求/响应周期示例,它显示了问题(省略了一些输出):

响应对象(JAXB2生成):

以及它所生成的模式:

<?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>