我是一個新手,他有一個比較好的開始,直到我決定玩一些複雜的對象。我碰到的問題是關於解組到服務器的對象(在服務器端從XML創建對象)。CXF Restful服務複合對象解組不起作用
以下是我的示例(代表性)服務實現。
這是我的「複雜對象」數據類型。
package data;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class ComplexType {
private long id;
private String name;
private Boolean isRegistered;
public ComplexType() {
super();
}
public ComplexType(long id, String name, Boolean isRegistered) {
super();
this.id = id;
this.name = name;
this.isRegistered = isRegistered;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getIsRegistered() {
return isRegistered;
}
public void setIsRegistered(Boolean isRegistered) {
this.isRegistered = isRegistered;
}
}
這是我的服務API
package api;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import data.ComplexType;
public interface Service {
@GET
@Path("/nummembers")
int getNumElements();
@GET
@Path("/member/{id}")
ComplexType getMember(@PathParam("id") long id);
@POST
@Path("/member")
boolean addMember(@FormParam("member") ComplexType member);
}
這是服務的實現:
package impl;
import java.util.HashMap;
import java.util.Map;
import data.ComplexType;
import api.Service;
public class ServiceImpl implements Service {
Map<Long, ComplexType> data;
public ServiceImpl() {
System.out.println("TestApp Starting");
data = new HashMap<Long, ComplexType>();
}
@Override
public int getNumElements() {
return data.size();
}
@Override
public ComplexType getMember(long id) {
if (data.containsKey(id)) {
return data.get(id);
}
ComplexType ct =
new ComplexType(id, "NAME" + new Long(id).toString(), (id % 2 == 1));
data.put(id, ct);
return ct;
}
@Override
public boolean addMember(ComplexType member) {
int preSize = data.size();
data.put(member.getId(), member);
return preSize < data.size(); // True if added
}
}
所以,當我打電話getNumElements()
是沒有問題的。當我打電話給getMember(long id)
時,我得到一個序列化的「ComplexType」就好了。當我序列化複雜類型,並把它作爲FormParam到addMember(ComplexType member)
,我總是Parameter Class data.ComplexType has no constructor with single String parameter, static valueOf(String) or fromString(String) methods
我試圖爲我定製的供應商,通過編寫以下類:
package impl;
import javax.ws.rs.ext.ContextResolver;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import data.ComplexType;
public class JaxbXmlContextResolver implements ContextResolver<Object> {
private static final Class<?>[] classes = new Class[] {ComplexType.class};
private static final JAXBContext context = initContext();
public static JAXBContext initContext() {
JAXBContext context = null;
try {
context = JAXBContext.newInstance(classes);
} catch (JAXBException e) {
throw new RuntimeException(e);
}
return context;
}
@Override
public Object getContext(Class<?> arg0) {
return context;
}
}
而對於配置的其餘部分,這裏是我的web.xml:
<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>TestApp</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:cxf.xml</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
而且cxf.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:util="http://www.springframework.org/schema/util"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.0.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="myservice" class="impl.ServiceImpl" />
<bean id="jaxbXmlProvider" class="impl.JaxbXmlContextResolver" />
<jaxrs:server id="connectionService" address="/" >
<jaxrs:serviceBeans>
<ref bean="myservice" />
</jaxrs:serviceBeans>
<jaxrs:extensionMappings>
<entry key="xml" value="application/xml" />
</jaxrs:extensionMappings>
<jaxrs:providers>
<ref bean="jaxbXmlProvider" />
</jaxrs:providers>
</jaxrs:server>
</beans>
爲了完整起見,這裏是我用來構建應用程序的pom.xml。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<modelVersion>4.0.0</modelVersion>
<groupId>TESTAPP</groupId>
<artifactId>testApp</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<name>Test Application</name>
<url>http://www.mycompany.com</url>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>2.4.1</version>
<exclusions>
<exclusion>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>net.sf.kxml</groupId>
<artifactId>kxml2</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
任何幫助(溶液,指針,或任何種類的方向),將不勝感激。
哦,我正在使用cxf 2.4.1和Spring 3.0.5.RELEASE。這是我部署的應用程序的精確副本。
謝謝。
據:http://cxf.547215.n5.nabble.com/MessageBodyReader-not-picked-up-td564496.html標記爲@FormParam的參數不由消息閱讀器處理,並且需要特定的ParameterHandler。所以,我寫了一個自定義處理程序,它運行良好。令我困擾的是,我必須爲每個obj編寫一個處理程序,我希望能夠通過一種形式接收它。如果有解決方案,我將不勝感激。另外,我的擔心之一是,我想在我的服務中支持xml和json。我不知道如何爲相同的obj編寫兩個處理程序,或者是否應該編寫處理程序來處理這兩種格式。 –