我正在使用Spring 3.0.5。发布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>
以下是我在控制器(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是一个接口,因此我的MAV返回BatchProgressMetrics
个对象的列表,并且我在servlet.xml
中绑定了类中的impl的条目。
你能帮我解决一下我做错了什么。是的,如果我只在MAV中发送batchProgressMetricsList.get(0)
它就可以了。
答案 0 :(得分:1)
这是因为JAXB上下文不知道如何处理对象列表,只知道对象本身。当你想到它时有意义 - 在XML中表示列表的唯一方法是将它包装在容器元素中,并且它没有关于如何做到这一点的信息。
所以你需要定义一个类,它是BatchProgressMetrics
列表的容器,而是在模型中返回它。