【问题标题】:POJO JAXB annotation not converting to XMLPOJO JAXB 注释未转换为 XML
【发布时间】:2014-03-22 03:11:42
【问题描述】:

我有一个用 JAXB 注释的简单 POJO“问候语”,并试图从 Java Restful 服务返回 XML。但是,每当我尝试访问网页时,POJO 都没有成功转换为 XML。我的日志中出现 Http 406 错误:

o.s.w.s.m.a.AnnotationMethodHandlerExceptionResolver - Resolving exception from handler [GreetingController@20b722]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

我可以很好地返回一个简单的字符串,但是当我尝试返回我的 POJO 时,它会出错。

我使用的是 Spring-MVC 结构。

Greeting.java:

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Greeting {


    private String id;
    private String content;

    public Greeting() {

    }

    public void setId(String id) {
        this.id = id;
    }

    @XmlElement
    public String getId() {
        return id;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @XmlElement
    public String getContent() {
        return content;
    }
}

控制器:

@Controller
@RequestMapping("/greeting")
public class GreetingController {

    protected final Logger log = LoggerFactory.getLogger(GreetingController.class);

    private static final String template = "Hello, %s!";
    private static Random rand = new Random();


    //Returns correct string
    @RequestMapping(method = RequestMethod.GET, value="/goodbye", headers="Accept=application/xml")
    public @ResponseBody String letsReturnAString() {
        log.info("Entered letsReturnAString()");

        return "Curses, Foiled Again!";
    }

    //Returns Http 406
    @RequestMapping(method = RequestMethod.GET, headers="Accept=application/xml")
    public @ResponseBody Greeting greeting() {
        log.info("Entered greeting()");

        Greeting g = new Greeting();
        g.setId(rand.nextInt(99999999) +"");
        g.setContent(String.format(template, "NAME"));

        return g;
    }
}

Context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:security="http://www.springframework.org/schema/security"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:oxm="http://www.springframework.org/schema/oxm"
    xmlns:mvc="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

    <context:component-scan base-package="com.package" />

    <mvc:annotation-driven/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="prefix">
            <value>/WEB-INF/pages/</value>
      </property>
      <property name="suffix">
            <value>.jsp</value>
      </property>
    </bean>

    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="mediaTypes">
      <map>
          <entry key="html" value="text/html"></entry>
          <entry key="json" value="application/json"></entry>
          <entry key="xml"  value="application/xml"></entry>
      </map>
    </property>
    <property name="viewResolvers">
        <list>
          <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
            <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
            <property name="prefix" value="/WEB-INF/jsp/"></property>
            <property name="suffix" value=".jsp"></property>
          </bean>
        </list>
    </property>
</bean>

</beans>

与点击页面相关的完整错误日志:

DEBUG o.s.security.web.FilterChainProxy - /greeting at position 1 of 12 in additional filter chain; firing Filter: 'ChannelProcessingFilter'
DEBUG o.s.s.web.util.AntPathRequestMatcher - Request '/greeting' matched by universal pattern '/**'
DEBUG o.s.s.w.a.c.ChannelProcessingFilter - Request: FilterInvocation: URL: /greeting; ConfigAttributes: [ANY_CHANNEL]
DEBUG o.s.security.web.FilterChainProxy - /greeting at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No HttpSession currently exists
DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: null. A new one will be created.
DEBUG o.s.security.web.FilterChainProxy - /greeting at position 3 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
DEBUG o.s.security.web.FilterChainProxy - /greeting at position 4 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
DEBUG o.s.security.web.FilterChainProxy - /greeting at position 5 of 12 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
DEBUG o.s.security.web.FilterChainProxy - /greeting at position 6 of 12 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
DEBUG o.s.security.web.FilterChainProxy - /greeting at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
DEBUG o.s.security.web.FilterChainProxy - /greeting at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
DEBUG o.s.security.web.FilterChainProxy - /greeting at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
DEBUG o.s.security.web.FilterChainProxy - /greeting at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
DEBUG o.s.security.web.FilterChainProxy - /greeting at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
DEBUG o.s.security.web.FilterChainProxy - /greeting at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
DEBUG o.s.s.web.util.AntPathRequestMatcher - Checking match of request : '/greeting'; against '/welcome*'
DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /greeting; Attributes: [IS_AUTHENTICATED_ANONYMOUSLY]
DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.RoleVoter@84fdbc, returned: 0
DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.access.vote.AuthenticatedVoter@12e5c94, returned: 1
DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
DEBUG o.s.security.web.FilterChainProxy - /greeting reached end of additional filter chain; proceeding with original chain
DEBUG o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 'spring-tutorial' processing GET request for [/SpringMVC/greeting]
DEBUG o.s.w.s.m.a.DefaultAnnotationHandlerMapping - Mapping [/greeting] to HandlerExecutionChain with handler [com.package.controller.GreetingController@20b722] and 1 interceptor
DEBUG o.s.web.servlet.DispatcherServlet - Last-Modified value for [/SpringMVC/greeting] is: -1
DEBUG o.s.w.b.a.s.HandlerMethodInvoker - Invoking request handler method: public com.package.form.Greeting com.package.controller.GreetingController.greeting()
INFO  c.s.controller.GreetingController - Entered greeting()
DEBUG o.s.w.s.m.a.AnnotationMethodHandlerExceptionResolver - Resolving exception from handler [com.package.controller.GreetingController@20b722]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver - Resolving exception from handler [com.package.controller.GreetingController@20b722]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
DEBUG o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolving exception from handler [com.package.controller.GreetingController@20b722]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'spring-tutorial': assuming HandlerAdapter completed request handling
DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed

【问题讨论】:

  • 您是否在上下文文件中配置了 jaxb? mkyong.com/spring-mvc/spring-3-mvc-and-xml-example
  • 是的,我的上下文文件中有&lt;mvc:annotation-driven/&gt;。见编辑。另外,有趣的事实:这个项目是基于 mkyong 的教程。

标签: java xml spring-mvc jaxb


【解决方案1】:

不确定这是否是您的问题,但由于您正在注释字段(实例变量)而不是属性(get 或 set 方法),因此您需要使用 @XmlAccessorType(XmlAccessType.FIELD) 注释您的类。如果您不这样做,JAXB 将抛出“重复属性”异常,这可能会表现为您所看到的问题。

【讨论】:

  • 当我添加 @XmlAccessorType(XmlAccessType.FIELD) 时,它会使我的所有网页返回 404,包括我的 localhost:8080/Project-home/index.jsp。没有注释可以让我的网站运行。
  • @sparks - 尝试将注释移动到 get 方法。
  • 完成,服务器工作,但一旦我将@XmlElement 移动到吸气剂(有@XmlAccessorType 和没有),仍然得到 406。不过感谢您的澄清,我不确定这些注释的正确安排是什么,不同的示例和教程将它们放在不同的位置。
  • @sparks - 这是我写的关于访问类型的博客文章的链接:blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html
  • 哦哇...今天早些时候,谷歌搜索将我带到了那个确切的博客条目。我知道你的名字听起来很熟悉。我对你为什么在字段和吸气剂上都加上注释感到困惑:我知道这是出于对像我这样的人的教育原因,但你没有一个应该如何做的例子(@XmlAccessorType并注释字段或仅注释方法)。老实说让我有点困惑。但是您在这里的回答澄清了这一点。
【解决方案2】:

我发现了我的问题。我正在使用&lt;mvc:annotation-driven/&gt; 但是,我用于 mvc 的架构不正确。

xmlns:mvc="http://www.springframework.org/schema/tx"

不是正确的架构。一旦我将其更改为正确的,一切正常。正确的架构:

xmlns:mvc="http://www.springframework.org/schema/mvc"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-17
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多