springBoot整合CXF并实现用户名密码校验的方法
创始人
2025-06-01 09:39:22
0

话不多说直接上代码:

准备工作:
创建springBoot项目webservice_server

创建springBoot项目webservice_client

分别添加CXF的依赖:



    org.apache.cxf
    cxf-spring-boot-starter-jaxws
    3.1.11

一.定义要发布的接口和实现类
接口:

@WebService
public interface AppService {


    @WebMethod
    String getUserName(@WebParam(name = "id") String id) throws UnsupportedEncodingException;
    @WebMethod
    public User getUser(String id) throws UnsupportedEncodingException;
}
实现类:


//name暴露的服务名称, targetNamespace:命名空间,设置为接口的包名倒写(默认是本类包名倒写). endpointInterface接口地址
@WebService(name = "test" ,targetNamespace ="http://cxf.wolfcode.cn/" ,endpointInterface = "cn.wolfcode.cxf.AppService")
public class AppServiceImpl implements AppService {
    JSONResult jsonResult = JSONResult.getJsonResult();
    @Override
    public String getUserName(String id) throws UnsupportedEncodingException {
        System.out.println("==========================="+id);
        JSONResult result=  JSONResult.getJsonResult();
        result.setSuccess(true);
        result.setMessage("明哥");
        return result.toJsonObject();
    }
    @Override
    public User getUser(String id)throws UnsupportedEncodingException  {
        System.out.println("==========================="+id);
        return new User(1L,"明哥");
    }

}
二.发布服务
1.定义配置类


@Configuration
public class CxfConfig {
    //默认servlet路径/*,如果覆写则按照自己定义的来
    @Bean
    public ServletRegistrationBean dispatcherServlet() {
        return new ServletRegistrationBean(new CXFServlet(), "/services/*");
    }

    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
        return new SpringBus();
    }

    //把实现类交给spring管理
    @Bean
    public AppService appService() {
        return new AppServiceImpl();
    }

    //终端路径
    @Bean
    public Endpoint endpoint() {
        EndpointImpl endpoint = new EndpointImpl(springBus(), appService());
        endpoint.getInInterceptors().add(new AuthInterceptor());//添加校验拦截器
        endpoint.publish("/user");
        return endpoint;
    }
}
2.发布服务


@SpringBootApplication
public class WebserviceApplication {

    public static void main(String[] args) {
        SpringApplication.run(WebserviceApplication.class, args);
    }
}
因为我添加了用户名和密码校验所以在发布之前还需要定义自己校验用户名和密码的Interceptor


public class AuthInterceptor extends AbstractPhaseInterceptor {
    Logger logger = LoggerFactory.getLogger(this.getClass());
    private static final String USERNAME="root";
    private static final String PASSWORD="admin";

    public AuthInterceptor() {
        //定义在哪个阶段进行拦截
        super(Phase.PRE_PROTOCOL);
    }

    @Override
    public void handleMessage(SoapMessage soapMessage) throws Fault {
        List

headers = null;
        String username=null;
        String password=null;
        try {
           headers = soapMessage.getHeaders();
        } catch (Exception e) {
            logger.error("getSOAPHeader error: {}",e.getMessage(),e);
        }

        if (headers == null) {
            throw new Fault(new IllegalArgumentException("找不到Header,无法验证用户信息"));
        }
        //获取用户名,密码
        for (Header header : headers) {
            SoapHeader soapHeader = (SoapHeader) header;
            Element e = (Element) soapHeader.getObject();
            NodeList usernameNode = e.getElementsByTagName("username");
            NodeList pwdNode = e.getElementsByTagName("password");
             username=usernameNode.item(0).getTextContent();
             password=pwdNode.item(0).getTextContent();
            if( StringUtils.isEmpty(username)||StringUtils.isEmpty(password)){
                throw new Fault(new IllegalArgumentException("用户信息为空"));
            }
        }
        //校验用户名密码
        if(!(username.equals(USERNAME) && password.equals(PASSWORD))){
            SOAPException soapExc = new SOAPException("认证失败");
            logger.debug("用户认证信息错误");
            throw new Fault(soapExc);
        }

    }

}

现在可以发布服务了.....

发布完成后访问http://localhost:8888/services/user?wsdl

能够出现以下界面就是发布OK

三.调用服务
1.新建调用端项目,添加依赖

2.因为示例演示了两种调用方式,其中一种需要用到接口,所以先把服务接口拷贝一份到调用端项目中(代码就是上面接口的代码)

3.因为服务端添加了用户名密码校验,所以调用的时候需要添加用户名密码信息, 所以需要使用下面的Interceptor完成添加用户名密码信息


/**
 * Created by sky on 2018/2/27.
 */
public class LoginInterceptor extends AbstractPhaseInterceptor {
    private String username="root";
    private String password="admin";
    public LoginInterceptor(String username, String password) {
        //设置在发送请求前阶段进行拦截
        super(Phase.PREPARE_SEND);
        this.username=username;
        this.password=password;
    }

    @Override
    public void handleMessage(SoapMessage soapMessage) throws Fault {
        List

headers = soapMessage.getHeaders();
        Document doc = DOMUtils.createDocument();
        Element auth = doc.createElementNS("http://cxf.wolfcode.cn/","SecurityHeader");
        Element UserName = doc.createElement("username");
        Element UserPass = doc.createElement("password");

        UserName.setTextContent(username);
        UserPass.setTextContent(password);

        auth.appendChild(UserName);
        auth.appendChild(UserPass);

        headers.add(0, new Header(new QName("SecurityHeader"),auth));
    }
}
4.调用接口


/**
 * Created by sky on 2018/2/27.
 */
public class Cxfclient {
    //webservice接口地址
    private static String address = "http://localhost:8888/services/user?wsdl";

    //测试
    public static void main(String[] args) {
        test1();
        test2();
    }

    /**
     * 方式1:使用代理类工厂,需要拿到对方的接口
     */
    public static void test1() {
        try {
            // 代理工厂
            JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
            // 设置代理地址
            jaxWsProxyFactoryBean.setAddress(address);
            //添加用户名密码拦截器
            jaxWsProxyFactoryBean.getOutInterceptors().add(new LoginInterceptor("root","admin"));;
            // 设置接口类型
            jaxWsProxyFactoryBean.setServiceClass(AppService.class);
            // 创建一个代理接口实现
            AppService cs = (AppService) jaxWsProxyFactoryBean.create();
            // 数据准备
            String LineId = "1";
            // 调用代理接口的方法调用并返回结果
            User result = (User)cs.getUser(LineId);
            System.out.println("==============返回结果:" + result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 动态调用方式
     */
    public static void test2() {
        // 创建动态客户端
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Client client = dcf.createClient(address);
        // 需要密码的情况需要加上用户名和密码
         client.getOutInterceptors().add(new LoginInterceptor("root","admin"));
        Object[] objects = new Object[0];
        try {
            // invoke("方法名",参数1,参数2,参数3....);
            System.out.println("======client"+client);
            objects = client.invoke("getUserName", "1");
            System.out.println("返回数据:" + objects[0]);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

————————————————
版权声明:本文为CSDN博主「__sky__」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41138656/article/details/79393366

相关内容

热门资讯

linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
C++ 机房预约系统(六):学... 8、 学生模块 8.1 学生子菜单、登录和注销 实现步骤: 在Student.cpp的...
JAVA多线程知识整理 Java多线程基础 线程的创建和启动 继承Thread类来创建并启动 自定义Thread类的子类&#...
【洛谷 P1090】[NOIP... [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G ...
国民技术LPUART介绍 低功耗通用异步接收器(LPUART) 简介 低功耗通用异步收发器...
城乡供水一体化平台-助力乡村振... 城乡供水一体化管理系统建设方案 城乡供水一体化管理系统是运用云计算、大数据等信息化手段࿰...
程序的循环结构和random库...   第三个参数就是步长     引入文件时记得指明字符格式,否则读入不了 ...
中国版ChatGPT在哪些方面... 目录 一、中国巨大的市场需求 二、中国企业加速创新 三、中国的人工智能发展 四、企业愿景的推进 五、...
报名开启 | 共赴一场 Flu... 2023 年 1 月 25 日,Flutter Forward 大会在肯尼亚首都内罗毕...
汇编00-MASM 和 Vis... Qt源码解析 索引 汇编逆向--- MASM 和 Visual Studio入门 前提知识ÿ...
【简陋Web应用3】实现人脸比... 文章目录🍉 前情提要🌷 效果演示🥝 实现过程1. u...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
windows安装JDK步骤 一、 下载JDK安装包 下载地址:https://www.oracle.com/jav...
分治法实现合并排序(归并排序)... 🎊【数据结构与算法】专题正在持续更新中,各种数据结构的创建原理与运用✨...
在linux上安装配置node... 目录前言1,关于nodejs2,配置环境变量3,总结 前言...
Linux学习之端口、网络协议... 端口:设备与外界通讯交流的出口 网络协议:   网络协议是指计算机通信网...
Linux内核进程管理并发同步... 并发同步并发 是指在某一时间段内能够处理多个任务的能力,而 并行 是指同一时间能够处理...
opencv学习-HOG LO... 目录1. HOG(Histogram of Oriented Gradients,方向梯度直方图)1...
EEG微状态的功能意义 导读大脑的瞬时全局功能状态反映在其电场结构上。聚类分析方法一致地提取了四种头表面脑电场结构ÿ...
【Unity 手写PBR】Bu... 写在前面 前期积累: GAMES101作业7提高-实现微表面模型你需要了解的知识 【技...