CXF Restful服务复杂对象解组不起作用

Vir*_*eal 6 java cxf jaxb

我是宁静的服务新手,并且有一个相对良好的开端,直到我决定玩一些复杂的对象.我遇到的问题是解组一个到服务器的对象(在服务器端从XML创建对象).

以下是我的服务示例(代表)实现.

这是我的"复杂对象"数据类型.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的服务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);
}
Run Code Online (Sandbox Code Playgroud)

这是服务的实现:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,当我打电话时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;
    }
}
Run Code Online (Sandbox Code Playgroud)

对于其余配置,这是我的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>
Run Code Online (Sandbox Code Playgroud)

它引用的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>
Run Code Online (Sandbox Code Playgroud)

为了完整起见,这里是我用来构建应用程序的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>
Run Code Online (Sandbox Code Playgroud)

任何帮助(解决方案,指针或任何方向)将不胜感激.

哦,我使用的是cxf 2.4.1和Spring 3.0.5.RELEASE.这是我部署的应用程序的精确副本.

谢谢.

小智 0

为三个属性中的每一个实现一个不带参数的默认构造函数和一个带有参数的默认构造函数。这应该会让 JAXB 高兴。