发布时间:2022-08-19 12:17
网上的解释很多,其实就是跨语言和操作系统的的远程调用技术。比如亚马逊,可以将自己的服务以webservice的服务形式暴露出来,我们就可以通过web调用这些,无论我们使用的语言是java还是c,这也是SOA应用一种表现形式。
WSDL(Web Services Description Language)将无论用何种语言书写的web service描述出来,比如其参数或返回值。WSDL是服务端和客户端都能解读的标准格式。客户端通过URL地址访问到WSDL文件,在调用服务端之前先访问WSDL文件。 读取到WSDL后通过客户端的API类可以生成代理类,调用这些代理类就可以访问webservice服务。代理类将客户端的方法变为soap(Simple Object Access Protocol,可以理解为http+xml)格式通过http发送,同时接受soap格式的返回值并解析。
org.springframework.boot
spring-boot-starter-parent
2.0.8.RELEASE
org.apache.cxf
cxf-spring-boot-starter-jaxws
3.3.3
import com.techhero.platform.api.service.GfService;
import com.techhero.platform.api.service.Impl.GfServiceImpl;
import com.techhero.platform.api.util.WsInterceptor;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
/**
* @ClassName CxfConfig
* @Description: cxf 发布所有接口至服务
* @Author wuchao
* @Date 2020/1/13
* @Version V1.0
**/
@Configuration
public class CxfConfig {
/*springboot 2.0.6版本之后写法改为配置文件*/
/* @Bean
public ServletRegistrationBean dispatcherServlet() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new CXFServlet(), "/util/*");
servletRegistrationBean.setName("GfService");
return servletRegistrationBean;
}*/
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public GfService gfJsonService() {
return new GfServiceImpl();
}
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), gfJsonService());
endpoint.publish("/api");
endpoint.getInInterceptors().add(new WsInterceptor());
return endpoint;
}
}
cxf:
path: /GfService
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.interceptor.AbstractLoggingInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.io.DelegatingInputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.Phase;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.logging.Logger;
/**
* @ClassName WsInterceptor
* @Description: 过滤器
* @Author wuchao
* @Date 2020/1/13
* @Version V1.0
**/
public class WsInterceptor extends AbstractLoggingInterceptor {
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(WsInterceptor.class);
public WsInterceptor() {
super(Phase.RECEIVE);
}
@Override
protected Logger getLogger() {
return null;
}
@Override
public void handleMessage(Message message) throws Fault {
InputStream is = message.getContent(InputStream.class);
if (is != null) {
CachedOutputStream bos = new CachedOutputStream();
if (threshold > 0) {
bos.setThreshold(threshold);
}
try {
// 使用适当的输入流并在以后还原
InputStream bis = is instanceof DelegatingInputStream ? ((DelegatingInputStream) is).getInputStream() : is;
//仅复制到最大限制,因为这就是我们需要记录的全部
//我们可以流剩下的
IOUtils.copyAtLeast(bis, bos, limit == -1 ? Integer.MAX_VALUE : limit);
bos.flush();
bis = new SequenceInputStream(bos.getInputStream(), bis);
// 恢复委托输入流或输入流
if (is instanceof DelegatingInputStream) {
((DelegatingInputStream) is).setInputStream(bis);
} else {
message.setContent(InputStream.class, bis);
}
bos.close();
} catch (IOException e) {
throw new Fault(e);
} finally {
LOGGER.info(bos.toString());
}
}
}
}
/**
* @ClassName gfService
* @Description: TODO
* @Author wuchao
* @Date 2020/1/13
* @Version V1.0
* @WebService 使接口为webService接口
* @name 暴露服务名称
* @targetNamespace 命名空间, 一般是接口的包名倒序
**/
@WebService(name = "GfService", targetNamespace = "http://service.api.platform.techhero.com")
public interface GfService {
/**
* 获取八大类型接口
*
* @param model
* @param czsj
* @param num
* @return
*/
@WebMethod
String getBusinessData(@WebParam(name = "model") String model, @WebParam(name = "czsj") Date czsj, @WebParam(name = "num") int num);
}
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.techhero.platform.api.entity.ModelXml;
import com.techhero.platform.api.service.GfService;
import com.techhero.platform.api.util.WebUtil;
import javax.jws.WebService;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @ClassName GfServiceImpl
* @Description: TODO
* @Author wuchao
* @Date 2020/1/13
* @Version V1.0
* @WebService 使接口为webService接口
* @serviceName 与接口中指定的name一致
* @targetNamespace 命名空间, 一般是接口的包名倒序
* @endpointInterface 接口地址
**/
@WebService(serviceName ="GfService",targetNamespace="http://service.api.platform.techhero.com",
endpointInterface="com.techhero.platform.api.service.GfService")
public class GfServiceImpl implements GfService {
/**
* 获取八大类型接口
*
* @param model
* @param czsj
* @param num
* @return
*/
@Override
public String getBusinessData(String model, Date czsj, int num) {
/*此处业务逻辑*/
return null;
}
}
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.junit.Test;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
/**
*@ClassName WebServerTest 客服端测试类
*@Description: TODO
*@Author wuchao
*@Date 2020/1/13
*@Version V1.0
**/
public class WebServiceTest {
@Test
public void testSend1(){
// 创建动态客户端
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost:9099/GfService/api?wsdl");
// 需要密码的情况需要加上用户名和密码
// client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,PASS_WORD));
Object[] objects = new Object[0];
try {
//Date作为参数传递时需要转化为XMLGregorianCalendar类型
Date date = parseDate("2019-08-01 09:28:00","yyyy-MM-dd HH:mm:ss");
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(date);
XMLGregorianCalendar xmlDate = null;
try {
xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
} catch (Exception e) {
e.printStackTrace();
}
// invoke("方法名",参数1,参数2,参数3....);
/*获取八大类型*/
//objects = client.invoke("getBusinessData", "300002001",xmlDate,-1);
/*获取年度目标值*/
//objects = client.invoke("notifyYearData", "2019-04-01","1000","014043");
/*获取月度目标值*/
objects = client.invoke("getMonthData", "2019-04-01");
System.out.println( objects[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Date parseDate(String dateStr, String parseStyle) {
Date date = null;
if (null != parseStyle && !"".equals(parseStyle.trim()) && null != dateStr && !"".equals(dateStr.trim())) {
SimpleDateFormat sdf = new SimpleDateFormat(parseStyle);
try {
date = sdf.parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
}
return date;
}