JAX-WS:服务器端的SOAP处理程序

本文介绍了如何在JAX-WS中创建和使用服务器端SOAP处理程序,用于从传入的消息中提取并验证SOAP头中的MAC地址。通过示例展示了SOAP处理程序的实现,包括Web服务接口、SOAP处理程序类、处理程序XML配置以及如何将处理程序附加到Web服务上。文章还提供了源代码下载以供进一步学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SOAP处理程序是SOAP消息拦截器,它能够拦截传入或传出的SOAP消息并操纵其值。 例如,在客户端附加一个SOAP处理程序,它将为客户端发送的每个传出SOAP消息将客户端的计算机MAC地址注入SOAP标头块。 在服务器端,附加另一个SOAP处理程序,以从每个传入的SOAP消息中检索回SOAP标头块中的客户端MAC地址。 这样服务器端就可以确定允许哪台计算机访问已发布的服务。

本文分为三个部分:

  1. JAX-WS:服务器端的SOAP处理程序。 (本文)
  2. JAX-WS:客户端中的SOAP处理程序
  3. JAX-WS:针对客户端和服务器端的SOAP处理程序测试

服务器端的SOAP处理程序

在本文中,我们向您展示如何创建SOAP处理程序并将其附加到服务器端,以从每个传入的SOAP消息中检索SOAP标头块中的mac地址。 并进行验证以仅允许MAC地址为“ 90-4C-E5-44-B9-8F ”的计算机访问此发布的服务。 如果无效的客户端尝试访问服务,则将SOAPFaultException返回给客户端。

本示例的目录结构

1. Web服务

一个简单的Web服务,带有getServerName()方法以返回字符串。

文件:ServerInfo.java

package com.mkyong.ws;

import javax.jws.HandlerChain;
import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
public class ServerInfo{

	@WebMethod
	public String getServerName() {
		
		return "mkyong server";
		
	}

}

生成Web服务部署所需的Java文件。

D:\workspace-new\WebServices\bin>wsgen -keep -verbose -cp . com.mkyong.ws.ServerInfo
Note:   ap round: 1
...
com\mkyong\ws\jaxws\GetServerName.java
com\mkyong\ws\jaxws\GetServerNameResponse.java
Note:   ap round: 2

生成两个文件:

  1. com \ mkyong \ ws \ jaxws \ GetServerName.java
  2. com \ mkyong \ ws \ jaxws \ GetServerNameResponse.java

文件:GetServerName.java

package com.mkyong.ws.jaxws;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "getServerName", namespace = "http://ws.mkyong.com/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getServerName", namespace = "http://ws.mkyong.com/")
public class GetServerName {
}

文件:GetServerNameResponse.java

package com.mkyong.ws.jaxws;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "getServerNameResponse", namespace = "http://ws.mkyong.com/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getServerNameResponse", namespace = "http://ws.mkyong.com/")
public class GetServerNameResponse {

    @XmlElement(name = "return", namespace = "")
    private String _return;

    /**
     * 
     * @return
     *     returns String
     */
    public String getReturn() {
        return this._return;
    }

    /**
     * 
     * @param _return
     *     the value for the _return property
     */
    public void setReturn(String _return) {
        this._return = _return;
    }

}

2. SOAP处理程序

对于每个传入的SOAP消息,创建一个SOAP处理程序以检索SOAP标头块中的值。 有关代码说明,请参见注释。

文件MacAddressValidatorHandler.java

package com.mkyong.handler;

import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import javax.xml.ws.soap.SOAPFaultException;

public class MacAddressValidatorHandler implements SOAPHandler<SOAPMessageContext>{

   @Override
   public boolean handleMessage(SOAPMessageContext context) {

	System.out.println("Server : handleMessage()......");
		
	Boolean isRequest = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

	//for response message only, true for outbound messages, false for inbound
	if(!isRequest){
			
	try{
	    SOAPMessage soapMsg = context.getMessage();
	    SOAPEnvelope soapEnv = soapMsg.getSOAPPart().getEnvelope();
            SOAPHeader soapHeader = soapEnv.getHeader();
	            
            //if no header, add one
	    if (soapHeader == null){
	            soapHeader = soapEnv.addHeader();
	            //throw exception
	            generateSOAPErrMessage(soapMsg, "No SOAP header.");
	     }

             //Get client mac address from SOAP header
	     Iterator it = soapHeader.extractHeaderElements(SOAPConstants.URI_SOAP_ACTOR_NEXT);
	            
	     //if no header block for next actor found? throw exception
	     if (it == null || !it.hasNext()){
	      	generateSOAPErrMessage(soapMsg, "No header block for next actor.");
             }
	            
	     //if no mac address found? throw exception
	     Node macNode = (Node) it.next();
	     String macValue = (macNode == null) ? null : macNode.getValue();
	          
	      if (macValue == null){
	      	  generateSOAPErrMessage(soapMsg, "No mac address in header block.");
	      }

	       //if mac address is not match, throw exception
	       if(!macValue.equals("90-4C-E5-44-B9-8F")){
	       	   generateSOAPErrMessage(soapMsg, "Invalid mac address, access is denied.");
	       }
	            
	       //tracking
	       soapMsg.writeTo(System.out);

		}catch(SOAPException e){
			System.err.println(e);
		}catch(IOException e){
			System.err.println(e);
		}
            
	    }

	  //continue other handler chain
	  return true;
	}

	@Override
	public boolean handleFault(SOAPMessageContext context) {
		
		System.out.println("Server : handleFault()......");
		
		return true;
	}

	@Override
	public void close(MessageContext context) {
		System.out.println("Server : close()......");
	}

	@Override
	public Set<QName> getHeaders() {
		System.out.println("Server : getHeaders()......");
		return null;
	}
	
     private void generateSOAPErrMessage(SOAPMessage msg, String reason) {
       try {
          SOAPBody soapBody = msg.getSOAPPart().getEnvelope().getBody();
          SOAPFault soapFault = soapBody.addFault();
          soapFault.setFaultString(reason);
          throw new SOAPFaultException(soapFault); 
       }
       catch(SOAPException e) { }
    }

}

3. SOAP处理程序XML文件

创建一个SOAP处理程序XML文件,然后放入SOAP处理程序声明。

文件:handler-chain.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<javaee:handler-chains 
     xmlns:javaee="http://java.sun.com/xml/ns/javaee" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <javaee:handler-chain>
    <javaee:handler>
      <javaee:handler-class>com.mkyong.handler.MacAddressValidatorHandler</javaee:handler-class>
    </javaee:handler>
  </javaee:handler-chain>
</javaee:handler-chains>

4.附加SOAP处理程序–> Web服务

要将上面的SOAP处理程序附加到Web服务ServerInfo.java ,只需使用@HandlerChain注释并在其中指定SOAP处理程序文件名即可。

文件:ServerInfo.java

package com.mkyong.ws;

import javax.jws.HandlerChain;
import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
@HandlerChain(file="handler-chain.xml")
public class ServerInfo{

	@WebMethod
	public String getServerName() {
		
		return "mkyong server";
		
	}

}

5. Web服务发布者

一个简单的Web服务发布者进行测试。

package com.mkyong.endpoint;
 
import javax.xml.ws.Endpoint;
import com.mkyong.ws.ServerInfo;

//Endpoint publisher
public class WsPublisher{
 
	public static void main(String[] args) {
	   Endpoint.publish("http://localhost:8888/ws/server", new ServerInfo());
	   
	   System.out.println("Service is published!");
    }
 
}

完成后,请继续下一篇文章– 第2部分:JAX-WS –客户端中的SOAP处理程序

下载源代码

下载它– JAX-WS-Handler-Example.zip (21KB)

翻译自: https://mkyong.com/webservices/jax-ws/jax-ws-soap-handler-in-server-side/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值