これは、JAX-WS SOAPハンドラのパート2です。前の記事のリンク://webservices/jax-ws/jax-ws-soap-handler-in-server-side/[JAX-WS:
サーバサイドのSOAPハンドラ]では、Webサービスを作成し、受信したSOAPメッセージごとにヘッダブロック内のクライアントMACアドレスを取得するハンドラをアタッチしました。
クライアントサイドのSOAPハンドラ
この記事では、webservices/jax-ws/jax-ws-soap-handler-in-server-side/[前の記事]で公開されたサービスにアクセスするためのWebサービスクライアントを開発し、ハンドラを添付しますクライアント側から送信されるすべての送信SOAPメッセージに対して、クライアントのMACアドレスをヘッダーブロックに挿入します。
この例のディレクトリ構造
1. Webサービスクライアント
C:\>wsimport -keep -verbose http://localhost:8888/ws/server?wsdl parsing WSDL... generating code... com\mkyong\ws\GetServerName.java com\mkyong\ws\GetServerNameResponse.java com\mkyong\ws\ObjectFactory.java com\mkyong\ws\ServerInfo.java com\mkyong\ws\ServerInfoService.java com\mkyong\ws\package-info.java
6つのファイルが自動的に生成されますが、 `ServerInfoService.java`だけを気にする必要があります。
ファイル:Server Info Service.java
@WebServiceClient(name = "ServerInfoService",
targetNamespace = "http://ws.mkyong.com/",
wsdlLocation = "http://localhost:8888/ws/server?wsdl")
public class ServerInfoService extends Service
{
//......
}
公開されたサービスにアクセスするクライアント。 +
File:WsClient.java
package com.mkyong.client;
import com.mkyong.ws.ServerInfo;
import com.mkyong.ws.ServerInfoService;
public class WsClient{
public static void main(String[]args) throws Exception {
ServerInfoService sis = new ServerInfoService();
ServerInfo si = sis.getServerInfoPort();
System.out.println(si.getServerName());
}
}
2. SOAPハンドラ
送信SOAPメッセージごとに、クライアントのMACアドレスをSOAPヘッダーブロックに挿入するSOAPハンドラーを作成します。コードの説明については、コメントを参照してください。
File:MacAddressInjectHandler.java
package com.mkyong.handler;
import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
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;
public class MacAddressInjectHandler implements SOAPHandler<SOAPMessageContext>{
@Override
public boolean handleMessage(SOAPMessageContext context) {
System.out.println("Client : handleMessage()......");
Boolean isRequest = (Boolean) context.get(MessageContext.MESSAGE__OUTBOUND__PROPERTY);
//if this is a request, 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();
}
//get mac address
String mac = getMACAddress();
//add a soap header, name as "mac address"
QName qname = new QName("http://ws.mkyong.com/", "macAddress");
SOAPHeaderElement soapHeaderElement = soapHeader.addHeaderElement(qname);
soapHeaderElement.setActor(SOAPConstants.URI__SOAP__ACTOR__NEXT);
soapHeaderElement.addTextNode(mac);
soapMsg.saveChanges();
//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("Client : handleFault()......");
return true;
}
@Override
public void close(MessageContext context) {
System.out.println("Client : close()......");
}
@Override
public Set<QName> getHeaders() {
System.out.println("Client : getHeaders()......");
return null;
}
//return current client mac address
private String getMACAddress(){
InetAddress ip;
StringBuilder sb = new StringBuilder();
try {
ip = InetAddress.getLocalHost();
System.out.println("Current IP address : " + ip.getHostAddress());
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
byte[]mac = network.getHardwareAddress();
System.out.print("Current MAC address : ");
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
}
System.out.println(sb.toString());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e){
e.printStackTrace();
}
return sb.toString();
}
}
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.MacAddressInjectHandler</javaee:handler-class>
</javaee:handler>
</javaee:handler-chain>
</javaee:handler-chains>
4. SOAPハンドラ – > Webサービスクライアントを添付します.
上記のSOAPハンドラをWebサービスクライアントに接続するには、(ServerInfoService.java)ファイル(wsimport経由で生成)を編集し、
@ HandlerChain
で注釈をつけ、SOAPハンドラファイル名を内部で指定します。
File:ServerInfoService.java
@WebServiceClient(name = "ServerInfoService",
targetNamespace = "http://ws.mkyong.com/",
wsdlLocation = "http://localhost:8888/ws/server?wsdl")
@HandlerChain(file="handler-chain.xml")
public class ServerInfoService extends Service
{
//......
}
完了したら、次の記事に進んでください://webservices/jax-ws/jax-ws-soap-handler-testing-for-client-and-server-side/[パート3:JAX-WS-SOAPハンドラのテストクライアント側とサーバー側]。