Due to project needs, I picked up the webservice I used before and chose to use Java native Jaxws that does not require jar packages. First, the usage of wsimport is shared first: go to the path where the project is located under cmd, and then run the following command
The code copy is as follows:
wsimport -keep -extension -s./src -p com.jaxws.test http://192.168.1.1:8080/service?wsdl
You can find various client-related auxiliary classes that are automatically generated under the com.jaxws.test package. I won’t explain how these categories are used in detail, there is a lot of information online. Then I write the calling class myself (I am just a method here, just call it)
The code copy is as follows:
public String jaxws(Object[] opArgs)
{
ServicesService service=new ServicesService();
//Add a header to SOAP
service.setHandlerResolver(new HandlerResolver(){
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerList = new ArrayList<Handler>();
//Add authentication information
handlerList.add(new ClientHandler());
return handlerList;
}
});
String result = service.getServicesPort().getResults(opArgs.toString());
//Get the result
System.out.println(result);
return result;
}
Note the [//Add authentication information handlerList.add(new ClientHandler());] here, so we also need to create a new ClientHandler class to implement the assembly of authentication messages, as follows:
The code copy is as follows:
package com.jaxws.test;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.*;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class ClientHandler implements SOAPHandler<SOAPMessageContext> {
public boolean handleMessage(SOAPMessageContext ctx) {
//Outbound, that is, add header information before the client issues a request
Boolean request_p=(Boolean)ctx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if(request_p){
try {
SOAPMessage msg=ctx.getMessage();
SOAPEnvelope env=msg.getSOAPPart().getEnvelope();
SOAPHeader hdr=env.getHeader();
if(hdr==null) hdr=env.addHeader();
//Add a certification information header
//QName(String namespaceURI, String localPart, String prefix)
//QName(String namespaceURI, String localPart)
//QName(String localPart)
//@param namespaceURI:QName namespace
//@param localPart: the local part of QName
//@param prefix:QName prefix
QName name=new QName("http://csdc.info/", "Authentication", "wsse");
SOAPHeaderElement header = hdr.addHeaderElement(name);
//addChildElement(String localName, String prefix,String uri)
//addChildElement(String localName, String prefix)
//addChildElement(String localName)
//@param uri: The space name URI to which the new element belongs
//@param localName: the local name of the new element
//@param prefix: Space prefix for new element name
//See the API of JDK 1.6
SOAPElement userElement = header.addChildElement("Username", "wsse");
userElement.addTextNode("admin");
SOAPElement passElement = header.addChildElement("Password", "wsse");
passElement.addTextNode("admin");
msg.saveChanges();
//Output SOAP message to System.out, that is, the console
msg.writeTo(System.out);
return true;
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
return false;
}
@Override
public void close(MessageContext context) {
// TODO Auto-generated method stub
}
@Override
public Set<QName> getHeaders() {
// TODO Auto-generated method stub
return null;
}
}
This class adds a header message to all soap messages. My header message is as follows:
The code copy is as follows:
<wsse:Authentication xmlns:wsse="http://csdc.info/">
<wsse:Username>admin</wsse:Username>
<wsse:Password>admin</wsse:Password>
</wsse:Authentication>
This implements a jaxws-based webservice client with soap header authentication.