天天看點

jax-ws 處理webservice

package org.ticket.adpt.tsp.service.common;

import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;

public class SOAPClient {

	private Dispatch<SOAPMessage> dispatch;
	private MessageFactory factory;

	// 基礎配置
	private String wsdlLocation;
	private String targetNamespace;
	private String serviceName;
	private String portName;
	private String bindingType;

	/**
	 * 建立用戶端對象基礎構造函數
	 * 
	 * @param wsdlLocation
	 *            wsdl位址
	 * @param targetNamespace
	 *            命名空間
	 * @param serviceName
	 *            服務名:wsdl裡service節點的name屬性
	 * @param portName
	 *            端口名 wsdl裡service下的其中一個port名字,一般類似xxxxHttpSoap12Endpoint
	 * @param bindingType
	 *            SOAP版本,常見值SOAP11HTTP_BINDING、SOAP12HTTP_BINDING
	 */
	public SOAPClient(String wsdlLocation, String targetNamespace, String serviceName, String portName, String bindingType) {
		this.wsdlLocation = wsdlLocation;
		this.targetNamespace = targetNamespace;
		this.serviceName = serviceName;
		this.portName = portName;
		this.bindingType = bindingType;

		// 初始化
		QName portQName = new QName(targetNamespace, this.portName);
		QName serviceQName = new QName(targetNamespace, this.serviceName);

		// 通過服務名對象建立服務對象
		javax.xml.ws.Service service = Service.create(serviceQName);
		// 向服務上添加一個新的端口
		service.addPort(portQName, this.bindingType, this.wsdlLocation);
		// 建立一個分發執行個體
		dispatch = service.createDispatch(portQName, SOAPMessage.class, Service.Mode.MESSAGE);
		BindingProvider bp = (BindingProvider) dispatch;
		factory = ((SOAPBinding) bp.getBinding()).getMessageFactory();
	}

	/**
	 * 建立用戶端
	 * 
	 * @param wsdlLocation
	 *            wsdl位址
	 * @param targetNamespace
	 *            命名空間
	 * @param serviceName
	 *            服務名:wsdl裡service節點的name屬性
	 * @param portName
	 *            端口名 wsdl裡service下的其中一個port名字,一般類似xxxxHttpSoap1xEndpoint
	 */
	public SOAPClient(String wsdlLocation, String targetNamespace, String serviceName, String portName) {
		this(wsdlLocation, targetNamespace, serviceName, portName, SOAPBinding.SOAP11HTTP_BINDING);
	}

	public String call(String action, Map<String, String> params) throws SOAPException {
		SOAPMessage request = factory.createMessage();
		
		SOAPEnvelope envelope = request.getSOAPPart().getEnvelope();
		envelope.addNamespaceDeclaration("soap", targetNamespace);
		
		SOAPBody body = request.getSOAPBody();
		QName payloadName = new QName(targetNamespace, action,"soap");
		SOAPBodyElement payload = body.addBodyElement(payloadName);

		// 請求參數
		for (String key : params.keySet()) {
			String value = params.get(key) == null ? "" : params.get(key);
			payload.addChildElement(key).addTextNode(value);
		}

		SOAPMessage reply = dispatch.invoke(request);

		SOAPBody soapBody = reply.getSOAPBody();
		SOAPBodyElement nextSoapBodyElement = (SOAPBodyElement) soapBody.getChildElements().next();
		SOAPElement soapElement = (SOAPElement) nextSoapBodyElement.getChildElements().next();

		return soapElement.getValue();
	}
}
           

配置檔案:

# service config
service.pAppCode=SGWUSER
service.pVerifyKey=e10adc3949ba59abbe56e057f20f883e
service.namesapce=http://soap.ws.tsp.oristartech.com/
service.service.name=TspSoapServiceImplService
service.port.name=TspSoapServiceImplPort
service.wsdl.location=http://121.32.27.26:18080/tsp-ws/services/tsp/cinema
           
package org.ticket.adpt.tsp.service.common;

import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.ws.soap.SOAPBinding;

import mtime.lark.util.config.AppConfig;
import mtime.lark.util.config.SettingMap;
import mtime.lark.util.lang.FaultException;
import mtime.lark.util.log.Logger;
import mtime.lark.util.log.LoggerManager;
import mtime.lark.util.security.EncryptUtil;

/**
 * TSP(中鑫彙科)API工具類
 *
 * @author zhangyongzhou
 */
public class TspUtils {

	private static final Logger log = LoggerManager.getLogger("TspApi");

	private static SOAPClient client;
	private static String pAppCode;
	private static String pVerifyKey;

	static {
		init();
	}

	public static void init() {
		// 初始化SOAP用戶端
		SettingMap custom = AppConfig.getDefault().getCustom();
		String wsdlLocation = custom.getString("service_wsdl_location");
		String serviceNamesapce = custom.getString("service_namesapce");
		String serviceName = custom.getString("service_name");
		String servicePort = custom.getString("service_port_name");
		client = new SOAPClient(wsdlLocation, serviceNamesapce, serviceName, servicePort);

		// 應用編碼和驗證密鑰
		pAppCode = custom.getString("service_pAppCode");
		pVerifyKey = custom.getString("service_pVerifyKey");
	}

	@SuppressWarnings("unchecked")
	public static <T> T getResponse(String action, Map<String, String> params, Class<T> clazz) {
		T response = null;
		String data = "";
		String exMsg = "";
		try {
			data = client.call(action, params);
		} catch (Exception ex) {
			// 記錄請求日志(異常),異常的情況,抛給上層還會有記錄
			exMsg = ex.getMessage();
			throw new FaultException("TSP(中鑫彙科)API請求異常,action=" + action, ex);
		} finally {
			log.info("request:#:{}*#*method:#:{}*#*charset:#:{}*#*response:#:{}*#*exception:#:{}",
					action + ":" + params, "POST", "UTF-8", data, exMsg);
		}

		try {
			// 解析xml->對象
			JAXBContext context = JAXBContext.newInstance(clazz);
			Unmarshaller unmarshaller = context.createUnmarshaller();
			response = (T) unmarshaller.unmarshal(new StringReader(data));
		} catch (Exception ex) {
			throw new FaultException(MessageFormat.format("TSP(中鑫彙科)API解析資料異常,action:{0},data:{1}", action, data), ex);
		}
		return response;
	}
	
	/**
	 * 擷取應用編碼
	 * @return
	 */
	public static String getAppCode(){
		return TspUtils.pAppCode;
	}

	/**
	 * 擷取校驗資訊
	 * 
	 * @param params
	 * @return
	 */
	public static String getVerifyInfo(String ... params) {
		StringBuffer sb = new StringBuffer("");
		String result = null;
		for(String param : params){
			try {
				sb.append(new String(param.getBytes("UTF-8")));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		result = EncryptUtil.md5((pAppCode + "" + sb.toString() + "" + pVerifyKey).toLowerCase());
		return result;
	}

	/**
	 * 轉換參數
	 * 
	 * @param params
	 * @return
	 */
	public static Map<String, String> convertParams(Map<String, String> params) {
		Map<String, String> newParams = new LinkedHashMap<>();
		newParams.put("pAppCode", pAppCode);
		newParams.putAll(params);
		StringBuffer sb = new StringBuffer("");
		for (String dataKey : params.keySet()) {
			try {
				sb.append(new String(params.get(dataKey).getBytes("UTF-8")));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		String str = pAppCode + "" + sb.toString() + "" + pVerifyKey;
		newParams.put("pVerifyInfo", EncryptUtil.md5(str.toLowerCase()));
		return newParams;
	}

}