WebService

news2025/3/1 15:02:27

Webservice 是一种传统的soa技术架构, 它不依赖于任何的编程语言,也不依赖于任何的技术平台, 可以直接基于http协议实现网络应用间的数据交互

Webservice 服务端是以接口远程接口为主的, 在java实现的webservice技术里面主要依靠的是CXF开发框架,而这个CXF框架可以直接将接口发布成webservice,同时还需要考虑到整个项目之中的安全性问题

[ws-common] 子模块中  定义接口

package com.ly.service;

import javax.jws.WebMethod;

import javax.jws.WebParam;

import javax.jws.WebService;

@WebService(name="MessageService",targetNamespace = "http://service.ly.com") //与包名相反

public interface IMessageService {

    @WebMethod    //进行webservice 方法标注

    public String echo(@WebParam String msg);

}

[ws-server] 中 定义接口的实现

package com.ly.service.impl;

import com.ly.service.IMessageService;

import org.springframework.stereotype.Service;

import javax.jws.WebService;

@WebService(serviceName = "MessageService",

            targetNamespace = "http://service.ly.com",   //接口命名空间

            endpointInterface = "com.ly.service.IMessageService")  //接口名称

@Service

public class MessageService implements IMessageService {

    @Override

    public String echo(String msg) {

        return "[Echo]"+msg;

    }

}

此时webservice 接口开发完成了, 但最终想要使用 还需要一些安全上的配置,

这个安全配置是基于拦截器完成的

[ws-server 中 ]

package com.ly.interceptor;

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.message.Message;

import org.apache.cxf.phase.AbstractPhaseInterceptor;

import org.apache.cxf.phase.Phase;

import org.springframework.stereotype.Component;

import org.w3c.dom.NodeList;

import javax.xml.soap.SOAPException;

import javax.xml.soap.SOAPHeader;

import javax.xml.soap.SOAPMessage;

import java.util.Locale;

@Component

public class WebServiceInterceptorLy extends AbstractPhaseInterceptor<SoapMessage> {

    private SAAJInInterceptor saaj = new SAAJInInterceptor();//创建拦截器

    private static final String USER_NAME="liu"; //用户名

    private static final String USER_PASS="ly.com";//密码

    public WebServiceInterceptorLy() {

        super(Phase.PRE_PROTOCOL);

        super.getAfter().add(SAAJInInterceptor.class.getName());//添加拦截

    }

    @Override

    public void handleMessage(SoapMessage soapMessage) throws Fault {

        SOAPMessage content = soapMessage.getContent(SOAPMessage.class);

        if(content ==null){ //没有消息内容

            this.saaj.handleMessage(soapMessage); // 直接走默认处理

            content = soapMessage.getContent(SOAPMessage.class);//尝试获取消息

        }

        SOAPHeader header = null; //soa 头信息

        try {

            header = content.getSOAPHeader(); //通过消息获取头

        } catch (SOAPException e) {

            e.printStackTrace();

        }

        if(header==null){  //没有头信息

          throw new Fault(new IllegalAccessException("找不到头信息,无法实现用户认证"));

        }

        //SOAP 是就xml文件结构进行传输的,所以如果要想获取认证信息必须进行相关的结构约定

        NodeList usernameList = header.getElementsByTagName("username");

        NodeList passwordList = header.getElementsByTagName("password");

        if (usernameList.getLength()<1 || passwordList.getLength()<1){

            throw new Fault(new IllegalAccessException("找不到头信息,无法实现用户认证"));

        }

        String username = usernameList.item(0).getTextContent().trim();

        String passsword = passwordList.item(0).getTextContent().trim();

        if(USER_NAME.equals(username) && USER_PASS.equals(passsword)){ //认证合法

            System.out.println("认证成功-------------");

        }else{

            SOAPException soapException = new SOAPException("用户认证失败");

            System.out.println("用户认证失败--------------------");

            throw new Fault(soapException);

        }

    }

}

[ws-server]

package com.ly.config;

import com.ly.interceptor.WebServiceInterceptorLy;

import com.ly.service.IMessageService;

import org.apache.cxf.Bus;

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;

@Configuration

public class CXFConfig {

    @Autowired

    private Bus bus;  //注入bug接口实例

    @Autowired

    private IMessageService messageService;//注入业务实例

    @Autowired

    private WebServiceInterceptorLy interceptor;//认证拦截器

    @Bean

    public ServletRegistrationBean getRegistrationBean(){

        return new ServletRegistrationBean(new CXFServlet(),"/services/*");  //webservice 访问的父路径

    }

@Bean

    public Endpoint messagePoint(){

        EndpointImpl endpoint = new EndpointImpl(this.bus,this.messageService);

        endpoint.publish("/MessageService");

        endpoint.getInInterceptors().add(this.interceptor);

        return endpoint;

    }

}

[ws-server]  创键 启动类

package com.ly;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class WSServer {

    public static void main(String[] args) {

        SpringApplication.run(WSServer.class,args);

    }

}

启动 ,  地址栏输入 http://localhost:8080/services

Wsdl 描述文件

[ws-client] 创建一个拦截器 ,来实现认证数据的传递

package com.ly.interceptor;

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.message.Message;

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 ClientInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

    private String username;

    private String password;

    public ClientInterceptor(String username,String password){

        super(Phase.PREPARE_SEND);

        this.username = username;

        this.password =password;

    }

    @Override

    public void handleMessage(SoapMessage soap) throws Fault {

        List<Header> headers = soap.getHeaders();//获取全部头信息

        Document document = DOMUtils.createDocument();//创建文档

        Element auth = document.createElement("authority");//认证数据信息

        Element username = document.createElement("username");//认证数据信息

        Element password = document.createElement("password");//认证数据信息

        username.setTextContent(this.username);

        password.setTextContent(this.password);

        auth.appendChild(username);

        auth.appendChild(password);

        headers.add(0,new Header(new QName("authority"),auth));

    }

}

[ws-client]  基于代理的方式 实现WebService服务调用

package com.ly.client;

import com.ly.interceptor.ClientInterceptor;

import com.ly.service.IMessageService;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

public class CXFClientProxy {

    public static void main(String[] args) throws Exception{

        String address = "http://localhost:8080/services/MessageService?wsdl";

        JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();

        jaxWsProxyFactoryBean.setAddress(address);

        jaxWsProxyFactoryBean.setServiceClass(IMessageService.class);// 映射的接口

        jaxWsProxyFactoryBean.getOutInterceptors().add(new ClientInterceptor("liu","ly.com"));

        IMessageService service = (IMessageService) jaxWsProxyFactoryBean.create();//远程接口映射

        String message = "hello webservice";

        String result = service.echo(message);

        System.out.println("客户端输出----"+result);

    }

}

启动 ws-server , 启动成功后, 在ws-client中 运行CXFClientProxy的main

控制台 输出

[ws-client]  通过动态代理方式实现

package com.ly.client;

import com.ly.interceptor.ClientInterceptor;

import org.apache.cxf.endpoint.Client;

import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;

public class CXFClientDyn {

    public static void main(String[] args) throws Exception{

        String address = "http://localhost:8080/services/MessageService?wsdl";

        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();

        Client client = dcf.createClient(address); //创建一个客户端类

        client.getOutInterceptors().add(new ClientInterceptor("liu","ly.com"));

        String message = "hello webservice";

        Object[] result = client.invoke("echo",message);

        System.out.println("客户端输出333333----"+result[0]);

    }

}

启动 server  运行 ,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1382333.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《向量数据库指南》让「引用」为 RAG 机器人回答增加可信度

在之前的文章中&#xff0c;我们已经介绍了如何用 Milvus 向量数据库以及 LlamaIndex 搭建基础的聊天机器人《Chat Towards Data Science &#xff5c;如何用个人数据知识库构建 RAG 聊天机器人&#xff1f;》《书接上回&#xff0c;如何用 LlamaIndex 搭建聊天机器人&#xff…

计算机图形学作业:三维线段的图形变换

1. 将三维空间某线段 P1P2进行如下的操作&#xff0c;请按要求回答问题&#xff1a; &#xff08;1&#xff09; 沿 X 轴、Y 轴和 Z 轴分别平移 dx、dy 和 dz 的长度&#xff0c;给出相应的变换矩阵。 变换矩阵为&#xff1a; T100001000010dxdydz1 &#xff08;2&#xff09…

Scanner接收用户键盘输入数据(Java)

1.导包&#xff1a;import java.util.Scanner; 一般情况不需要自己导包&#xff0c;idea工具会自动帮助我们导包 2.代码&#xff1a; 得到键盘扫描器对象&#xff1a; Scanner sc new Scanner(System.in); 接收用户输入数据&#xff1a; int sth sc.nextInt(); String…

算法每日一题: 删除排序列表中的重复元素 | 链表的删除

大家好&#xff0c;我是星恒 今天给大家带来的是一道简单的链表删除题&#xff0c;题目很简单&#xff0c;不过可以帮助我们很好的复习链表的删除&#xff0c;尤其适合基础薄弱的友友们学习 ~ 题目&#xff1a;leetcode 83 给定一个已排序的链表的头 head &#xff0c; 删除所有…

【教学类-43-20】20240113 数独(二)4宫格、9宫格 无空行A4模板

作品展示&#xff1a; 4宫格 9宫格 题目连在一起 背景需求&#xff1a; 制作十宫格数独模板&#xff0c;为了凑满20行&#xff0c;删除了每个数独题之间的行列分割线 【教学类-43-18】A4最终版 20240111 数独11.0 十宫格X*YZ套(n10)&#xff0c;套用没有分割行列的A4横版模板…

C语言辨析——深入理解字符常量与表达式

1. 问题 今天看到一个题目&#xff0c;截图如下。 从答题情况来看&#xff0c;本题的答案是B&#xff0c;那么就意味着A、C、D是错的。但我认为这4个选项都是对的。当然&#xff0c;如果要从4个选项中挑选一个的话&#xff0c;那还是选择B妥当一些。 2. 分析 字符常量的定义…

SpringCloud Aliba-Nacos-从入门到学废【1】

&#x1f95a;今日鸡汤&#x1f95a; 当你最倒霉地时候一定要扛住。 因为&#xff0c;那正是你运气该上升的时候。 ——《一人之下》 目录 &#x1f9c8;1.Nacos介绍 &#x1f9c2;2.Nacos服务提供者注册 &#x1f953;3.Nacos服务消费者 &#x1f32d;4.Nacos作为配置中心…

学习使用Rainyun搭建网站

我们选择了白嫖雨云的二级域名 浏览器输入https://www.rainyun.com/z22_ 创建账号然后选择一个你喜欢的子域名我建议后缀选择ates.top的 选择自定义地址&#xff0c;类型选择cname 现在要选择记录值了&#xff0c;有a&#xff0c;aa&#xff0c;txt等 根据实际情况填写。就可以…

最新 Vmware (17 )下载安装教程

文章目录 Vmware安装Vmware官网Vmware官网选择对应的平台 win或者 linux安装包下载完成后 双击开始安装秘钥vmware workstation pro17密钥分享: Vmware安装 Vmware官网 中文网: https://www.vmware.com/cn.html 英文网: https://www.vmware.com/Vmware官网 选择对应的平台 wi…

Aigtek超声功率放大器的选型技巧及参数指标有哪些

超声功率放大器是一种广泛应用于声学测量、医疗成像、声纳等领域的装置&#xff0c;其作用是将输入信号的功率放大到需要的水平。在选型超声功率放大器时&#xff0c;需要考虑一些关键的技巧和参数指标&#xff0c;以确保选择合适的设备来满足特定的需求。 首先&#xff0c;需要…

【Spring Cloud Alibaba】Sentinel 服务熔断与流量控制

目录 前言 一、Sentinel 入门 1.1 什么是 Sentinel ? 1.2 微服务集成 Sentinel 1.3 安装Sentinel控制台 二、Jmeter 压力测试工具 2.1 Jmeter 介绍 2.2 Jmeter 安装 2.3 接口测试 三、Sentinel 使用 3.1 限流规则 3.1.1 warm up(预热模式) 3.1.2 排队等待 3.1.3…

Cortex-M移植

常用寄存器 PRIMASK寄存器 PRIMASK寄存器为1位宽的中断屏蔽寄存器。在置位时&#xff0c;它会阻止不可屏蔽中断&#xff08;NMI&#xff09;和HardFault异常之外的所有异常&#xff08;包括中断&#xff09;。实际上&#xff0c;它是将当前异常优先级提升为0&#xff0c;这就是…

如何激活数据要素价值

文章目录 前言一、数据作为生产要素的背景二、数据作为新型生产要素&#xff0c;是价值创造的重要源泉&#xff08;一&#xff09;生产要素是经济活动中的基本要素&#xff08;二&#xff09;激活数据要素价值&#xff0c;要从理论上认识数据要素的基本特征&#xff08;三&…

记redis5.x在windows上搭建集群(六主六从)

六个运行端口 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 1、安装redis,文章太多不多BB 2、复制六份redis文件夹出来改名 3、修改每一份的配置文件 redis.windows.conf 修改为以下格式&#xff1a; #运行端口 port…

【K12】Python写分类电阻问题的求解思路解析

分压电阻类电路问题python程序写法 一个灯泡的电阻是20Ω&#xff0c;正常工作的电压是8V&#xff0c;正常工作时通过它的电流是______A。现在把这个灯泡接到电压是9V的电源上&#xff0c;要使它正常工作&#xff0c;需要给它______联一个阻值为______的分压电阻。 解决思想 …

Gitlab集成openLDAP统一认证登录

vim /etc/gitlab/gitlab.rb&#xff0c; 可以配置很多个server&#xff0c;因此与sssd服务一样可以配置多个ldap作为高可用 gitlab-ctl reconfiguregitlab-rake gitlab:ldap:checkgitlab-ctl restart gitlab-rake gitlab:ldap:check Checking LDAP ...LDAP: ... Server: ldapm…

centos7系统部署rancher2.x,并创建k8s集群

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 前言 一 本文目标&#xff1a; 1、部署rancher-server UI&#xff0c;版本&#xff1a;2.3.5 2、通过rancher部署一个k8s集群c…

html+JavaScript的媒体元素

<video src"conference.mpg" id"myVideo">Video player not available.</video> <!-- 嵌入音频 --> <audio src"song.mp3" id"myAudio">Audio player not available.</audio> - 属性 每个元素至少…

【蓝桥杯日记】第一篇——系统环境的搭建

目录 前言 环境相关文件 学生机环境-Web应用开发环境&#xff08;第十五届大赛&#xff09; 学生机环境-Java编程环境&#xff08;第十五届大赛&#xff09; 学生机环境-C/C编程环境&#xff08;第十五届大赛&#xff09; 学生机环境-Python编程环境 &#xff08;第十五届…

JavaScript深拷贝与浅拷贝的全面解析

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》 ​ ​ 目录 ✨ 前言 ✨ 正文 浅拷贝 对象的浅拷贝 数组的浅拷贝 浅拷贝的问题 深拷贝 什么是深拷贝…