我的webservice类如下:
package com.siemens.rest;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.BindingType;
import javax.xml.ws.Provider;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.http.HTTPBinding;
import javax.xml.ws.http.HTTPException;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
@WebServiceProvider
@BindingType(value = HTTPBinding.HTTP_BINDING)
public class ConverterService implements Provider<Source> {
/**
*
*/
private static final long serialVersionUID = 1L;
@Resource
protected WebServiceContext wsContext;
private BigDecimal rupeeRate = new BigDecimal("40.58");
private BigDecimal euroRate = new BigDecimal("0.018368");
public Source invoke(Source source) {
try {
String amount = null;
if (source == null) {
System.out.println("Getting input from query string");
MessageContext mc = wsContext.getMessageContext();
String query = (String) mc.get(MessageContext.QUERY_STRING);
System.out.println("Query String = " + query);
ServletRequest req = (ServletRequest) mc
.get(MessageContext.SERVLET_REQUEST);
amount = req.getParameter("amount");
} else {
System.out.println("Getting input from input message");
Node n = null;
if (source instanceof DOMSource) {
n = ((DOMSource) source).getNode();
} else if (source instanceof StreamSource) {
StreamSource streamSource = (StreamSource) source;
DocumentBuilderFactory dbf = DocumentBuilderFactory
.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource inputSource = null;
if (streamSource.getInputStream() != null) {
inputSource = new InputSource(
streamSource.getInputStream());
} else if (streamSource.getReader() != null) {
inputSource = new InputSource(streamSource.getReader());
}
n = db.parse(inputSource);
} else {
throw new RuntimeException("Unsupported source: " + source);
}
NodeList children = n.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeName().equals("dollars")) {
amount = child.getAttributes().getNamedItem("amount")
.getNodeValue();
break;
}
}
}
BigDecimal dollars = new BigDecimal(amount);
BigDecimal rupees = dollarToRupees(dollars);
BigDecimal euros = rupeesToEuro(rupees);
return createResultSource(rupees, euros);
} catch (Exception e) {
e.printStackTrace();
throw new HTTPException(500);
}
}
public BigDecimal dollarToRupees(BigDecimal dollars) {
BigDecimal result = dollars.multiply(rupeeRate);
return result.setScale(2, BigDecimal.ROUND_UP);
}
public BigDecimal rupeesToEuro(BigDecimal rupees) {
BigDecimal result = rupees.multiply(euroRate);
return result.setScale(2, BigDecimal.ROUND_UP);
}
private Source createResultSource(BigDecimal rupees, BigDecimal euros) {
String body = "<ns:return xmlns:ns=\"http://rest.jaxws.samples.geronimo.apache.org\">"
+ "<ns:dollarToRupeesResponse>"
+ rupees
+ "</ns:dollarToRupeesResponse><ns:rupeesToEurosResponse>"
+ euros + "</ns:rupeesToEurosResponse></ns:return>";
Source source = new StreamSource(new ByteArrayInputStream(
body.getBytes()));
return source;
}
}
和web.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>jaxws-rest-converter</display-name>
<servlet>
<servlet-name>ConverterService</servlet-name>
<servlet-class> com.siemens.rest.ConverterService </servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ConverterService</servlet-name>
<url-pattern>/converter</url-pattern>
</servlet-mapping>
</web-app>
在tomcat 6.0中部署它时,我得到以下异常:
严重:Servlet / jaxws-rest-converter引发了load()异常 java.lang.ClassCastException:com.siemens.rest.ConverterService不能 被转换为javax.servlet.Servlet at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1116) 在 org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:993) 在 org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4420) 在 org.apache.catalina.core.StandardContext.start(StandardContext.java:4733) 在 org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053) 在org.apache.catalina.core.StandardHost.start(StandardHost.java:840) 在 org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053) 在 org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463) 在 org.apache.catalina.core.StandardService.start(StandardService.java:525) 在 org.apache.catalina.core.StandardServer.start(StandardServer.java:754) 在org.apache.catalina.startup.Catalina.start(Catalina.java:595)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(未知来源)at sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源)at java.lang.reflect.Method.invoke(未知来源)at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)at at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
我认为web.xml
是错误的,任何人都可以帮助我。我试图在CXF
中实现restful webservices。
答案 0 :(得分:0)
我认为您的实施中存在一些问题。
首先,你的web.xml
确实是错误的。此文件用于声明servlet,过滤器等,但从不声明webservices提供程序。您收到ClassCastException
,因为您告诉您ConverterService
是一个servlet。
因此,您需要做的是在web.xml中声明Apache CXF servlet,让他回答一些请求。检查此示例:
<!--
Web service Front Controller. It will receive all the web service request and then it
delegates the request to the web services configured in the CXF config file
-->
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!--
Every request that start with this will be handled by the CXF servlet
-->
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/ctx/authbasic/ws/*</url-pattern>
</servlet-mapping>
在此之后,您需要正确声明每个Web服务。我使用Spring来配置我的Apache CXF服务,所以在这里你可以查看一个例子。
<jaxws:endpoint id="dataService"
implementor="some.package.DataSIB"
address="/DataService" wsdlLocation="classpath:wsdls/DataService.wsdl">
<jaxws:properties>
<!-- jaxws properties binding config -->
</jaxws:properties>
<jaxws:dataBinding>
<!-- data binding config -->
</jaxws:dataBinding>
</jaxws:endpoint>
使用此配置,您对/ctx/authbasic/ws/DataService
的任何请求都将由Web服务实现处理。这里是Web服务声明(SEI)及其实现(SIB)的示例:
@WebService(name = "dataService", targetNamespace = "http://some-domain/dataservice/definition")
@SOAPBinding(style = Style.DOCUMENT, use = Use.LITERAL, parameterStyle = ParameterStyle.WRAPPED)
public interface DataSEI {
// You methods here
}
@WebService(endpointInterface = "some.package.DataSEI",
serviceName = "dataServiceService",
portName = "dataServicePort",
targetNamespace = "http://some-domain/dataservice/definition")
public class DataSIB implements DataSEI {
// Your methods here
}
注意:这是SOAP Web服务的示例,但这可能有助于您理解框架