博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实现一个spring webservice服务端四:服务端、客户端以及httpclient调用spring-ws服务...
阅读量:7090 次
发布时间:2019-06-28

本文共 8786 字,大约阅读时间需要 29 分钟。

经过前段时间的学习,已经实现一个有返回值的spring-ws服务,那接下来,就要试试能不能通过不同方式的调用,要实现一下几种方式的测试:

  • spring-ws服务端测试

  • spring-ws客户端测试

  • httpclient

spring-ws服务端测试

我对spring-test 和spring-ws-test,几乎没有什么了解,只好按照文档来写spring-ws服务端测试的,这是测试代码:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("spring-ws-servlet.xml")public class WebserviceTest {        @Autowired    private ApplicationContext applicationContext;        private MockWebServiceClient client;        @Before    public void createClient() {        client = MockWebServiceClient.createClient(applicationContext);    }            @Test    public void holidayTest() {            Source requestPayload = new StringSource(                            "
" + "
旺财
" + "
"); Source responsePayload = new StringSource( "
" + "
中华田园犬
" + "
5
" + "
"); client.sendRequest(RequestCreators.withPayload(requestPayload)).andExpect(ResponseMatchers .payload (responsePayload)); }}

需要添加jar包:

junit
junit
4.12
org.springframework.ws
spring-ws-test
2.4.0.RELEASE
org.springframework
spring-test
4.2.7.RELEASE

执行测试方法,一直报下面这个错误:

failed to load applicationcontext

因为我没有配置日志,所以不知道具体错误是什么,只好又去配置log4j2,配置完之后,具体的错误信息可以看到了:

Caused by: java.io.FileNotFoundException: class path resource [spring-ws-servlet.xml] cannot be opened because it does not exist    at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172)    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:330)    ... 36 more

可以看到,是因为找不到配置文件【spring-ws-servlet.xml】,我找到了出错的代码:

public URL getResource(String name) {        URL url;        if (parent != null) {            url = parent.getResource(name);        } else {            url = getBootstrapResource(name);        }        if (url == null) {            url = findResource(name);        }        return url;    }

name就是spring-ws-servlet.xml, parent就是Classloader,只是不知道为什么找不到;

我只好把路径修改为@ContextConfiguration("classpath:spring-ws-servlet.xml"),为了能够在classpath下找到这个文件,又把spring-ws-servlet.xml 和hr.xsd文件复制到src/main/resource下面,可能有人会疑惑为什么是复制过去一份,而不是把WEB-INF下的文件转移到src/main/resource下面,因为spring 的默认加载位置就是wWEB-INF下的文件,而我又没有找到读取classpath路径文件的配置,就是这个:

spring-ws
org.springframework.ws.transport.http.MessageDispatcherServlet
transformWsdlLocations
true

所以只好改成这样,虽然看着奇怪,但是不再报找不到文件的错误了。

改完之后,继续测试,可是又有报错了:

[different] Expected namespace URI 'http://mycompany.com/hr/webservice' but was 'null' - comparing 
at /holidayResponse[1] to
at /holidayResponse[1]Payload:
中华田园犬
5

起初,以为是哪里错了,后来,认真看了下信息,才发现,报错是因为期望返回值中有xmlns='',但是实际返回值是:

中华田园犬
5

和期望的值不一样,所以才报了这个错,把期望值修改了一下:

Source responsePayload = new StringSource(                            "
" + "
中华田园犬
" + "
5
" + "
");

这样再测试,就不报错了。

至此,spring-ws服务端测试通过。

spring-ws客户端测试

spring-ws参考文档上关于服务端测试,给出了几种方式,有http、jms、eamil等,因为我的测试服务端是http的,所以就使用http的测试;

关于http测试webservice的方式,spring-ws首先给出的要求是要有消息工厂【messageFactory】,就像下面的配置一样:

spring-ws提供了两种消息工厂,分别为:

  • SaajSoapMessageFactory ------saaj 支持多

  • AxiomSoapMessageFactory ------axis2 适合数据多

我参考文档写的测试代码是:

import org.junit.Test;import org.springframework.ws.client.core.WebServiceTemplate;import org.springframework.xml.transform.StringSource;import javax.xml.transform.stream.StreamResult;import javax.xml.transform.stream.StreamSource;/** * Created by nyl * 2017/6/23 */public class SpringClient {        private final WebServiceTemplate client = new WebServiceTemplate();            @Test    public void sptingTest() {                client.setDefaultUri("http://www.ningyongli.site:8080/webservicelearn/holidayService");            StreamSource source =  new StringSource(                        "
" + "
旺财
" + "
"); try { JAXBContext unmarshaller = JAXBContext.newInstance(HolidayResponse.class); JAXBResult jaxbResult = new JAXBResult(unmarshaller); //StreamResult result = new StreamResult(System.out); client.sendSourceAndReceiveToResult(source, jaxbResult); HolidayResponse holidayResponse = (HolidayResponse) jaxbResult.getResult(); System.out.println(holidayResponse.toString()); } catch (JAXBException e) { e.printStackTrace(); } } }

代码中并没有设置messageFactory,于是我去看源码,发现:

public WebServiceTemplate() {        initDefaultStrategies();    }    /**     * Creates a new {@code WebServiceTemplate} based on the given message factory.     *     * @param messageFactory the message factory to use     */    public WebServiceTemplate(WebServiceMessageFactory messageFactory) {        setMessageFactory(messageFactory);        initDefaultStrategies();    } 还有···········

WebServiceTemplate 提供了很多中构造方法,无参构造方法会加载默认的配置(initDefaultStrategies),默认配置如下:

org.springframework.ws.client.core.FaultMessageResolver=org.springframework.ws.soap.client.core.SoapFaultMessageResolverorg.springframework.ws.WebServiceMessageFactory=org.springframework.ws.soap.saaj.SaajSoapMessageFactoryorg.springframework.ws.transport.WebServiceMessageSender=org.springframework.ws.transport.http.HttpUrlConnectionMessageSender

也就是说,默认的就是SaajSoapMessageFactory这个,知道了,我就不管这个了。

WebServiceTemplate 有很多用于请求的方法

请求方法

我用的是这个sendSourceAndReceiveToResult(source, result),这些方法的参数请求参数顶级接口Source ,返回数据顶级接口Result,回调方法等;只要根据接口要求,实现子类,放进方法里执行即可。

执行结果如下:

HolidayResponse{ name=中华田园犬, age=5}

httpclient测试

我认为所有使用http协议的,都能使用httpclient测试。

我在学习spring-ws之前遇到了几次webservice的问题,其中一个让我印象深刻,第三方公司给我一个wsdl文件,我根据文件生成客户端代码,发现返回值是boolean类型的数据,但是他给我的soap ui测试截图上,返回的是一个复杂的对象,我以为我客户端代码生成错了,于是尝试了axis 、axis2 、cxf等jar包,生成的返回值都一样,于是我就去看wsdl文件(那时候基本上还看不懂),发现wsdl中返回值就是boolean类型,于是和对接人员沟通希望给出正确的wsdl文件,结果对方不认为wsdl有问题,反正soap ui 测通了,让我自己想办法。
于是就有了httpclient调用webservice的经历。

下面是我写的测试代码:

@Test    public void httpclientTest() {        CloseableHttpClient closeableHttpClient = null;        CloseableHttpResponse closeableHttpResponse = null;        String  result = null;        try {                        String requestStr = "
" + "
" + "
"+ "
" + "
旺财
" + "
" + "
" + "
"; HttpPost httpPost = new HttpPost("http://www.ningyongli.site:8080/webservicelearn/holidayService"); httpPost.setHeader("Content-Type", "text/xml;charset=utf-8"); //httpPost.setHeader("SOAPAction", "hollidayService"); System.out.println(requestStr); StringEntity entity = new StringEntity(requestStr, "UTF-8"); httpPost.setEntity(entity); closeableHttpClient = HttpClients.createDefault(); closeableHttpResponse = closeableHttpClient.execute(httpPost); result = EntityUtils.toString(closeableHttpResponse.getEntity()); System.out.println(result); } catch (Exception e) { e.printStackTrace(); } finally { try { closeableHttpResponse.close(); closeableHttpClient.close(); } catch (Exception e) { e.printStackTrace(); } } }

需要增加一个jar包:

org.apache.httpcomponents
httpclient
4.5.3

测试结果返回值如下:

中华田园犬
5

写法稍微有点麻烦的是,需要拼接请求参数,参数少的话还好,多的话就很烦;不过这种方法不用生成一大堆客户端代码。

总结

总体而言,测试实现要比服务端实现要简单一些,基本都很快调通了。

本来还想用axis、axis2调用测试一下的,但是突然发现spring-ws生成的wsdl路径和它们要求的有点不一样,这两种要求路径都是这样的http://ip:port/name/servicena...,和我用spring-ws有点不一样,尝试了一下常用的调用方式都无法实现。以后对axis和axis2有一定了解了,再来看这个问题

客户端测试源码在

转载地址:http://txiql.baihongyu.com/

你可能感兴趣的文章
用Soap消息调用Web Services(续)
查看>>
php数据库操作封装类
查看>>
atitit.导出excel的设计----查询结果 导出为excel的实现java .net php 总结
查看>>
[LeetCode] Partition List 划分链表
查看>>
以Ajax方式显示Lotus Notes视图的javasript类库----NotesView2
查看>>
ylbtech-memorandum(备忘录)-数据库设计
查看>>
spm中头动绘图的理解,自带数据集
查看>>
PostgreSQL的 initdb 源代码分析之二十五
查看>>
I.MX6 su.c 测试
查看>>
Restful风格API接口开发springMVC篇
查看>>
车辆管理系统之继续自己的任务(五)
查看>>
谁该赋予一款产品灵魂?
查看>>
自我总结(八)- 新学期
查看>>
I.MX6 wm8962 0-001a: DC servo timed out
查看>>
ACM进阶计划
查看>>
Spring3 表达式语言(SpEL)介绍
查看>>
【Java学习笔记之七】java函数的语法规则总结
查看>>
5.23. msgpack
查看>>
【Java学习笔记之三十三】详解Java中try,catch,finally的用法及分析
查看>>
IE6 png图片实现半透明的方法
查看>>