我都面臨着同樣的問題,最後我們使用了Apache CXF庫創建客戶端,並寫了一些攔截它。在我們的例子中,Web服務具有身份驗證頭,並啓用了X509。以下代碼適用於我,我與您分享:
要離線生成Web服務客戶端,可以將wsdl的xml保存在本地計算機中,然後使用wsconsume/wsdl2java命令創建存根。
在下面的代碼中,如果在SOAP Header中沒有爲Web服務 設置userName和pwd,則可以跳過addSoapHeader部分。
TestClient.java:-
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.xml.bind.JAXBException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import javax.xml.ws.soap.AddressingFeature;
import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.headers.Header;
import org.apache.cxf.jaxb.JAXBDataBinding;
import org.apache.cxf.ws.addressing.AddressingProperties;
import org.apache.cxf.ws.addressing.AttributedURIType;
import org.apache.cxf.ws.addressing.EndpointReferenceType;
import org.apache.cxf.ws.addressing.VersionTransformer;
import org.apache.cxf.ws.addressing.impl.AddressingPropertiesImpl;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.handler.WSHandlerConstants;
import com.icbase.tsamplex509.ArrayOfDetailLineItem;
import com.icbase.tsamplex509.ArrayOfInventoryLineItem;
import com.icbase.tsamplex509.AuthHeader;
import com.icbase.tsamplex509.CompleteInventory;
import com.icbase.tsamplex509.DetailLineItem;
import com.icbase.tsamplex509.InventoryLineItem;
import com.icbase.tsamplex509.OrderAdd;
import com.icbase.tsamplex509.OrderStatus;
import com.icbase.tsamplex509.ResultMessage;
import com.icbase.tsamplex509.Service;
import com.icbase.tsamplex509.ServiceSoap;
import com.st.passport.PassportWebServiceHandler;
import com.st.passport.UserInfo;
import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;
public class TestClient
{
private static String proxyUser = "javaMagician";
private static String proxyPassword = "myProxyPws";
private static String proxyHost = "sxf4.dlh.ts.com";
private static String proxyPort = "8080";
private static String wsURL = "http://www.wsdoamin.com/tssamplex509/service.asmx?WSDL";
public static void main(String[] args) throws MalformedURLException, Exception
{
Authenticator.setDefault(new ANSAuthenticationHandler(proxyUser,proxyPassword));
System.getProperties().put("http.proxyHost", proxyHost);
System.getProperties().put("http.proxyPort", proxyPort);
Service service = new Service(new URL(wsURL),new QName("http://www.wsdoamin.com/tssamplex509/", "Service"));
ServiceSoap port = service.getServiceSoap(new AddressingFeature(true,true));
Client client = ClientProxy.getClient(port);
enableWSAddressing(client);
enableWsSecurity(client);
addSOAPHeader(client);
System.out.println("Invoking Web Service ...");
//Calling First Web service
CompleteInventory getProductResponse = port.getproduct("*");
System.out.println("Result :: " + getProductResponse.getResultMessage().getResult().name());
System.out.println("Return Message :: " + getProductResponse.getResultMessage().getMessage());
System.out.println("------------------- Inventory -------------------");
}
private static void enableWSAddressing(Client client) {
AddressingProperties maps = new AddressingPropertiesImpl();
EndpointReferenceType ref = new EndpointReferenceType();
AttributedURIType add = new AttributedURIType();
add.setValue("http://www.wsdoamin.com/tssamplex509/getproduct");
ref.setAddress(add);
maps.setReplyTo(ref);
maps.setFaultTo(ref);
maps.exposeAs(VersionTransformer.Names200408.WSA_NAMESPACE_NAME);
client.getRequestContext().put("javax.xml.ws.addressing.context", maps);
}
private static void enableWsSecurity(Client client) {
Properties properties = new Properties();
properties.put("org.apache.ws.security.crypto.provider","org.apache.ws.security.components.crypto.Merlin");
properties.put("org.apache.ws.security.crypto.merlin.keystore.type","jks");
properties.put("org.apache.ws.security.crypto.merlin.keystore.password","changeit");
properties.put("org.apache.ws.security.crypto.merlin.keystore.alias","ts_p&s_ws");
properties.put("org.apache.ws.security.crypto.merlin.file", "cert/TS_P&S_WS.jks");
Map<String, Object> outProps = new HashMap<String, Object>();
outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE);
outProps.put(WSHandlerConstants.USER, "ts_p&s_ws");
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,ANSAuthenticationHandler.class.getName());
outProps.put("cryptoProperties", properties);
outProps.put(WSHandlerConstants.SIG_PROP_REF_ID,"cryptoProperties");
outProps.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
client.getEndpoint().getOutInterceptors().add(new WSS4JOutInterceptor(outProps));
client.getEndpoint().getOutInterceptors().add(new org.apache.cxf.interceptor.LoggingOutInterceptor());
client.getEndpoint().getInInterceptors().add(new org.apache.cxf.interceptor.LoggingInInterceptor());
}
private static void addSOAPHeader(Client client) throws JAXBException {
List<Header> headers = new ArrayList<Header>();
AuthHeader authHeader = new AuthHeader();
authHeader.setUsername("ts");
authHeader.setPassword("46u43242bw3670");
SoapHeader tokenHeader = new SoapHeader(new QName("http://www.wsdoamin.com/tssamplex509", "AuthHeader"), authHeader,new JAXBDataBinding(AuthHeader.class));
headers.add(tokenHeader);
client.getRequestContext().put(Header.HEADER_LIST, headers);
}
}
ANSAuthenticationHandler.java
import java.io.IOException;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class ANSAuthenticationHandler extends Authenticator implements CallbackHandler {
private String proxyUser;
private String proxyPassword;
public ANSAuthenticationHandler() {
super();
}
public ANSAuthenticationHandler(String proxyUser, String proxyPassword) {
super();
this.proxyUser = proxyUser;
this.proxyPassword = proxyPassword;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
{
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
System.err.println("CallbackHandler providing password for :: "+pc.getIdentifier());
if ("ts_p&s_ws".equals(pc.getIdentifier())) {
pc.setPassword("changeit");
}
}
public PasswordAuthentication getPasswordAuthentication()
{
System.err.println("Feeding username and password for ["+getRequestingPrompt()+"] to ["+getRequestingHost()+":"+getRequestingPort()+"] for ["+getRequestingScheme()+"] scheme");
return (new PasswordAuthentication(proxyUser, proxyPassword.toCharArray()));
}
}