webservice小记

月初导师给了份差事给我,让我写一个调用webservice接口的功能,刚好自己这边有webservice的学习资料,就先看了下,大致了解了.发布服务之后可以生成一个wsdl文件,通过jdk自带的wsimport命令可以直接生成客户端代码.

wsimport -s /路径/ -p /包名/ http://localhost/example/HelloWorld?wsdl

类似如此的命令,wsdl既可以是文件,也可以是网上的链接.

查看下结构

根据类型,去掉class文件,快速写个客户端.

wsdl文档是从下往上读的,先根据Service的名称创建service,然后根据port的名称创建接口.最后根据operation的名称调用接口的方法.实现webservice接口的调用,服务端也正常输出了Hello World,当然这只是最简单的demo案例.

一开始打算写在公司的项目里面,但转念一想是一个独立的功能,所以准备快速搭建一个环境.Spring Boot是个不错的选择.虽然对Spring Boot还不是特别熟,但至少简化了配置.要先从oracle数据库中读取数据,添加到soap报文中,然后还有认证头信息.最后如果调用接口成功,要在数据库中的returndate中返回当前时间.

一开始没有底,从来没有写过.在网上一直找如何添加认证头信息.找了很久发现CXF框架可以通过添加拦截器的方式,进行认证.瞎鼓捣了好久,总算是写出了初版.这里就要吐槽一下了,项目方部署项目竟然全都是内网.在现场的大佬说,就连内网访问服务器都要通过远程.真是晕.服务器上还有多个版本的jdk以及tomcat,所幸,有个tomcat8.0能跑.部署到测试服务器之后.实施说webservice访问的接口地址要做成可配置,定时任务也要做成可配置.当时脑子是懵的,cxf自动通过wsdl生成客户端,然后进行修改.没有涉及到地址之说,因为wsdl上有个soap:address 他的值就是暴露给外界的访问地址.

后面我使用服务器上的soapui进行测试发现给的wsdl文件自带的地址根本没有进行头信息验证,信息验证错误也是可以通过的,然后使用他们给的地址进行soap请求,发现对头信息进行了校验..又进入了懵逼状态.

思考了许久,后面想到soap请求本质上其实就是http+xml,那么直接将请求内容通过拼串的方式用post请求发送.于是又开始查资料,带内容发送http请求的工具类.找了许久有个apache的commons-httpclient包.再查下去发现这个已经停止开发了,转向了新的项目httpcomponents-httpclient,在maven中加上依赖后,查阅文档 开始.

    @Value("${url}")
    private String url;

    @Autowired
    private EAIResultService eaiResultService;

    @RequestMapping("/test")
    public String test() throws IOException {
        //出现异常的次数
        int count = 0;
        //是否全部调用成功
        boolean flag = true;
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        CloseableHttpClient client = httpClientBuilder.build();
        HttpPost post = new HttpPost(url);
        List<EAIResult> eaiResults = eaiResultService.selectAll();
        for (EAIResult result : eaiResults) {
            String sb = String.valueOf(getHeader()) + getBody(result);
            StringEntity entity = new StringEntity(sb);
            entity.setContentType("\"text/xml; UTF-8\"");
            post.setEntity(entity);
            CloseableHttpResponse execute = client.execute(post);
            int statusCode = execute.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                count += 1;
                flag = false;
            }
        }
        if (flag) {
            System.out.println("webservice调用成功");
            return "success";
        } else {
            System.out.println("有" + count + "条记录调用webservice出现问题");
            return "failed";
        }
    }

贴一下调用接口的http的方法.要注意的是请求体里面的ContentType一定要设置为text/xml;utf-8,否则会返回415编码错误.

url是在Spring Boot的配置文件里面写好的

连接池,依旧使用的是我最喜欢的Druid,阿里的东西就是好用 嘻嘻~

需要注意的是Spring Boot因为内置tomcat,所以要以war包的形式部署在服务器上需要在入口添加重写configure方法.

@SpringBootApplication
@MapperScan("com.mingcloud.eai.dao")
public class EaiApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(EaiApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(EaiApplication.class);
    }
}

在maven依赖中也要添加,并且修改项目的packaging为war,Spring Boot默认的打包方式是jar.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>

然后就是打成war包,传到他们的服务器上,部署到tomcat上.

说下使用的定时器.其实是一个类实现了Runable,然后在线程中死循环调用,在循环中对线程进行sleep操作. : p

这次功能做完,对webservice算是登堂入室了.收益颇丰.还是很喜欢这种感觉,像是高中时候做数学题的感觉.23333

猜你喜欢

转载自blog.csdn.net/hexiaodiao/article/details/84110641