首页 > 编程知识 正文

java调用webservice接口 三种方法,webservice接口开发简单例子

时间:2023-05-04 05:43:48 阅读:197665 作者:2310

转自:https://thewangzl.iteye.com/blog/2326075

尊敬的铅笔:使用JaxWsDynamicClientFactory调用WebService public static Object call(String wsdl,String method,String requestStr){ JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance(); Client client = factory.createClient(wsdl); HTTPConduit conduit = (HTTPConduit) client.getConduit(); HTTPClientPolicy policy = new HTTPClientPolicy(); long timeout = 10 * 60 * 1000;// policy.setConnectionTimeout(timeout); policy.setReceiveTimeout(timeout); conduit.setClient(policy); //动态invoke方法 Object[] os =client.invoke(method,requestStr); return os[0]; } 方法二:使用JaxWsProxyFactoryBean调用WebService

原理:使用JaxWsProxyFactoryBean类生成本地的代理类。
首先创建接口,然后通过JaxWsProxyFactoryBean调用。

@WebService public interface IDataService { @WebMethod @WebResult String getData(@WebParam String requestData); } public static String call(String wsdl, String requestStr) { JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.setServiceClass(IDataService.class); factory.setAddress(wsdl); IDataService service = (IDataService) factory.create(); // 设置超时时间 org.apache.cxf.endpoint.Client proxy = ClientProxy.getClient(service); HTTPConduit conduit = (HTTPConduit) proxy.getConduit(); HTTPClientPolicy policy = new HTTPClientPolicy(); long timeout = 10 * 60 * 1000;// policy.setConnectionTimeout(timeout); policy.setReceiveTimeout(timeout); conduit.setClient(policy); // 发出请求 return service.getData(requestStr); } 方法三:使用wsimport命令构建WebService客户端

首先使用wsimport命令构建客户端,然后用下面的方法调用。

public static String call(String requestData) { // 构建的客户端代码 IDataService_Service factory = new IDataService_Service(); IDataService service = factory.getDataSharedWebService(); long timeout = 30 * 60 * 1000;// 30分钟 // 设置超时时间 // 当前起作用的配置 ((BindingProvider) service).getRequestContext().put("javax.xml.ws.client.connectionTimeout", timeout); ((BindingProvider) service).getRequestContext().put("javax.xml.ws.client.receiveTimeout", timeout); // 网上搜到的其他设置超时的方法,当前项目没有起作用 ((BindingProvider) service).getRequestContext().put("com.sun.xml.ws.connect.timeout", timeout); ((BindingProvider) service).getRequestContext().put("com.sun.xml.ws.request.timeout", timeout); ((BindingProvider) service).getRequestContext().put("com.sun.xml.internal.ws.connect.timeout", timeout); ((BindingProvider) service).getRequestContext().put("com.sun.xml.internal.ws.request.timeout", timeout); ((BindingProvider) service).getRequestContext().put("sun.net.client.defaultConnectTimeout", timeout); ((BindingProvider) service).getRequestContext().put("sun.net.client.defaultReadTimeout", timeout); try { // 调用WebService return service.getData(requestData); } catch (Exception e) { log.error(e.getMessage()); } return null; }

也可以用cxf的wsdl2java命令构建客户端,调用方式一样,但是如何设置超时时间没有试。

笑点低的草莓:使用HttpClient调用WebService

使用commons-httpclient-3.1,依赖jar包(commons-codec.jar、commons-logging.jar)。

public String call(String wsdl, String requestData) { try { // requestData可以直接用soapui中请求的数据,注意<![CDATA[]]>的使用 PostMethod postMethod = new PostMethod(wsdl); byte[] b = requestData.getBytes("UTF-8"); InputStream in = new ByteArrayInputStream(b, 0, b.length); RequestEntity re = new InputStreamRequestEntity(in, "text/xml; charset=utf-8"); postMethod.setRequestEntity(re); // 设置header SOAPAction,不设置的话,会报异常:no SOAPAction // header,但是SOAPAction的好像任意值都可以 String soapAction = "XX"; postMethod.setRequestHeader("SOAPAction", soapAction); HttpClient client = new HttpClient(); // 设置超时(不知道默认是多久,没有设置的时候,也没有报错,设置下保险些) int timeout = 10 * 60 * 1000; client.getHttpConnectionManager().getParams().setConnectionTimeout(timeout); client.getHttpConnectionManager().getParams().setSoTimeout(timeout); // int status = client.executeMethod(postMethod); if (status == 200) {// 成功 InputStream is = postMethod.getResponseBodyAsStream(); /** * 获取的结果可以参考用soapui调用时的返回值, * 如果约定的返回值是XML,并不会像soapui一样把xml用<![CDATA[]]>包含起来,要注意解析的方法, * 不知道soapui如何处理的,暂时没时间研究。 */ return getResponseXML(is); } else { log.error("调用Webservice出错;错误代码为:" + status); } } catch (Exception e) { log.error(e.getMessage()); } return null; } public String getResponseXML(InputStream response) throws Exception { // 根据具体的返回值写的解析 SAXReader reader = new SAXReader(); Document document = reader.read(response); Element root = document.getRootElement(); List<Element> childElements = root.elements(); for (Element child : childElements) { List<Element> datas = child.selectNodes("getOrgInfoResponse/getOrgInfoResponse"); for (Element node : datas) { // 返回约定的xml return node.getText(); } } return null; }

总结下这次遇到的问题:
1.异常:java.lang.NoSuchFieldError: QUALIFIED
jar包冲突,删除jar包(如果可以的话,不能删除就用HttpClient的方式)。由于项目中第三方工具需要XmlSchema-1.3.x.jar,而cxf-2.5作为客户端时需要用到xmlschema-core-2.0.1.jar导致前三种方式都不能用。
2.超时
由于接收数据较大,时间较长,必须设置超时时间。
3.异常:javax.xml.bind.UnmarshalException:unexpected element (uri:"", local:“getDataResponse”).Expected elements are <{http://xxx/xx}getOrgInfoResponse>
是namespace的问题,如果用JaxWsProxyFactoryBean的方式,要修改@WebResult中targetNamespace;如果用wsimport命令的方式,需要修改类GetDataResponse中属性getDataResponse的注解中namespace的值。
4.异常:no SOAPAction header
没有设置SOAPAction,设置方式:postMethod.setRequestHeader(“SOAPAction”, soapAction),soapAction的值是什么好像并不影响结果。

附加:

添加一个webserivice调用的工具类,

import org.apache.cxf.endpoint.Client;import org.apache.cxf.frontend.ClientProxy;import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;import org.apache.cxf.transport.http.HTTPConduit;import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;import org.springframework.stereotype.Component;import java.util.ResourceBundle;@Componentpublic class WebServiceUtil {public static final int CXF_CLIENT_CONNECT_TIMEOUT = 20 * 1000; public static final int CXF_CLIENT_RECEIVE_TIMEOUT = 20 * 1000;/** * * @param clazz 接口客户端类 * @param url接口地址 * @param timeout超时时间 * @return */public <T> T getWebService(Class<T> clazz, String url,Integer...timeout){return getWebServiceByUrl(clazz,url,CXF_CLIENT_RECEIVE_TIMEOUT,CXF_CLIENT_RECEIVE_TIMEOUT);}public <T> T getWebServiceByUrl(Class<T> clazz, String url){return getWebServiceByUrl(clazz,url,CXF_CLIENT_CONNECT_TIMEOUT,CXF_CLIENT_RECEIVE_TIMEOUT);}private <T> T getWebServiceByUrl(Class<T> clazz, String url,Integer connetTimeout,Integer receiveTimeout){JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();factory.setServiceClass(clazz);factory.setAddress(url);@SuppressWarnings("unchecked")T webService = (T) factory.create();//设置接口 连接超时和请求超时Client proxy = ClientProxy.getClient(webService);HTTPConduit conduit = (HTTPConduit) proxy.getConduit();HTTPClientPolicy policy = new HTTPClientPolicy();policy.setConnectionTimeout(connetTimeout);policy.setReceiveTimeout(receiveTimeout);conduit.setClient(policy);return webService;}}

使用方式如下:
首先生成客户端接口:

//注入WebServiceUtil//XXXX.class代表生成的接口类// webServiceUrl 接口地址// getWebService() 后可以点出可用的接口方法.webServiceUtil.getWebService(XXXX.class, webServiceUrl).方法

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。