मैं आराम से सेवाओं में नया हूं, और अपेक्षाकृत अच्छी शुरुआत हुई, जब तक कि मैंने कुछ जटिल वस्तुओं के साथ खेलने का फैसला नहीं किया। जिस समस्या को मैं मार रहा हूं वह सर्वर पर आने वाली ऑब्जेक्ट को अनमर्शलिंग करने के बारे में है (सर्वर पक्ष पर एक्सएमएल से ऑब्जेक्ट बनाना)।सीएक्सएफ आराम से सेवा जटिल वस्तु unmarshalling काम नहीं करता
नीचे मेरा नमूना (प्रतिनिधि) सेवा का कार्यान्वयन है।
यहां मेरा "जटिल ऑब्जेक्ट" डेटा प्रकार है।
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;
}
}
यह मेरी सेवा एपीआई
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)
पर कॉल करता हूं तो मुझे एक सीरियलाइज्ड "कॉम्प्लेक्स टाइप" ठीक लगता है। मैं एक जटिल प्रकार क्रमानुसार और addMember(ComplexType member)
को FormParam के रूप में इसे पारित करते हैं, तो मैं हमेशा मिलता 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;
}
}
और विन्यास के बाकी के लिए
<?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>
, यहाँ मेरी web.xml है
और पूर्णता के लिए, यहां 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>
कोई भी मदद (समाधान, पॉइंटर्स, या किसी भी प्रकार की दिशा) की सराहना की जाएगी।
ओह, मैं सीएक्सएफ 2.4.1 और स्प्रिंग 3.0.5.RELEASE का उपयोग कर रहा हूं। यह मेरे तैनात आवेदन की सटीक प्रति है।
धन्यवाद।
के अनुसार: http://cxf.547215.n5.nabble.com/MessageBodyReader-not-picked-up-td564496.html @FormParam चिह्नित पैराम संदेश पाठकों द्वारा संभाला नहीं जाता है, और एक विशिष्ट पैरामीटर हैंडलर की आवश्यकता होती है। तो, मैंने एक कस्टम हैंडलर लिखा, और यह ठीक काम किया। यह मुझे परेशान करता है कि मुझे प्रत्येक ओबीजे के लिए एक हैंडलर लिखना है जिसे मैं एक रूप में प्राप्त करने की उम्मीद करता हूं। यदि कोई समाधान है, तो मैं इसकी सराहना करता हूं। इसके अलावा, मेरी चिंताओं में से एक यह है कि, मैं अपनी सेवा में एक्सएमएल और जेसन दोनों का समर्थन करना चाहता हूं। मुझे यकीन नहीं है कि मैं एक ही ओबीजे के लिए दो हैंडलर कैसे लिख सकता हूं, या क्या मुझे दोनों प्रारूपों को संभालने के लिए अपना हैंडलर लिखना चाहिए। –