1. 程式人生 > >webservice之自定義請求頭實現

webservice之自定義請求頭實現

需求:目前遇到一個呼叫webservice服務端的程式,需要開發客戶端呼叫程式,但是涉及到自定義請求頭,這個有一點麻煩

目前基於http+json的restful大行其道,所以本篇不介紹webservice服務開發過程,詳情可自行百度,基於cxf 可開發webservice和restful服務
好的,言歸正傳,本篇文章將會介紹webservice客戶端呼叫新增自定義請求頭的兩種方式,一種是jdk,一種藉助於cxf框架

自定義請求頭格式:

<auth>
<token></token>
<user></user>
<password
>
</password> </auth>

服務端實現:
自定義頭部,需要自定義解析,本例服務端採用的是cxf,所以採用的是
攔截器AbstractPhaseInterceptor,攔截請求,解析頭部

public class AuthHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
    private Logger log = Logger.getLogger(AuthHeaderInterceptor.class);
    public AuthHeaderInterceptor() {
        super(Phase.PRE_INVOKE);
    }

    @Override
    public
void handleMessage(SoapMessage msg) throws Fault { try { Header authHeader =null; //獲取驗證頭 List<Header> headers = msg.getHeaders(); for(Header h:headers){ if(h.getName().toString().contains("auth")){ authHeader=h; break
; } } Element auth = (Element) authHeader.getObject(); NodeList childNodes = auth.getChildNodes(); String token,user,password; for(int i=0,len=childNodes.getLength();i<len;i++){ Node item = childNodes.item(i); if(item.getNodeName().contains("token")){ token=item.getTextContent(); // do check token } if(item.getNodeName().contains("user")){ user=item.getTextContent(); // do check user } if(item.getNodeName().contains("password")){ password=item.getTextContent(); // do check password } } } catch (Exception e) { e.printStackTrace(); log.error("許可權驗證異常"); throw new Fault(new Exception("請求頭auth不合法")); } } }

客戶端實現
cxf 框架實現:
實現手段,攔截每次請求,新增自定義認證頭部;
繼承 AbstractSoapInterceptor

import java.util.List;

import javax.xml.namespace.QName;

import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class AuthHeaderInterceptor extends AbstractSoapInterceptor {
    private String token;
    private String user;
    private String password;

    public AuthHeaderInterceptor(String p, String token, String user, String password) {
        super(p);
        this.token = token;
        this.user = user;
        this.password = password;
    }

    public AuthHeaderInterceptor() {
        super(Phase.WRITE);
    }

    public void handleMessage(SoapMessage message) throws Fault {
        // SoapHeader部分待新增的節點
        QName qName = new QName("auth");
        Document doc = DOMUtils.createDocument();
        // 驗證token
        Element tokenEl = doc.createElement("token");
        tokenEl.setTextContent(token);

        Element pwdEl = doc.createElement("password");
        pwdEl.setTextContent(password);
        Element userEl = doc.createElement("user");
        userEl.setTextContent(user);
        Element root = doc.createElement("auth");


        root.appendChild(tokenEl);
        root.appendChild(userEl);
        root.appendChild(pwdEl);
        // 建立SoapHeader內容
        SoapHeader header = new SoapHeader(qName, root);
        // 新增SoapHeader內容
        List<Header> headers = message.getHeaders();
        headers.add(header);
    }

}


客戶端呼叫,新增到outInterceptors
    Client client= ClientProxy.getClient(service);
    AuthHeaderInterceptor authHeaderInterceptor = new AuthHeaderInterceptor("token","user","password");
services.xxx(呼叫)

jdk 實現:
和cxf 原理差不多,都是在請求之前新增頭部,不過實現的是HandlerResolver 介面

//首先實現:新增頭部邏輯
public class RequesterCredentials implements SOAPHandler<SOAPMessageContext> {
    private String token;
    private String user;
    private String password;

    public RequesterCredentials(String token, String user, String password) {
        super();
        this.token = token;
        this.user = user;
        this.password = password;
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public Set<QName> getHeaders() {
        return null;
    }

    @Override
    public void close(MessageContext context) {
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        // TODO return true
        return true;
    }

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        addRequesterCredentials(context);
        return true;
    }

    private void addRequesterCredentials(SOAPMessageContext context) {
        try {
            Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

            if (outboundProperty.booleanValue()) {
                SOAPMessage message = context.getMessage();

                SOAPHeader header = message.getSOAPHeader();
                if (header == null) {
                    message.getSOAPPart().getEnvelope().addHeader();
                    header = message.getSOAPHeader();
                }
                SOAPElement authenticationToken = header.addChildElement("auth", "", "");
                authenticationToken.addChildElement("user").addTextNode(user);
                authenticationToken.addChildElement("password").addTextNode(password);
                authenticationToken.addChildElement("token").addTextNode(token);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public RequesterCredentials() {

    }

}
//實現 HandlerResolver 介面

public class HeaderHandlerResolver implements HandlerResolver {
    private RequesterCredentials requesterCredentials;

    public HeaderHandlerResolver(RequesterCredentials requesterCredentials){
        this.requesterCredentials=requesterCredentials;
    }
    @Override
    public List getHandlerChain(PortInfo portInfo) {
        return Arrays.asList(requesterCredentials);
    }




}

最終效果:
這裡寫圖片描述