CXF生成webservice服务端,httpclient客户端调用webservice服务端



本博客分为
1.CXF编写webservice 服务端代码
2.HttpClient调用webservice代码
3.客户端调用服务端遇到的问题及解决方案


*********************************************
一.CXF编写webservice 服务端代码
我的项目spring是3.1.4版本建议使用cxf-core-3.0.12版本


在项目为spring3.1.4的框架中使用cxf的步骤
如果没有相关jar包请在apache官网上下载"cxf 3.0.12"版本解压后copy以下jar包到项目中
导入必须jar包(导入前先确保项目是正常运行的)
cxf-core-3.0.12.jar
cxf-rt-bindings-soap-3.0.12.jar
cxf-rt-databinding-jaxb-3.0.12.jar
cxf-rt-frontend-jaxws-3.0.12.jar
cxf-rt-frontend-simple-3.0.12.jar
cxf-rt-transports-http-3.0.12.jar
cxf-rt-transports-udp-3.0.12.jar
cxf-rt-ws-addr-3.0.12.jar
cxf-rt-ws-policy-3.0.12.jar
cxf-rt-wsdl-3.0.12.jar
cxf-services-sts-core-3.0.12.jar
geronimo-jaxws_2.2_spec-1.2.jar
geronimo-servlet_3.0_spec-1.0.jar
neethi-3.0.3.jar
stax2-api-3.1.4.jar
woodstox-core-asl-4.4.1.jar
wsdl4j-1.6.3.jar
xmlschema-core-2.2.1.jar
导入后请启动项目确保没有jar包冲突
(也许还需要其他包依赖,我的项目就导入了这些,故不知其他的依赖包的信息)
------------------------------------------------------
一、配置文件
1.配置web.xml加入以下配置


<servlet>  
        <servlet-name>CXFServlet</servlet-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>/webservice/*</url-pattern>  
    </servlet-mapping>  
    
-------------------------------------------------------


开始编写代码
1.新建接口
package com.xxxx.xx.xxxx.webservice.server;




import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface UserService {
public String getUserName(@WebParam(name="name22") String name);
public String getUserName2();
}


---------------------------------------------------




2.新建接口实现类
package com.xxxx.xx.xxxx.webservice.server.impl;




import javax.jws.WebService;
import com.xxxx.xx.xxxx.webservice.server.UserService;


public class UserServiceImpl implements UserService {




public String getUserName2() {
System.out.println("返回成功!");
return "123456";
}


@Override
public String getUserName(String name) {
System.out.println("param"+name);
return createXml(name);
}
/**
* 根据传递的字符串生成对应的xml。

* @param 传递过来的参数name
* @return 返回xml的字符串
*/
public String createXml(String name) {


StringBuffer sb = new StringBuffer();
sb.append("<?xml version='1.0' encoding='UTF-8'?>");
sb.append("<Result>");
sb.append("<Name>小小鸟</cinamaName>");
sb.append("<director>" + name + "</director>");
sb.append("<introduce>好的系统,不错!!!</introduce>");
sb.append("<price>25</price>");
sb.append("</Result>");
return sb.toString();
}
}


------------------------------------------------






2.新建applicationContext-CXFServer.xml
复制一份之前的spring配置文件修改其名字为applicationContext-CXFServer.xml,
在其基础上进行更改。
加入
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jaxws="http://cxf.apache.org/jaxws"  



http://cxf.apache.org/jaxws   
   http://cxf.apache.org/schemas/jaxws.xsd




以下为cxf配置内容
 <bean id="userServiceImpl" class="com.xxxx.xx.xxxx.webservice.server.impl.UserServiceImpl" />
 <!-- 2:通过jaxws:server方式来配置webservice -->
 <jaxws:server serviceClass="com.xxxx.xx.xxxx.webservice.server.UserService"
        address="/User">
        <jaxws:serviceBean>
            <ref bean="userServiceImpl" />
        </jaxws:serviceBean>
    </jaxws:server> 
    
--------------------------------------------------------------------
配置完后,启动项目。(带有xx的请替换为您的真实路径)
启动成功后在浏览器中访问:  http://10.191.40.214:8080/systemName/webservice/User?wsdl 
如果有许多信息显示,那说明服务端代码已经好了!!!




*********************************************************************************************


二.客户端 httpClient方式调用CXF框架 webService
第一种
public class TestHttp {      
    public static void main(String[] args)   {  
        DefaultHttpClient httpClient = null;  
        try {  
            httpClient = new DefaultHttpClient();  
            HttpPost httppost = new HttpPost("http://10.191.40.214:8080/systemName/webservice/User"); //webservice服务地址  
            String soapRequestData = getRequestXml(); //soap协议的格式,定义了方法和参数  
            HttpEntity re = new StringEntity(soapRequestData,HTTP.UTF_8);  
          //必须加上这段,否则报空指针异常
            httppost.setHeader("Content-Type","application/soap+xml; charset=utf-8");    
            httppost.setEntity(re);   
            HttpResponse response = httpClient.execute(httppost); //调用接口                  
            //返回是否成功的状态  
            System.out.println(response.getStatusLine().getStatusCode());  
            if(response.getStatusLine().getStatusCode() == 200) {              
                //获得输出的字符串  
                String xmlString = EntityUtils.toString(response.getEntity());  
                System.out.println(xmlString);            
            }  
              
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            httpClient.getConnectionManager().shutdown(); //关闭连接  
        }  
          
    }  
      
    /** 
     * 获得请求XML 
     * @return 
     */  
    private static String getRequestXml(){  
        StringBuilder sb = new StringBuilder();  
        sb.append("<?xml version=\"1.0\"?>");  
        sb.append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");  
        sb.append(" xmlns:sam=\"http://server.webservice.xxxx.xx.xxxx.com/\" ");//要特别注意结尾必须带有"/",这一串由服务端提供  
        sb.append(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"");  
        sb.append(" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"); // 要特别注意结尾必须带有"/"
        sb.append("<soap:Header/>");  
        sb.append("<soap:Body>");  
        sb.append("<sam:getUserName2>");  //“getUserName"调用方法名  
        sb.append("<name22>老A</name22>"); //传参  name22为接口上定义的名称
        sb.append("</sam:getUserName2>");  
        sb.append("</soap:Body>");  
        sb.append("</soap:Envelope>");  
          
        return sb.toString();  
    }  
}




//
第二种方式
public class UserClient {
public static void main(String[] args) {
httpClientPost();
}
private static void httpClientPost(){
HttpClient client=new DefaultHttpClient();
HttpPost httpPost=new HttpPost("http://10.191.40.214:8080/systemName/webservice/User");
try {
ContentProducer cP=new ContentProducer(){
@Override
public void writeTo(OutputStream out) throws IOException {
Writer writer=new OutputStreamWriter(out,"UTF-8");
//获取请求xml数据
String requestXml=getRequestXmlTest();
writer.write(requestXml);
writer.flush();
}
};
//必须加上这段,否则报空指针异常
httpPost.setHeader("Content-Type","application/soap+xml; charset=utf-8");    
httpPost.setEntity(new EntityTemplate(cP));

HttpResponse  response=client.execute(httpPost);
//输出响应xml
System.out.println(EntityUtils.toString(response.getEntity()));
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}
 private static String getRequestXmlTest(){  
       StringBuilder sb = new StringBuilder();  
       sb.append("<?xml version=\"1.0\"?>");  
       sb.append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");  
       sb.append(" xmlns:sam=\"http://server.webservice.xxxx.xx.xxxx.com/\" "); //要特别注意结尾必须带有"/",这一串由服务端提供  
       sb.append(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"");  
       sb.append(" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">");  //要特别注意结尾必须带有"/"
       sb.append("<soap:Header/>");  
       sb.append("<soap:Body>");  
       sb.append("<sam:getUserName>");  //“getUserName”调用方法名  
    sb.append("<name22>老A</name22>"); //name22接口中定义的参数名
       sb.append("</sam:getUserName>");  
       sb.append("</soap:Body>");  
       sb.append("</soap:Envelope>");  
         
       return sb.toString();  
   }  
}


************************************************************************
三.客户端调用服务端遇到的问题总结


6.服务端报错
org.apache.cxf.binding.soap.SoapFault: A SOAP 1.2 message is not valid when sent to a SOAP 1.1 only endpoint.
at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:179)
at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:69)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
org.apache.cxf.binding.soap.SoapFault: "http://www.w3.org/2003/05/soap-envelope/", the namespace on the "Envelope" element, is not a valid SOAP version.
at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.readVersion(ReadHeadersInterceptor.java:131)
at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:174)
at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:69)


解决方案:




//StringBuilder sb = new StringBuilder();
sb.append("<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope/\"");
        改为
        sb.append("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"");
















5.服务端异常
org.apache.cxf.interceptor.Fault: Unmarshalling Error: unexpected element (uri:"http://server.webservice.cpic.naiu.cpic.com/", local:"name22"). Expected elements are <{}name22> 
at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:909)
at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:712)
at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:179)


                sb.append("<soap:Body>");
sb.append("<sam:getUserName>");
sb.append("<sam:name22>小吧</sam:name22>");
sb.append("</sam:getUserName>");
sb.append("</soap:Body>");


sb.append("<sam:name22>小吧</sam:name22>");改为sb.append("<name22>小吧<name22>");








4.服务器端异常
Caused by: javax.xml.bind.UnmarshalException
 - with linked exception:
[javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"name22"). Expected elements are (none)]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(Unknown Source)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(Unknown Source)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(Unknown Source)
at org.apache.cxf.jaxb.JAXBEncoderDecoder.doUnmarshal(JAXBEncoderDecoder.java:858)


解决方案:               sb.append("<soap:Body>");
sb.append("<sam:getUserName>");
sb.append("<name22>小吧<name22>");
sb.append("</sam:getUserName>");
sb.append("</soap:Body>");


sb.append("<name22>小吧<name22>"); 改为sb.append("<name22>小吧</name22>"); 










3.
客户端:<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Client</faultcode><faultstring>Error reading XMLStreamReader: Unexpected character 'x' (code 120) excepted space, or '>' or "/>"&#xd;
 at [row,col {unknown-source}]: [1,70]</faultstring></soap:Fault></soap:Body></soap:Envelope>
服务端:org.apache.cxf.binding.soap.SoapFault: Error reading XMLStreamReader: Unexpected character 'x' (code 120) excepted space, or '>' or "/>"
 at [row,col {unknown-source}]: [1,70]
at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:288)
at org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:69)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
解决方案:查看客户端拼接 ququestxml中 xmlns或其他标签 是否有空格  正常情况下两个标签是需要空格隔开的。














2.httpclient访问 cxf   webservice 空指针异常
客户端:<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>Fault occurred while processing.</faultstring></soap:Fault></soap:Body></soap:Envelope>
服务端:java.lang.NullPointerException
at org.apache.cxf.binding.soap.interceptor.StartBodyInterceptor.handleMessage(StartBodyInterceptor.java:59)
at org.apache.cxf.binding.soap.interceptor.StartBodyInterceptor.handleMessage(StartBodyInterceptor.java:37)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
解决方案:
HttpPost httpPost=new HttpPost("http://10.x.x:8080/xx/webservice/User");
在客户端设置httpPost.setHeader("Content-Type","application/soap+xml; charset=utf-8"); 解决了空指针异常   










1.客户端httpclient调用 cxf webservice访问不到服务器端代码
客户端 :Interceptor for {http://server.webservice.cpic.naiu.cpic.com/}UserServiceService#{http://server.webservice.cpic.naiu.cpic.com/}getUserName2 has thrown exception, unwinding now
服务端:org.apache.cxf.interceptor.Fault: Unexpected wrapper element {http://server.webservice.cpic.naiu.cpic.com}getUserName2 found.   Expected {http://server.webservice.cpic.naiu.cpic.com/}getUserName2.
at org.apache.cxf.wsdl.interceptors.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:107)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:252)


解决方案:       StringBuilder sb = new StringBuilder();
1.sb.append("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope\"");
2.sb.append(" xmlns:sam=\"http://server.webservice.cpic.naiu.cpic.com\">");
3.sb.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");//new
4.sb.append(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" ");//new


第一行和第二行必须已 /结尾
1.sb.append("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope\"");
2.sb.append(" xmlns:sam=\"http://server.webservice.cpic.naiu.cpic.com\">");
必须改为
1.sb.append("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"");
2.sb.append(" xmlns:sam=\"http://server.webservice.cpic.naiu.cpic.com/\">");











  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值