JAX-WS:クライアントサイドのSOAPハンドラ
これは、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ハンドラのテストクライアント側とサーバー側]。