springboot 整合xcf 发布 webservice
Spring Boot集成webService
在pom添加依赖
<!--WerbService CXF依赖 start-->
<dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId>
</dependency>
<dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId>
</dependency>
<!--WerbService CXF依赖 end-->
提供webservice接口
@WebService(name = "MesService", // 暴露服务名称targetNamespace = "http://mes.jingchuang.com/"// 命名空间,一般是接口的包名倒序
)
public interface T100Service {/*** 1.【sendMaterialInfo】接收T100料件信息** @param requestMaterialInfoData* @return Result*/@WebMethodResult sendMaterialInfo(RequestMaterialInfoData requestMaterialInfoData);
}
实现webservice的方法
@Service
@Transactional
@WebService(// 对外发布的服务名,指定Web Service的服务名称:wsdl:service。缺省值为 Java 类的简单名称 + ServiceserviceName = "MesService",//portName:wsdl:portName的值。缺省值为WebService.name+PortportName = "UserServiceImpl",// 命名空间(默认的值为 “http://包名/” (也可为域名) ,可以通过此变量指定一个自定义的targetNamespace值)targetNamespace = "http://mes.jingchuang.com/",// 对外提供的接口endpointInterface = "com.jingchuang.mes.t100service.service.T100Service")
@Component
@Slf4j
public class T100ServiceImpl implements T100Service {/*** 1.【sendMaterialInfo】接收****料件信息 ** @param requestMaterialInfoData* @return*///region 接收料件信息@Override@Transactionalpublic Result sendMaterialInfo(RequestMaterialInfoData requestMaterialInfoData) {return ResultGenerator.fail("请输入正确的操作码");}//endregion
}
配置并发布
@Configuration
public class WebServiceConfig {// 注意更改此方法名:public ServletRegistrationBean dispatcherServlet() // 把默认映射覆盖掉了,把这个名字改掉,控制类方法就能访问了,可以正常其他请求url,webservice服务也正常。@Beanpublic ServletRegistrationBean disServlet(){return new ServletRegistrationBean(new CXFServlet(),"/service/*");//发布服务名称}@Bean(name = Bus.DEFAULT_BUS_ID)public SpringBus springBus(){return new SpringBus();}@Autowiredpublic T100Service t100Service;@Beanpublic Endpoint endpoint() {EndpointImpl endpoint=new EndpointImpl(springBus(), t100Service);//绑定要发布的服务endpoint.publish("/zhlxmes"); //显示要发布的名称endpoint.getInInterceptors().add(new AuthInterceptor()); //增加用户名密码验证return endpoint;}
}
增加用户名,密码验证配置
public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {private static final Logger logger = LoggerFactory.getLogger(AuthInterceptor.class);private SAAJInInterceptor saa = new SAAJInInterceptor();private static final String USER_NAME = "t100";private static final String USER_PASSWORD = "t100";public AuthInterceptor() {super(Phase.PRE_PROTOCOL);getAfter().add(SAAJInInterceptor.class.getName());}@Overridepublic void handleMessage(SoapMessage message) throws Fault {SOAPMessage mess = message.getContent(SOAPMessage.class);if (mess == null) {saa.handleMessage(message);mess = message.getContent(SOAPMessage.class);}SOAPHeader head = null;try {head = mess.getSOAPHeader();} catch (Exception e) {logger.error("getSOAPHeader error: {}", e.getMessage(), e);}if (head == null) {throw new Fault(new IllegalArgumentException("找不到Header,无法验证用户信息"));}NodeList users = head.getElementsByTagName("username");NodeList passwords = head.getElementsByTagName("password");if (users.getLength() < 1) {throw new Fault(new IllegalArgumentException("找不到用户信息"));}if (passwords.getLength() < 1) {throw new Fault(new IllegalArgumentException("找不到密码信息"));}String userName = users.item(0).getTextContent().trim();String password = passwords.item(0).getTextContent().trim();if (USER_NAME.equals(userName) && USER_PASSWORD.equals(password)) {logger.debug("admin auth success");} else {SOAPException soapExc = new SOAPException("认证错误");logger.debug("admin auth failed");throw new Fault(soapExc);}}
}
客户端
客户端可以通过两种方式调用服务端。
1 .通过JaxWsDynamicClientFactory方式
public static Object doPostSoap(Class<?> clazz, String postUrl, String methodName, String xml) {try {Object[] objects;if (postUrl.equals("dev")) {objects = new Object[]{TestConten};} else {log.info("【T00/doPostSoap发送】:\n" + xml);// 创建动态客户端JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();Client client = dcf.createClient(postUrl);// 设置超时单位为毫秒HTTPConduit conduit = (HTTPConduit) client.getConduit();HTTPClientPolicy policy = new HTTPClientPolicy();policy.setConnectionTimeout(15000);policy.setAllowChunking(false);policy.setReceiveTimeout(30000);conduit.setClient(policy);// invoke("方法名",参数1,参数2,参数3....);objects = client.invoke(methodName, xml);log.info("【T00/doPostSoap接收】:\n" + objects[0].toString());// 需要密码的情况需要加上用户名和密码
// client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,PASS_WORD));}Log loginfo = new Log();loginfo.setType("info");loginfo.setName("【请求T100接口】-doPostSoap");loginfo.setContent(xml);loginfo.setMethodName(methodName);loginfo.setCreateTime(new Date());loginfo.setCreateUserId(BaseContextHandler.getUserID());loginfo.setCreateUserName(BaseContextHandler.getUsername());loginfo.setResult(objects[0].toString());try {logService.save(loginfo);} catch (Exception ex) {log.info("保存日志错误" + ex.getMessage());}if (objects.length <= 0) {return null;}ReceivingData receivingData = (ReceivingData) XsteamUtil.toBean(ReceivingData.class, objects[0].toString());
// receivingData = (ReceivingData)XsteamUtil.toBean(ReceivingData.class,TestConten);Object rulest = XsteamUtil.toBean(clazz, receivingData.getPayload().getParam().getData());return rulest;} catch (Exception e) {System.out.println("错误信息:" + e.getMessage());return null;}}
这种方式要注意的就是,如果调用的服务接口返回的是一个自定义对象,那么结果Object[]中的数据类型就成了这个自定义对象(组件帮你自动生成了这个对象),
但是你本地可能并没有这个类,所以需要自行转换处理,最简单的是新建一个跟返回结果一模一样的类进行强转。
客户端需要在header中添加用户信息,这样才能通过服务器的验证。
public class ClientLoginInterceptor extends AbstractPhaseInterceptor<SoapMessage> {private String username;private String password;public ClientLoginInterceptor(String username, String password) {super(Phase.PREPARE_SEND);this.username = username;this.password = password;}@Overridepublic void handleMessage(SoapMessage soap) throws Fault {List<Header> headers = soap.getHeaders();Document doc = DOMUtils.createDocument();Element auth = doc.createElement("authrity");Element username = doc.createElement("username");Element password = doc.createElement("password");username.setTextContent(this.username);password.setTextContent(this.password);auth.appendChild(username);auth.appendChild(password);headers.add(0, new Header(new QName("tiamaes"),auth));}
}
2、通过wsimport生成客户端代码
通过jdk自带的wsimport生成客户端代码。进入$JAVA_HOME/bin下,新建bin和src两个文件夹,执行以下命令:
wsimport -d ./bin -s ./src -keep http://localhost:8080/services/layout?wsdl
其中几个参数有以下几个,
-d:生成客户端执行类的class文件存放目录,
-s:生成客户端执行类的源文件存放目录,
-p:定义生成类的包名
-verbose:显示生成过程
需要注意的是:无论-d或是-s后的目录必须在文件系统中存在,否则报错。
将src下连同包一起复制到程序中,编写客户端入口类:
public class WSClient {private static final Logger LOG = LoggerFactory.getLogger(WSClient.class);private static final String USER_NAME = "admin";private static final String PASS_WORD = "pass";public static void main(String[] args) {//方式二:通过wsimport生成客户端代码LayoutServiceImpl impl = new LayoutServiceImpl();impl.setHandlerResolver(new HandlerResolver() {@Overridepublic List<Handler> getHandlerChain(PortInfo portInfo) {List<Handler> handlerList = new ArrayList<Handler>();handlerList.add(new ClientHandler(USER_NAME, PASS_WORD));return handlerList;}});try {LayoutService layoutService = impl.getLayoutImpl();String result_1 = layoutService.sayHello("jack");LOG.debug("[2]sayHello:" + result_1);OperationResult result_2 = layoutService.addLayout("name", "content");LOG.debug("[2]addLayout result_succeed:" + result_2.isSucceed());LOG.debug("[2]addLayout result_msg:" + result_2.getMsg());} catch (SOAPFaultException e) {LOG.error("SOAPFaultException occurs:{}", e.getMessage());}}
该方式的好处是可以像调用本地接口一样调用服务端方法,简单明了。缺点就是会生成一堆文件。
用户的头信息设置类:
public class ClientHandler implements SOAPHandler<SOAPMessageContext> {private String username;private String password;public ClientHandler(String username, String password) {this.username = username;this.password = password;}public boolean handleMessage(SOAPMessageContext ctx) {//出站,即客户端发出请求前,添加表头信息Boolean request_p = (Boolean)ctx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);if (request_p) {try {SOAPMessage msg = ctx.getMessage();SOAPEnvelope env = msg.getSOAPPart().getEnvelope();SOAPHeader hdr = env.getHeader();if (hdr == null) hdr = env.addHeader();//添加认证信息头QName name = new QName("http://service.webservice.com/", "LayoutImpl");SOAPHeaderElement header = hdr.addHeaderElement(name);SOAPElement userElement = header.addChildElement("username");userElement.addTextNode(username);SOAPElement passElement = header.addChildElement("password");passElement.addTextNode(password);msg.saveChanges();return true;} catch (Exception e) {e.printStackTrace();}}return false;}@Overridepublic boolean handleFault(SOAPMessageContext context) {// TODO Auto-generated method stubreturn false;}@Overridepublic void close(MessageContext context) {// TODO Auto-generated method stub}@Overridepublic Set<QName> getHeaders() {// TODO Auto-generated method stubreturn null;}
}
springboot 整合xcf 发布 webservice相关推荐
- IDEA中进行SpringBoot整合spring-ws开发webservice接口后期要修改xsd文件流程
场景 SpringBoot整合spring-ws开发webservice接口(全流程详细教程) 参照: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/articl ...
- 基于Springboot整合RestTemplate调用Webservice接口
1.基于Springboot整合RestTemplate调用Webservice接口,如果感觉使用webservice客户端调用服务器端不会,或者不方便 的时候,可以尝试使用RestTemplate来 ...
- SpringBoot整合spring-ws开发webservice接口(全流程详细教程)
场景 spring-ws spring-ws官网: https://spring.io/projects/spring-ws SpringWebServices(Spring-WS)是Spring社区 ...
- java - springmvc整合cxf发布webservice
1.jar包已上传百度云盘,在jar包目录下 2.web.xml配置 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-inst ...
- IDEA快速 实现 SpringMVC 整合xfire 发布 WebService 服务
文章目录 一.idea快速搭建web项目 二.xfire 服务方搭建 1. pom依赖 2. web.xml 3. 创建一个entity 4. 创建一个接口 5. 创建接口实现类 6. 在WEB-IN ...
- spring boot整合cxf发布和调用webservice
一.前言 说起web service最近几年restful大行其道,大有取代传统soap web service的趋势,但是一些特有或相对老旧的系统依然使用了传统的soap web service,例 ...
- springboot整合dubbo\zookeeper做注册中心
springboot整合dubbo发布服务,zookeeper做注册中心.前期的安装zookeeper以及启动zookeeper集群就不说了. dubbo-admin-2.5.4.war:dubbo服 ...
- SpringBoot整合WebService(服务端+客户端)
SpringBoot整合WebService(服务端+客户端) 文章目录 SpringBoot整合WebService(服务端+客户端) 一.服务端 1.项目结构 2.创建好SpringBoot项目后 ...
- Spring和CXF整合发布WebService(服务端、客户端)
参考Spring和CXF整合发布WebService(服务端.客户端) 转载于:https://www.cnblogs.com/timspace/p/11113576.html
最新文章
- 微信扫描二维码登入实现,网页端
- Heinz College of Information Systems and Public Policy Carnegie Mellon University
- USACO1.3.4 Prime Cryptarithm 牛式 解题报告(模拟)
- anaconda中gurobi下载_Anaconda是什么?Anconda下载安装教程 - python基础入门(16)
- 作者:陈兴鹏(1963-),男,兰州大学资源环境学院教授、博士生导师。
- mysql如何查看dbid_如何获得数据库的DBID
- Luogu2467 SDOI2010 地精部落 DP
- oracle 索引监控
- c语言函数定义的语法格式,C语言函数
-C语言函数定义的语法格式
- python提取句子_关于python:从句子中提取介词短语
- php设置pdf下载加密文件,pdf文件加密方法 PDF文件怎样加密 如何给PDF文件添加打开口令...
- IT人才外包的合作流程是怎样的?
- php手机网页下载文件,php 手机下载 POST 类
- 扩展Euclidean算法求乘法逆原理详解与算法实现
- Git 版本控制工具学习
- adb 强制删除系统应用
- SQL Server 中WITH (NOLOCK)浅析 2014-08-30 11:58 by 潇湘隐者, 58264 阅读, 33 评论, 收藏, 编辑 概念介绍 开发人员喜欢在SQL脚本
- iOS 苹果审核被下架的部分原因
- Go语言模板脚本语法——详细
- Linux 路由实现原理