web service 自定义拦截器

客户端拦截器:

package com.xh.ws.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 LoginInterceptor extends AbstractPhaseInterceptor<SoapMessage>{

	private String name;
	private String password;
	
	
	public LoginInterceptor() {
		super(Phase.PRE_PROTOCOL);
	}
	
	public LoginInterceptor(String name,String password) {
		super(Phase.PRE_PROTOCOL);
		this.name=name;
		this.password=password;
	
	}

	@Override
	public void handleMessage(SoapMessage arg0) throws Fault {
		/**
		 * 客户端的head
		 * <user>
		 * 		<name>zhangsan</name>
		 * 		<password>zhangsan</password>
		 * </user>
		 * 	
		 */
			List<Header> heads=arg0.getHeaders();
			
			Document document=DOMUtils.createDocument();
			Element rootEle=document.createElement("user");
			Element nameEle=document.createElement("name");
			nameEle.setTextContent(name);
			Element passwordEle=document.createElement("password");
			passwordEle.setTextContent(password);
			rootEle.appendChild(nameEle);
			rootEle.appendChild(passwordEle);
			heads.add(new Header(new QName("user"), rootEle));
			System.out.println("Client:handleMessage().....");
			
	}

}

客户端测试代码:

package com.xh.ws.test;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingOutInterceptor;

import com.xh.ws.interceptor.LoginInterceptor;
import com.xh.ws.sei.SayHello;
import com.xh.ws.sei.SayHelloImplService;

public class ClientTest {

	public static void main(String[] args) {
		SayHelloImplService factory=new SayHelloImplService();
		SayHello hello=factory.getSayHelloImplPort();
		Client client=ClientProxy.getClient(hello);
		//添加自定义拦截器
		client.getOutInterceptors().add(new LoginInterceptor("zhangsan","123456"));
		//添加日志拦截器
		client.getOutInterceptors().add(new LoggingOutInterceptor());
		System.out.println(hello.sayHello("lili"));
	}
}

服务端拦截器:

package com.xh.ws.interceptor;

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;



public class LoginInterceptor extends AbstractPhaseInterceptor<SoapMessage>{

	public LoginInterceptor() {
		super(Phase.PRE_INVOKE);
	}

	@Override
	public void handleMessage(SoapMessage arg0) throws Fault {
		
		Header header=arg0.getHeader(new QName("user"));
		if(header!=null)
		{
			/**
			 * 解析header
			 */
			Element rootEle=(Element) header.getObject();
			Element name=(Element) rootEle.getElementsByTagName("name").item(0);
			Element password=(Element) rootEle.getElementsByTagName("password").item(0);
			String name_1=name.getTextContent();
			String password_1=password.getTextContent();
			
			if("zhangsan".equals(name_1)&&"123456".equals(password_1))
			{
				return;
			}else
			{
				throw new RuntimeException("用户名或密码不正确!");
			}
			
			
			
		}
		
	}

}

服务端测试代码:

package com.xh.ws.test;

import javax.xml.ws.Endpoint;

import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.jaxws.EndpointImpl;

import com.xh.ws.interceptor.LoginInterceptor;
import com.xh.ws.sei.SayHelloImpl;

public class ServerTest {

	public static void main(String[] args) {
		Endpoint endpoint=Endpoint.publish("http://127.0.0.1:54321", new SayHelloImpl());
		EndpointImpl endpointImpl=(EndpointImpl) endpoint;
		//添加自定义拦截器
		endpointImpl.getInInterceptors().add(new LoginInterceptor());
		//添加日志拦截器
		endpointImpl.getInInterceptors().add(new LoggingInInterceptor());
		System.out.println("发布成功");
	}
}


结果:

当正确时:

Client:handleMessage().....
三月 01, 2016 4:14:11 下午 org.apache.cxf.services.SayHelloImplService.SayHelloImplPort.SayHello
信息: Outbound Message
---------------------------
ID: 1
Address: http://127.0.0.1:54321/
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml
Headers: {Accept=[*/*], SOAPAction=[""]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><user><name>zhangsan</name><password>123456</password></user></soap:Header><soap:Body><ns2:sayHello xmlns:ns2="http://sei.ws.xh.com/"><arg0>lili</arg0></ns2:sayHello></soap:Body></soap:Envelope>
--------------------------------------
lili

错误时:

Client:handleMessage().....
三月 01, 2016 4:37:17 下午 org.apache.cxf.services.SayHelloImplService.SayHelloImplPort.SayHello
信息: Outbound Message
---------------------------
ID: 1
Address: http://127.0.0.1:54321/
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml
Headers: {Accept=[*/*], SOAPAction=[""]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><user><name>zhangsan</name><password>1234561</password></user></soap:Header><soap:Body><ns2:sayHello xmlns:ns2="http://sei.ws.xh.com/"><arg0>lili</arg0></ns2:sayHello></soap:Body></soap:Envelope>
--------------------------------------
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: 用户名或密码不正确!
	at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:161)
	at com.sun.proxy.$Proxy34.sayHello(Unknown Source)
	at com.xh.ws.test.ClientTest.main(ClientTest.java:21)
Caused by: org.apache.cxf.binding.soap.SoapFault: 用户名或密码不正确!


相关参考资料:

http://huiseyiyu.iteye.com/blog/1172160




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,我们可以看出这是一个Java Web项目,其中包含了自定义注解和拦截的使用。在Java中,我们可以通过自定义注解和拦截来实现验签功能。具体步骤如下: 1.定义定义注解@Sign,用于标记需要验签的方法或类。 2.定义拦截,在拦截中获取请求参数和签名,并进行验签操作。 下面是一个简单的Java验签示例: ```java // 自定义注解 @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface Sign { } // 拦截 @Component public class SignInterceptor implements HandlerInterceptor { @Autowired private SignService signService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 判断是否有@Sign注解 if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; Sign sign = handlerMethod.getMethodAnnotation(Sign.class); if (sign == null) { sign = handlerMethod.getBeanType().getAnnotation(Sign.class); } if (sign != null) { // 获取请求参数和签名 Map<String, String[]> parameterMap = request.getParameterMap(); String signValue = request.getHeader("sign"); // 验签 boolean verifyResult = signService.verifySign(parameterMap, signValue); if (!verifyResult) { // 验签失败,返回错误信息 response.setContentType("application/json;charset=UTF-8"); response.getWriter().write("{\"code\":400,\"msg\":\"验签失败\"}"); return false; } } } return true; } } // 验签服务 @Service public class SignService { // 验签密钥 private static final String SIGN_KEY = "123456"; /** * 验签 * * @param parameterMap 请求参数 * @param signValue 签名 * @return 验签结果 */ public boolean verifySign(Map<String, String[]> parameterMap, String signValue) { // 将请求参数按照字典序排序并拼接成字符串 StringBuilder sb = new StringBuilder(); parameterMap.keySet().stream().sorted().forEach(key -> { String[] values = parameterMap.get(key); Arrays.sort(values); sb.append(key).append("=").append(values[0]).append("&"); }); sb.append("key=").append(SIGN_KEY); // 计算签名 String sign = DigestUtils.md5Hex(sb.toString()); // 验证签名 return StringUtils.equals(sign, signValue); } } // 控制 @RestController public class TestController { @Autowired private SignService signService; @PostMapping("/test") @Sign public ResponseBody<AuthCodeJson> getAuthCode(@CurrentUser UserInfo userInfo) { System.out.println(userInfo.getId()); System.out.println(ThreadContextHolder.getUserInfo().getUserId()); return this.success(); } } ``` 在上面的示例中,我们定义了一个自定义注解@Sign,用于标记需要验签的方法或类。然后定义了一个拦截SignInterceptor,在拦截中获取请求参数和签名,并进行验签操作。最后,在控制TestController中使用@Sign注解标记了需要验签的方法getAuthCode。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值