java - 使用 spring mvc 在 web 服务中公开 bean 时出现异常

标签 java spring spring-mvc

我正在使用 Spring 3.0.5.Release MVC 来公开 Web 服务,下面是我的 servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
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">

<!-- To enable @RequestMapping process on type level and method level -->
<context:component-scan base-package="com.pyramid.qls.progressReporter.service" />

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
  <property name="messageConverters">
    <list>
      <ref bean="marshallingConverter" />
      <ref bean="atomConverter"  />
      <ref bean="jsonConverter" />
    </list>
  </property>
</bean>

<bean id="marshallingConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
  <constructor-arg ref="jaxbMarshaller" />
  <property name="supportedMediaTypes" value="application/xml"/>
</bean>

<bean id="atomConverter" class="org.springframework.http.converter.feed.AtomFeedHttpMessageConverter">
  <property name="supportedMediaTypes" value="application/atom+xml" />
</bean>

<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
  <property name="supportedMediaTypes" value="application/json" />
</bean>

<!-- Client -->
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
  <property name="messageConverters">
    <list>
      <ref bean="marshallingConverter" />
      <ref bean="atomConverter"  />
      <ref bean="jsonConverter" />
    </list>
  </property>
</bean>

<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
  <property name="classesToBeBound">
    <list>
      <value>com.pyramid.qls.progressReporter.impl.BatchProgressMetricsImpl</value>
      <value>com.pyramid.qls.progressReporter.datatype.InstrumentStats</value>
      <value>com.pyramid.qls.progressReporter.datatype.InstrumentInfo</value>
      <value>com.pyramid.qls.progressReporter.datatype.BatchProgressMetricsList</value>
      <value>com.pyramid.qls.progressReporter.datatype.LoadOnConsumer</value>
      <value>com.pyramid.qls.progressReporter.datatype.HighLevelTaskStats</value>
      <value>com.pyramid.qls.progressReporter.datatype.SessionStats</value>
      <value>com.pyramid.qls.progressReporter.datatype.TaskStats</value>
      <value>com.pyramid.qls.progressReporter.datatype.ComputeStats</value>
      <value>com.pyramid.qls.progressReporter.datatype.DetailedInstrumentStats</value>
      <value>com.pyramid.qls.progressReporter.datatype.ImntHistoricalStats</value>
    </list>
  </property>
</bean>

<bean id="QPRXmlView" class="org.springframework.web.servlet.view.xml.MarshallingView">
  <constructor-arg ref="jaxbMarshaller" />
</bean>

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

<bean id="QPRController" class="com.pyramid.qls.progressReporter.service.QPRController">
  <property name="jaxb2Mashaller" ref="jaxbMarshaller" />
</bean>

</beans>  

以下是我在 Controller (QPRController)中所做的事情

@RequestMapping(value = "/clientMetrics/{clientId}", method = RequestMethod.GET)
public ModelAndView getBatchProgressMetrics(@PathVariable String clientId) {
  List<BatchProgressMetrics> batchProgressMetricsList = null;

  batchProgressMetricsList = batchProgressReporter.getBatchProgressMetricsForClient(clientId);
  BatchProgressMetricsList batchList = new BatchProgressMetricsList(batchProgressMetricsList);
  ModelAndView mav = new ModelAndView("QPRXmlView", BindingResult.MODEL_KEY_PREFIX + "batchProgressMetrics", batchList);
  return mav;
}  

这就是我的batchprogressmetricsList 的样子:

@XmlRootElement(name = "batchProgressMetrics")
public class BatchProgressMetricsList implements Serializable{

    private int count;
    private List<BatchProgressMetrics> batchProgressMetricsList;

    public BatchProgressMetricsList() {
    }

    public BatchProgressMetricsList(List<BatchProgressMetrics> batchProgressMetricsList) {
        this.batchProgressMetricsList = batchProgressMetricsList;
        this.count = batchProgressMetricsList.size();
    }

    public int getCount() {
        return count;
    }

    @XmlElement(name = "batchProgressMetrics1")
    public List<BatchProgressMetrics> getBatchProgressMetrics() {
        return batchProgressMetricsList;
    } 

现在我得到以下信息:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'QPRController' defined in ServletContext resource [/WEB-INF/rest-servlet.xml]: Cannot resolve reference to bean 'jaxbMarshaller' while setting bean property 'jaxb2Mashaller'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jaxbMarshaller' defined in ServletContext resource [/WEB-INF/rest-servlet.xml]: Invocation of init method failed; nested exception is org.springframework.oxm.UncategorizedMappingException: Unknown JAXB exception; nested exception is com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
com.pyramid.qls.progressReporter.iface.BatchProgressMetrics is an interface, and JAXB can't handle interfaces.
this problem is related to the following location:
    at com.pyramid.qls.progressReporter.iface.BatchProgressMetrics
    at public java.util.List com.pyramid.qls.progressReporter.datatype.BatchProgressMetricsList.getBatchProgressMetrics()
    at com.pyramid.qls.progressReporter.datatype.BatchProgressMetricsList
com.pyramid.qls.progressReporter.iface.BatchProgressMetrics does not have a no-arg default constructor.
this problem is related to the following location:
    at com.pyramid.qls.progressReporter.iface.BatchProgressMetrics
    at public java.util.List com.pyramid.qls.progressReporter.datatype.BatchProgressMetricsList.getBatchProgressMetrics()
    at com.pyramid.qls.progressReporter.datatype.BatchProgressMetricsList

        org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)  

以前我在没有更改的情况下得到了这个。

SEVERE: Servlet.service() for servlet rest threw exception
javax.servlet.ServletException: Unable to locate object to be marshalled in model: {org.springframework.validation.BindingResult.batchProgressMetrics=  

请注意,BatchProgressMetrics 是一个接口(interface),因此我的 MAV 返回 BatchProgressMetrics 对象列表,并且我在要绑定(bind)到 servlet.xml 的类中拥有其 impl 的条目。

你能帮我看看我做错了什么吗?是的,如果我只在 MAV 中发送 batchProgressMetricsList.get(0) ,它就可以正常工作。

最佳答案

这是因为 JAXB 上下文不知道如何处理对象列表,只知道如何处理对象本身。仔细想想,这是有道理的 - 在 XML 中表示列表的唯一方法是将其包装在容器元素中,并且它没有关于如何执行此操作的信息。

因此,您需要定义一个类,它是 BatchProgressMetrics 列表的容器,并将其返回到模型中。

关于java - 使用 spring mvc 在 web 服务中公开 bean 时出现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4699144/

相关文章:

java - 读取 java 中的二进制文件直到特定的 "%%EOF"标记?

java - 如何从响应json中获取用户的id

java - 为什么 Spring Security 使用默认的预认证检查?

java - Spring mvc 异常中的 servlet 名称为空

Java - Spring 注入(inject)正则表达式 - 非法字符 - & 符号

java - 如何打开一个 Activity 两次但内容不同?

java - 在单个 jframe 上交换两个不同的分割面板

java - Rest Service方法映射【Java Spring】

spring - Spring WebFlux中如何通过handler方法拦截请求

java - 在 spring mvc 应用程序中存储用户上传的位置?