一、需求分析

  • 客户端在调用服务端的方法时,需要进行用户名和密码验证。此时分为:
  1. 客户端请求的时候,要发送用户名密码到服务端
  2. 服务端检验用户名密码。

二、案例

  • 前提:本章案例是基于前一章节的例子进一步讲解自定义拦截器

  2.1  服务端

  • 发布服务
ublic class PublishMain {
public static void main(String[] args) { String address="http://localhost:3333/login";
JaxWsServerFactoryBean factoryBean=new JaxWsServerFactoryBean();
factoryBean.setAddress(address);
factoryBean.setServiceClass(ILogin.class);
factoryBean.setServiceBean(new Login());
/**
* // 添加in拦截器 日志拦截器
* // 添加out拦截器 日志拦截器
*/
factoryBean.getInInterceptors().add(new LoggingInInterceptor());// 添加in拦截器 日志拦截器
factoryBean.getOutInterceptors().add(new LoggingOutInterceptor()); 添加out拦截器 日志拦截器
/**
* 添加自定义拦截器,验证客户端发送的用户名和密码
*/
factoryBean.getInInterceptors().add(new MyLoginInteceptor()); factoryBean.create();
System.out.println("服务发布......."); }
}
  • factoryBean.getInInterceptors().add(new MyLoginInteceptor());   在接收SOAP消息的时候,会执行LoggingInInterceptor日志拦截器和

    自定义的 MyLoginInteceptor拦截器,该拦截器用于验证soap消息中的用户名和密码的合法性。

  • 编写自定义的拦截器类

package com.shyroke.interceptor;

import java.util.List;

import javax.xml.namespace.QName;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList; public class MyLoginInteceptor extends AbstractPhaseInterceptor<SoapMessage> { public MyLoginInteceptor() {
/**
* Phase.PRE_INVOKE 在调用方法之前调用自定拦截器
*/
super(Phase.PRE_INVOKE); } @SuppressWarnings("null")
public void handleMessage(SoapMessage message) throws Fault { List<Header> headers = message.getHeaders();
if (headers == null && headers.size() == 0) {
throw new Fault(new IllegalArgumentException("没有Header,拦截器实施拦截"));
} Header header = headers.get(0); Element ele = (Element) header.getObject();
NodeList uList = ele.getElementsByTagName("userName");
NodeList pList = ele.getElementsByTagName("passWord"); if (uList.getLength() != 1) {
throw new Fault(new IllegalArgumentException("用户名格式不对"));
}
if (pList.getLength() != 1) {
throw new Fault(new IllegalArgumentException("密码格式不对"));
} String userName = uList.item(0).getTextContent();
String passWord = pList.item(0).getTextContent(); if (!userName.equals("admin") || !passWord.equals("123")) {
throw new Fault(new IllegalArgumentException("用户名或者密码错误!"));
} } }
  • 其他代码与上一章节相同,本文省略。

  2.2  客户端

  • client.java
package com.shyroke.service;

import java.util.List;

import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor; import com.shyroke.interceptor.MyHeaderInterceptor; public class Client {
public static void main(String[] args) {
ILogin login=new ILoginService().getILoginPort(); org.apache.cxf.endpoint.Client client=ClientProxy.getClient(login); /**
* LoggingInInterceptor该拦截器类会在客户端被调用前打印日志
* LoggingOutInterceptor该拦截器类会在客户端被调用后打印日志
*/
client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor()); /**
* 客户端请求服务端的方法的时候要先加用户名密码以供服务端验证
*/
client.getOutInterceptors().add(new MyHeaderInterceptor("admin1","123")); MyRoleArray roles=login.getRoles();
List<MyRole> roleList= roles.item;
for(MyRole role:roleList) {
System.out.println(role.getKey());
for(Role r:role.getValue()) {
System.out.println(r.getId()+"\t"+r.getRoleName());
}
System.out.println("------------------");
}
}
}
  • client.getOutInterceptors().add(new MyHeaderInterceptor("admin1","123"))  客户端在请求服务单的方法时,会发送SOAP消息,就会先执行MyHeaderInterceptor

日志拦截器和自定义拦截器MyHeaderInterceptor,该拦截器用于发送在发送的SOAP消息中添加用户名密码等验证信息,以供服务端接收并验证。

  • MyHeaderInterceptor.java
package com.shyroke.interceptor;

import java.util.List;

import javax.xml.namespace.QName;

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; public class MyHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage> { private String userName;
private String passWord; public MyHeaderInterceptor(String userName, String passWord) {
/**
* Phase.PREPARE_SEND 准备发送SOAP消息的时候调用拦截器
*/
super(Phase.PREPARE_SEND);
this.userName = userName;
this.passWord = passWord;
} public void handleMessage(SoapMessage message) throws Fault { List<Header> headerList = message.getHeaders(); Document doc = DOMUtils.createDocument();
Element ele = doc.createElement("LoginHeader");
Element uElement = doc.createElement("userName");
uElement.setTextContent(userName); Element pElement = doc.createElement("passWord");
pElement.setTextContent(passWord); ele.appendChild(uElement);
ele.appendChild(pElement); headerList.add(new Header(new QName("http://com.shyroke"), ele)); } }
  • 结果:

  • 可知,服务端拦截器是生效的。

服务端代码在: 点击

客户端代码在: 点击

(六)CXF之自定义拦截器的更多相关文章

  1. CXF之六 自定义拦截器

    CXF已经内置了一些拦截器,这些拦截器大部分默认添加到拦截器链中,有些拦截器也可以手动添加,如手动添加CXF提供的日志拦截器.也可以自定义拦截器,CXF中实现自定义拦截器很简单,只要继承Abstrac ...

  2. Apache CXF自定义拦截器

    为什么设计拦截器?1.为了在webservice请求过程中,能动态操作请求和响应数据,CXF设计了拦截器 拦截器分类: 1.按所处的位置分:服务器端拦截器,客户端拦截器. 2.按消息的方向分:入拦截器 ...

  3. CXF添加拦截器和自定义拦截器

    前面讲了如何采用CXF开发webservice,现在来讲如何添加拦截器和自定义拦截器. 服务端代码: HelloWorld implementor=new HelloWorldImpl(); Stri ...

  4. Spring Mvc 的自定义拦截器

     spring mvc的拦截器 SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户 ...

  5. (六)Struts2的拦截器

    一.简介 拦截器体系是struts2重要的组成部分.正是大量的内建拦截器完成了该框架的大部分操作. 比如params拦截器将请求参数解析出来,设置Action的属性.servletConfig拦截器负 ...

  6. spring mvc <mvc:annotation-driven/> 自定义拦截器不走

    <mvc:annotation-driven/> 这个便签会注册2个自定义拦截器,所以导致请求过来就会自己去走注册的这2个拦截器和定义的一堆bean 但是这个便签是必须得定义的 直接贴代码 ...

  7. 12.Struts2自定义拦截器

    12.自定义拦截器        拦截器是Struts2的一个重要特性.因为Struts2的大多数核心功能都是通过拦截器实现的. 拦截器之所以称之为“拦截器”,是因为它可以拦截Action方法的执行, ...

  8. 【Java EE 学习 35 下】【struts2】【struts2文件上传】【struts2自定义拦截器】【struts2手动验证】

    一.struts2文件上传 1.上传文件的时候要求必须使得表单的enctype属性设置为multipart/form-data,把它的method属性设置为post 2.上传单个文件的时候需要在Act ...

  9. SpringMVC——自定义拦截器、异常处理以及父子容器配置

    自定义拦截器: 一.若想实现自定义拦截器,需要实现 org.springframework.web.servlet.HandlerInterceptor 接口. 二.HandlerIntercepto ...

随机推荐

  1. Python-文件读写及修改

    文件的读写有三种形式:读.写和追加. 一.读模式 r 和读写模式 r+ 1.读模式 r 读模式r特点:(1)只能读,不能写:(2)文件不存在时会报错. (1)例:读取当前目录下的books.txt文件 ...

  2. Team团队管理执行力

    执行力是什么_百度知道https://zhidao.baidu.com/question/144991863.html [图文]如何提高团队执行力 - 百度文库https://wenku.baidu. ...

  3. nginx限制流量

    location /download/ { limit_rate_after 5m; limit_rate 1m; alias /data/html/; }

  4. 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_08-用户认证-认证服务查询数据库-用户登录前端

    点击登陆注册链接 跳转到登陆的页面 门户的前端代码 当前路径base64编码 登陆的表单,在学习中心的前端. 这就是登陆的表单 这是表单的校验 请求服务端的接口 登陆请求的方法 请求的地址nginx上 ...

  5. Harbor 1.8.0 仓库的安装和使用

    安装的先决条件 硬件环境 1.CPU    至少2G,最好4G 2.内存    至少4G,最好8G 3.磁盘    至少40G,最好160G 软件环境 1.docker版本    17.03.0-ce ...

  6. linuxan安装redis出现Newer version of jemalloc required错误

    linux安装redis执行make命令时出现问题 解决方法 make MALLOC=libc 如果要指定安装文件夹 使用命令:make PREFIX  = /usr/local/redis(文件夹路 ...

  7. 取用户中文名 FDM_CUST_USER_NAME_READ_SINGLE

    DATA:lv_first TYPE ad_namefir,      lv_last  TYPE ad_namelas,      lv_full  TYPE ad_namtext.   CALL  ...

  8. RocketMQ共包含9个模块

    rocketmq-common:通用的枚举.基类方法.或者数据结构,包名有admin.consumer.filter.hook.message rocketmq-remoting:使用netty的客户 ...

  9. 设置Android模拟器的窗口大小

    Android SDK 中两个位置可以设置Android模拟器的窗口大小 1.设置Android模拟器的分辨率 Android Virtual Device Manager中创建AVD时,窗口中部Re ...

  10. jsplumb 流程图,常用功能配置记录

    前言: jsplumb 有2个版本一个Toolkit Edition(付费版),另外一个就是Community Edition(社区版本).Toolkit Edition版本功能集成的比较丰富,社区版 ...