接到一个对接json格式参数的webservice接口的任务,很久没做过webservice相关并且以前也只做过xml格式参数,所以对此做了一些了解。
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.11</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.11</version>
</dependency>
import javax.jws.WebMethod;
public interface HelloWebService {
@WebMethod(exclude=true)
String helloWord(String name);
}
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService(serviceName = "VHDMP", targetNamespace = "http://impl.service.study.test.com")
@Component
public class HelloWebServiceImpl implements HelloWebService {
@Override
public String helloWord(@WebParam(name="json")String json) {
return json;
}
}
import com.test.study.service.HelloWebService;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
/**
* WebService配置类
*/
@Configuration
public class WebServiceConfig {
@Autowired
private HelloWebService helloWebService;
/**
* 注入servlet bean name不能dispatcherServlet 否则会覆盖dispatcherServlet
* 配置访问根路径
*/
@Bean(name = "cxfServlet")
public ServletRegistrationBean cxfServlet() {
return new ServletRegistrationBean(new CXFServlet(), "/services/*");
}
/**
* 总线(BUS)是CXF架构的主干,为共享资源提供了一个可配置的场所,作用非常类似于Spring的ApplicationContext。
*/
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean(name = "webServiceTestEndPoint")
public Endpoint webServiceTestEndPoint() {
EndpointImpl endpoint = new EndpointImpl(springBus());
//配置webservice服务接口 接口地址,对应的接口
Endpoint.publish("/odr", helloWebService);
return endpoint;
}
}
访问webservice接口地址http://localhost:8081/services/odr?wsdl获取wsdl信息
通过soupui界面可以查看调用xml和响应xml格式,根据对应格式组装2.3请求报文和解析响应信息
import cn.hutool.json.JSONObject;
import cn.hutool.json.XML;
import org.apache.http.Consts;
import org.apache.http.HttpStatus;
import org.apache.http.entity.ContentType;
import org.springframework.http.HttpMethod;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
public class WebServiceTest {
public static void main(String[] args) throws Exception {
//第一步:创建服务地址,不是WSDL地址
URL url = new URL("http://localhost:8081/services/odr");
//第二步:打开一个通向服务地址的连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//第三步:设置参数
//3.1发送方式设置:POST必须大写
connection.setRequestMethod(HttpMethod.POST.toString());
//3.2设置数据格式:content-type
connection.setRequestProperty("Accept", ContentType.APPLICATION_JSON.toString());
connection.setRequestProperty("Content-Type", ContentType.APPLICATION_JSON.toString());
//3.3设置输入输出,因为默认新创建的connection没有读写权限
connection.setDoInput(true);
connection.setDoOutput(true);
//第四步:组织请求报文,发送请求
String requestStr = getXML("{\"name\":\"zhangsan\"}");
OutputStream os = connection.getOutputStream();
os.write(requestStr.getBytes());
//第五步:接收服务端响应,打印
int responseCode = connection.getResponseCode();
if(HttpStatus.SC_OK == responseCode) {//表示服务端响应成功
InputStream is = connection.getInputStream();
//将字节流转换为字符流
InputStreamReader isr = new InputStreamReader(is, Consts.UTF_8);
//使用缓存区
BufferedReader br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String temp = null;
while(null != (temp = br.readLine())){
sb.append(temp);
}
JSONObject responseJson = XML.toJSONObject(sb.toString());
if (responseJson != null) {
//helloWordResponse是方法名+"Response"
String result = responseJson.getJSONObject("soap:Envelope").getJSONObject("soap:Body")
.getJSONObject("ns2:helloWordResponse").get("return", String.class);
System.out.println(result);
}
is.close();
isr.close();
br.close();
} else {
throw new Exception("调用webservice接口发生异常,responseCode:" + responseCode);
}
os.close();
}
//组织数据,将数据拼接一下
public static String getXML(String parameters){
String soapXML = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:impl=\"http://impl.service.study.test.com\">"
+"<soapenv:Header/>"
+"<soapenv:Body>"
+"<impl:helloWord>" //webservice接口方法名
+ "<json>"+parameters+"</json>" //webservice接口参数名
+"</impl:helloWord>"
+"</soapenv:Body>"
+"</soapenv:Envelope>";
return soapXML;
}
}
解析响应报文时用到了hutool工具需要添加maven依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.1</version>
</dependency>
封装工具类:
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Consts;
import org.apache.http.HttpStatus;
import org.apache.http.entity.ContentType;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
@Component
@Slf4j
public class SoapUtil {
/**
* webservice接口发送json报文
* @param bytes
* @param wsdlUrl
* @return
* @throws Exception
*/
public static String sendJson(byte[] bytes, String wsdlUrl) throws Exception {
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
OutputStream os = null;
try {
//第一步:创建服务地址,不是WSDL地址
URL url = new URL(wsdlUrl);
//第二步:打开一个通向服务地址的连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//第三步:设置参数
//3.1发送方式设置:POST必须大写
connection.setRequestMethod(HttpMethod.POST.toString());
//3.2设置数据格式:content-type
connection.setRequestProperty("content-type", ContentType.APPLICATION_SOAP_XML.toString());
//3.3设置输入输出,因为默认新创建的connection没有读写权限
connection.setDoInput(true);
connection.setDoOutput(true);
//第四步:发送请求报文
os = connection.getOutputStream();
os.write(bytes);
//第五步:接收服务端响应,打印
int responseCode = connection.getResponseCode();
if(HttpStatus.SC_OK != responseCode){//表示服务端响应成功
is = connection.getErrorStream();
//将字节流转换为字符流
isr = new InputStreamReader(is, Consts.UTF_8);
//使用缓存区
br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String temp = null;
while(null != (temp = br.readLine())){
sb.append(temp);
}
log.error("webservice接口调用出错:{}", sb.toString());
throw new Exception("HTTP Request is not success, Response code is " + responseCode);
}
is = connection.getInputStream();
//将字节流转换为字符流
isr = new InputStreamReader(is, Consts.UTF_8);
//使用缓存区
br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String temp = null;
while(null != (temp = br.readLine())){
sb.append(temp);
}
return sb.toString();
} catch (Exception e){
throw e;
} finally {
if (is != null){
is.close();
}
if (isr != null){
isr.close();
}
if (br != null){
br.close();
}
if (os != null){
os.close();
}
}
}
}