SPRINGBOOT整合CXF发布WEB SERVICE和客户端调用(用户和密码验证)
主要分为客户端和服务端
服务端
- pom配置
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>webservice-service</artifactId><version>0.0.1-SNAPSHOT</version><name>webservice-service</name><description>webservice-client</description><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- HTTP --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.4</version></dependency><!-- Fast Json --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.1.41</version></dependency><!-- CXF webservice --><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-spring-boot-starter-jaxws</artifactId><version>3.3.3</version><exclusions><exclusion><groupId>javax.validation</groupId><artifactId>validation-api</artifactId></exclusion></exclusions></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build>
- Config配置
@Configuration
public class CxfConfig {@Autowiredprivate Bus bus;@Autowiredprivate ServiceMaster serviceMaster;//------------------------------------------ 默认是services ------------------------------------------@Beanpublic ServletRegistrationBean cxfServlet(){return new ServletRegistrationBean( new CXFServlet(), "/services/*");}@Beanpublic Endpoint endpoint(){EndpointImpl endpoint = new EndpointImpl(bus, serviceMaster);endpoint.publish("/ServiceMaster");endpoint.getInInterceptors().add(new ClientLoginInterceptor());endpoint.getInInterceptors().add(new AuthInterceptor());return endpoint;}}
3.WebService拦截器验证
package com.example.webserviceclient.intercptor;import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.NodeList;import javax.xml.soap.Name;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;/*** 定义拦截器用户用户验证*/
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 = "guanguan";private static final String USER_PASSWORD = "sailing2018!";public AuthInterceptor() {super(Phase.PRE_PROTOCOL);getAfter().add(SAAJInInterceptor.class.getName());}@Overridepublic void handleMessage(SoapMessage message) throws Fault {System.out.println("来了哟!"+message);SOAPMessage mess = message.getContent(SOAPMessage.class);if(mess==null){saa.handleMessage(message);mess=message.getContent(SOAPMessage.class);}SOAPHeader header =null;try {header = mess.getSOAPHeader();} catch (SOAPException e) {logger.error("getSOAPheader error:{}",e.getMessage(),e);e.printStackTrace();}if(header==null){throw new Fault(new IllegalAccessException("找不到Header,无法验证用户信息"));}NodeList username = header.getElementsByTagName("username");NodeList password = header.getElementsByTagName("password");if(username.getLength()<1){throw new Fault(new IllegalAccessException("找不到Header,无法验证用户信息"));}if(password.getLength()<1){throw new Fault(new IllegalAccessException("找不到Header,无法验证用户信息"));}String userName = username.item(0).getTextContent().trim();String passWord = password.item(0).getTextContent().trim();if(USER_NAME.equals(userName)&&USER_PASSWORD.equals(passWord)){System.out.println("admin auth success");logger.info("admin auth success");}else {SOAPException soapException = new SOAPException("认证错误");logger.info("admin auth failed");throw new Fault(soapException);}}
}
4.客户端用户密码登录验证
package com.example.webserviceclient.intercptor;import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;import javax.xml.namespace.QName;
import java.util.List;public class ClientLoginInterceptor extends AbstractPhaseInterceptor<SoapMessage> {private String username;private String password;public ClientLoginInterceptor() {super(Phase.PREPARE_SEND);}public ClientLoginInterceptor(String username, String password) {//super();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("timamaes"), auth));}
}
5.service处理类
import com.example.webserviceclient.service.ServiceMaster;
import org.springframework.stereotype.Service;
import javax.jws.WebService;@Service
@WebService(serviceName = "ServiceMaster", targetNamespace = "http://service.webserviceclient.example.com", endpointInterface = "com.example.webserviceclient.service.ServiceMaster")
public class ServiceMasterImpl implements ServiceMaster {@Overridepublic String sendMessage(String username) {System.out.println("---------------------"+username);return "收到消息啦!" + username;}
}
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;@WebService(name = "ServiceMaster", targetNamespace = "http://service.webserviceclient.example.com")//采用的是包的反向地址
public interface ServiceMaster {@WebMethod@WebResult(name = "String", targetNamespace = "http://service.webserviceclient.example.com")//采用的是包的反向地址String sendMessage(@WebParam(name = "username") String username);}
客户端
1.pom
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>webservice-client</artifactId><version>0.0.1-SNAPSHOT</version><name>webservice-client</name><description>webservice-client</description><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- HTTP --><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.4</version></dependency><!-- Fast Json --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.1.41</version></dependency><!-- Web Service - cxf --><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId><version>3.3.3</version></dependency><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>3.3.3</version></dependency><!-- Junit --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>RELEASE</version><scope>compile</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build>
2.测试代码
import com.example.webserviceclient.interceptor.ClientLoginInterceptor;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.junit.Test;public class WebController {@Testpublic void TestClient(){//---------------------------------------- 创建动态客户端 ----------------------------------------JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();Client client = dcf.createClient("http://localhost:8080/services/ServiceMaster?wsdl");
//此地址为服务端请求地址,端口配置文件中没有指定,默认为8080//------------------------------- 需要密码的情况需要加上用户名和密码 -----------------------------client.getOutInterceptors().add(new ClientLoginInterceptor("guanguan", "sailing2018!"));Object[] objects = new Object[0];try {// invoke("方法名",参数一,参数二,参数三....);objects = client.invoke("sendMessage", "天黑请闭眼。。。");System.out.println("返回数据:" + objects[0]);} catch (java.lang.Exception e) {e.printStackTrace();}}}
认证通过时服务端后台打印
客服端打印
当认证不通过时
服务端
客户端
相关文章:

SPRINGBOOT整合CXF发布WEB SERVICE和客户端调用(用户和密码验证)
主要分为客户端和服务端 服务端 pom配置 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.3</version><relativePath/> <!-- lookup parent fro…...
代码随想录训练营Day5:哈希数组
算是哈希的容器:数组(适合连续存放);set,map(适合无序存放)。所以数组操作就是hash[i];而set,map.insert(元素),map可以map[]是因为map存放了键值对可以索引查找。关于几个数组相加等…...

腾讯云3年轻量2核2G4M和2核4G5M服务器540元三年
腾讯云轻量应用服务器特价是有新用户限制的,所以阿腾云建议大家选择3年期轻量应用服务器,一劳永逸,免去续费困扰。腾讯云轻量应用服务器3年可以选择2核2G4M和2核4G5M带宽,3年轻量2核2G4M服务器540元,2核4G5M轻量应用服…...

程序员的护城河:职业发展的关键元素
目录 1. 技术深度与广度 2. 项目经验与实际操作 3. 沟通与团队协作 4. 持续学习与自我更新 5. 社区参与与开源贡献 6. 创新思维与解决问题的能力 7. 职业规划与自我管理 结语 在科技日新月异的今天,程序员的竞争已经不再仅仅依赖于技术水平,而是…...

基于SpringBoot+Vue的在线学习平台系统
基于SpringBootVue的在线学习平台系统的设计与实现~ 开发语言:Java数据库:MySQL技术:SpringBootMyBatisVue工具:IDEA/Ecilpse、Navicat、Maven 系统展示 主页 用户界面 登录界面 管理员界面 摘要 本文设计并实现了一套基于Spri…...
Kafka+redis分布式锁结合使用心得总结
#kafka部分 KafkaListener(topics "#{${vsmart_alert_detection_tms_send_message_topic}.split(,)}", groupId "${vsmart.alert.detection.consumer.group}") public void vsmartAlertDetectionTmsSendMessage(ConsumerRecord<?, ?> record, A…...

cmd打开idea
当我们用idea打开一个项目的时候,有时候这个项目目录是有的,但是用idea的open却找不到,有时候我要重新关闭窗口,再open好多次才有 于是我现在使用命令打开,先把idea安装路径的bin目录放在path里面 然后cd到项目路径&…...

javaScript爬虫程序抓取评论
由于评论区目前没有开放的API接口,所以我们不能直接通过编程获取到评论区的内容。但是,我们可以通过模拟浏览器的行为来实现这个功能。以下是一个使用Python的requests库和BeautifulSoup库来实现这个功能的基本思路: import requests from bs…...

RT-DETR 应用 CARAFE:特征内容感知重新组装
特征上采样是现代卷积神经网络架构中的关键操作,例如特征金字塔。其设计对于密集预测任务,如目标检测和语义/实例分割至关重要。在本研究中,我们提出了一种称为内容感知特征重组(CARAFE)的通用、轻量级且高效的操作符,以实现这一目标。CARAFE具有以下几个优点:(1)大的…...

Git Commit 之道:规范化 Commit Message 写作指南
1 commit message 规范 commit message格式都包括三部分:Header,Body和Footer <type>(<scope>): <subject><body><footer>Header是必需的,Body和Footer则可以省略 1.1 Header Type(必需…...

【机试题】LazyIterator迭代器懒加载问题
将下面这个未完成的Java工具类补充完成,实现懒加载的功能,该类需要实现Iterable接口,能够遍历所有数据。具体要求如下: 工具类提供了一个ValueLoader接口,用于获取数据,其中ValueLoader的接口定义为&#x…...

【面试经典150 | 位运算】位1的个数
文章目录 写在前面Tag题目来源题目解读解题思路方法一:循环检查二进制位方法二:位运算优化方法三:__builtin_popcount() 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更…...
vue中数据代理和事件处理
数据代理 直接在对象下可直接修改属性的值,而Object提供defineProperty()对属性进行控制 <script>let perosn {name: 小蜜,sex: 男,//age: 19 }Object.defineProperty(perosn,age,{value: 19//enumerable: true ,添加enumerable将默认值改为true,…...

Unity之NetCode多人网络游戏联机对战教程(8)--玩家位置同步
文章目录 前言添加相机玩家添加对应组件服务端权威(server authoritative)客户端权威(client authoritative)服务端同步位置阅读与理解PlayerTransformSync.csNetworkVariableUploadTransformSyncTransform 后话 前言 承接上篇&a…...

spring boot 中@Value读取中文配置时乱码
1.spring boot 读取application.properties 该文件是iso8859编码 如果是直接写中文 读取时会乱码 显示成?? 必须得转ascii码才能正常显示 其他方法测试也不行 Value("${apig.order.tiaokong.qianzi}") private String apigOrderTiaokongQianzi;...
选择.NET 还是 Java?
1、.NET Framework的演变: .NET Framework: 最初由Microsoft引入,是一个Windows上的全功能框架。它包含了ASP.NET、Windows Presentation Foundation(WPF)、Windows Communication Foundation(WCFÿ…...
vue 高阶组件;高阶组件
vue 高阶组件;高阶组件 文章目录 vue 高阶组件;高阶组件1. 什么是高阶组件2. 高阶组件的作用3. 高阶组件的使用 例子1:创建一个简单的高阶组件例子2:使用element-ui的高阶组件 1. 什么是高阶组件 高阶组件是一个函数,传给它一个组件…...

数据结构:树的基本概念(二叉树,定义性质,存储结构)
目录 1.树1.基本概念1.空树2.非空树 2.基本术语1.结点之间的关系描述2.结点、树的属性描述3.有序树、无序树4.森林 3.树的常考性质 2.二叉树1.基本概念2.特殊二叉树1.满二叉树2.完全二叉树3.二叉排序树4.平衡二叉树 3.常考性质4.二叉树的存储结构1.顺序存储2.链式存储 1.树 1.…...
【Qt之QStandardItemModel类】介绍
描述 QStandardItemModel类提供了一个通用的模型,用于存储自定义数据。QStandardItemModel可以用作Qt标准数据类型的存储库。它是 Model/View类 之一,是 Qt的model/view框架 的一部分。 QStandardItemModel提 供了一种基于项目的传统方法来处理模型。 Q…...

01-Spring中的工厂模式
工厂模式 工厂模式的三种形态: 工厂模式是解决对象创建问题的属于创建型设计模式,Spring框架底层使用了大量的工厂模式 第一种:简单工厂模式是工厂方法模式的一种特殊实现,简单工厂模式又叫静态工厂方法模式不属于23种设计模式之一第二种:工厂方法模式…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...