Java tutorial
/** * Copyright (C) 2013, Moss Computing Inc. * * This file is part of rpcutil. * * rpcutil is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * rpcutil is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rpcutil; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * Linking this library statically or dynamically with other modules is * making a combined work based on this library. Thus, the terms and * conditions of the GNU General Public License cover the whole * combination. * * As a special exception, the copyright holders of this library give you * permission to link this library with independent modules to produce an * executable, regardless of the license terms of these independent * modules, and to copy and distribute the resulting executable under * terms of your choice, provided that you also meet, for each linked * independent module, the terms and conditions of the license of that * module. An independent module is a module which is not derived from * or based on this library. If you modify this library, you may extend * this exception to your version of the library, but you are not * obligated to do so. If you do not wish to do so, delete this * exception statement from your version. */ package com.moss.rpcutil.proxy.jaxws; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.net.URL; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.namespace.QName; import javax.xml.soap.SOAPMessage; import javax.xml.ws.Service; import javax.xml.ws.handler.Handler; import javax.xml.ws.handler.HandlerResolver; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.PortInfo; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.moss.jaxbhelper.JAXBHelper; import com.moss.rpcutil.proxy.ProxyProvider; public final class JAXWSProxyProvider implements ProxyProvider { private final Log log; private final Map<Class, QName> registry; private final Map<String, Object> cache; public JAXWSProxyProvider() { this.log = LogFactory.getLog(this.getClass()); registry = new HashMap<Class, QName>(); cache = new HashMap<String, Object>(); } public synchronized JAXWSProxyProvider register(Class iface, QName type) { registry.put(iface, type); return this; } public synchronized <T> T getProxy(Class<T> iface, String url) { QName type = registry.get(iface); if (type == null) { throw new RuntimeException("Service type not registered: " + iface); } T proxy = (T) cache.get(url); if (proxy == null) { Service service; try { String wsdlLocation = url; if (!wsdlLocation.endsWith("?wsdl")) { wsdlLocation += "?wsdl"; } service = Service.create(new URL(wsdlLocation), type); } catch (Exception ex) { throw new RuntimeException(ex); } if (log.isDebugEnabled()) { // SOAP LOGGING STUFF service.setHandlerResolver(new HandlerResolver() { public List<Handler> getHandlerChain(PortInfo arg0) { List<Handler> handlers = new LinkedList<Handler>(); handlers.add(new SOAPLoggingHandler(log)); return handlers; } }); } proxy = service.getPort(iface); // BindingProvider bp = (BindingProvider) proxy; // // bp.getRequestContext().put( // MessageContext.HTTP_REQUEST_HEADERS, // Collections.singletonMap("Content-Type", Arrays.asList(new String[]{"application/soap+xml", "charset=utf-8"})) // ); cache.put(url, proxy); } return proxy; } /* * This simple SOAPHandler will output the contents of incoming * and outgoing messages. */ public class SOAPLoggingHandler implements SOAPHandler<SOAPMessageContext> { private Log log; public SOAPLoggingHandler(Log log) { super(); this.log = log; } public Set<QName> getHeaders() { return null; } public boolean handleMessage(SOAPMessageContext smc) { logToSystemOut(smc); return true; } public boolean handleFault(SOAPMessageContext smc) { logToSystemOut(smc); return true; } // nothing to clean up public void close(MessageContext messageContext) { } /* * Check the MESSAGE_OUTBOUND_PROPERTY in the context * to see if this is an outgoing or incoming message. * Write a brief message to the print stream and * output the message. The writeTo() method can throw * SOAPException or IOException */ private void logToSystemOut(SOAPMessageContext smc) { if (!log.isDebugEnabled()) return; try { final Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); final ByteArrayOutputStream messageBytes = new ByteArrayOutputStream(); SOAPMessage message = smc.getMessage(); message.writeTo(messageBytes); messageBytes.close(); new Thread() { @Override public void run() { try { if (outboundProperty.booleanValue()) { log.debug("\nOutbound message:"); } else { log.debug("\nInbound message:"); } ByteArrayOutputStream formattedBytes = new ByteArrayOutputStream(); setPriority(MIN_PRIORITY); JAXBHelper.beautify(new ByteArrayInputStream(messageBytes.toByteArray()), formattedBytes); formattedBytes.close(); log.debug(new String(formattedBytes.toByteArray())); log.debug(""); } catch (Exception e) { throw new RuntimeException(e); } } }.start(); // just to add a newline } catch (Exception e) { log.debug("Exception in handler: " + e); } } } }