• Spring Boot文档阅读笔记-3 Ways to Add Custom Header in Spring SOAP Request


    本篇博文使用3种不同的方法,在Spring SOAP(Simple Object Access Protocol)上添加自定义头信息。头信息一般是服务端用于身份验证的。

    SOAP头信息在SWDL文档中是不会提及的,这需要程序员手动在请求上添加头信息。这里可以使用interceptor用于添加头信息,也可以在WebServiceMessageCallback中重写dowithMessage()方法上做,也可以在JAXB Marshaller中添加头信息。

    下面是一个简单的SOAP请求的XML头信息。

    1. <soapenv:Header>
    2. <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    3. <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    4. <wsse:Username>abcwsse:Username>
    5. <wsse:Password>abcwsse:Password>
    6. wsse:UsernameToken>
    7. wsse:Security>
    8. soapenv:Header>

    SOAP Web Service Adapter

    在添加头信息前,首先要有一个SOAP的适配器,如下代码:

    BlzServiceAdpter.java

    1. public class BlzServiceAdapter extends WebServiceGatewaySupport {
    2. private static final Logger logger = LoggerFactory.getLogger(BlzServiceAdapter.class);
    3. public GetBankResponseType getBank(String url, Object requestPayload){
    4. WebServiceTemplate webServiceTemplate = getWebServiceTemplate();
    5. JAXBElement res = null;
    6. try {
    7. res = (JAXBElement) webServiceTemplate.marshalSendAndReceive(url, requestPayload);
    8. }catch(SoapFaultClientException ex){
    9. logger.error(ex.getMessage());
    10. }
    11. return res.getValue();
    12. }
    13. }

    Using TransformerFactory to Transform XML to Header

    首先在application.properties文件中添加对应的头数据,和用户名密码

    1. soap.auth.header="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">%(loginuser)"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">%(loginpass)
    2. soap.auth.username=testuser
    3. soap.auth.password=testpass

    然后getBank中读取application.properties中关于soap头的信息,并将头信息设置到webServiceTemplate中

    1. private static final Logger logger = LoggerFactory.getLogger(BlzServiceAdapter.class);
    2. @Autowired
    3. private Environment environment;
    4. public GetBankResponseType getBank(String url, Object requestPayload){
    5. WebServiceTemplate webServiceTemplate = getWebServiceTemplate();
    6. JAXBElement res = null;
    7. try {
    8. res = (JAXBElement) webServiceTemplate.marshalSendAndReceive(url, requestPayload, new WebServiceMessageCallback() {
    9. @Override
    10. public void doWithMessage(WebServiceMessage message) {
    11. try {
    12. SoapHeader soapHeader = ((SoapMessage) message).getSoapHeader();
    13. Map mapRequest = new HashMap();
    14. mapRequest.put("loginuser", environment.getProperty("soap.auth.username"));
    15. mapRequest.put("loginpass", environment.getProperty("soap.auth.password"));
    16. StringSubstitutor substitutor = new StringSubstitutor(mapRequest, "%(", ")");
    17. String finalXMLRequest = substitutor.replace(environment.getProperty("soap.auth.header"));
    18. StringSource headerSource = new StringSource(finalXMLRequest);
    19. Transformer transformer = TransformerFactory.newInstance().newTransformer();
    20. transformer.transform(headerSource, soapHeader.getResult());
    21. logger.info("Marshalling of SOAP header success.");
    22. } catch (Exception e) {
    23. logger.error("error during marshalling of the SOAP headers", e);
    24. }
    25. }
    26. });
    27. }catch (SoapFaultClientException e){
    28. logger.error("Error while invoking session service : " + e.getMessage());
    29. return null;
    30. }
    31. return res.getValue();
    32. }

    这里有一点要注意,如果要在header中的security结点上添加一个新的结点,这个方式就会报错The markup in the document following the root element must be well-formed,解决办法是手动加一个SOAPHeaderElement在头信息中。

    Using SOAPElement to Header Manually

    在doWithMessage()函数中实现,首先手动创建SOAPHeaderElement及SOAPElement,然后再把这个添加到SOAPHeader上。

    TokenHeaderRequestCallbak.java

    1. import org.slf4j.Logger;
    2. import org.slf4j.LoggerFactory;
    3. import org.springframework.ws.WebServiceMessage;
    4. import org.springframework.ws.client.core.WebServiceMessageCallback;
    5. import org.springframework.ws.soap.saaj.SaajSoapMessage;
    6. import javax.xml.soap.*;
    7. public class TokenHeaderRequestCallback implements WebServiceMessageCallback {
    8. private static final Logger logger = LoggerFactory.getLogger(SessionHeaderRequestCallback.class);
    9. private String username;
    10. private String password;
    11. public TokenHeaderRequestCallback(String username, String password){
    12. this.username = username;
    13. this.password = password;
    14. }
    15. public void doWithMessage(WebServiceMessage message) {
    16. try {
    17. SaajSoapMessage saajSoapMessage = (SaajSoapMessage)message;
    18. SOAPMessage soapMessage = saajSoapMessage.getSaajMessage();
    19. SOAPPart soapPart = soapMessage.getSOAPPart();
    20. SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
    21. SOAPHeader soapHeader = soapEnvelope.getHeader();
    22. Name headerElementName = soapEnvelope.createName(
    23. "Security",
    24. "wsse",
    25. "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    26. );
    27. SOAPHeaderElement soapHeaderElement = soapHeader.addHeaderElement(headerElementName);
    28. SOAPElement usernameTokenSOAPElement = soapHeaderElement.addChildElement("UsernameToken", "wsse");
    29. SOAPElement userNameSOAPElement = usernameTokenSOAPElement.addChildElement("Username", "wsse");
    30. logger.info(this.username);
    31. userNameSOAPElement.addTextNode(this.username);
    32. SOAPElement passwordSOAPElement = usernameTokenSOAPElement.addChildElement("Password", "wsse");
    33. passwordSOAPElement.addTextNode(this.password);
    34. soapMessage.saveChanges();
    35. } catch (SOAPException soapException) {
    36. throw new RuntimeException("TokenHeaderRequestCallback", soapException);
    37. }
    38. }
    39. }

    Using JAXB Marshaller to Add Header

    这种方式比较简单,在JAXB marshaller上创建SOAP header就可以了。如下代码:

    1. @Override
    2. public void doWithMessage(WebServiceMessage message) {
    3. try {
    4. SoapHeader soapHeader = ((SoapMessage) message).getSoapHeader();
    5. ObjectFactory factory = new ObjectFactory();
    6. AuthSoapHeaders authSoapHeaders =
    7. factory.createAuthSoapHeaders();
    8. authSoapHeaders.setUsername("testuser");
    9. authSoapHeaders.setPassword("testpass");
    10. JAXBElement headers =
    11. factory.createAuthSoapHeaders(AuthSoapHeaders);
    12. JAXBContext context = JAXBContext.newInstance(AuthSoapHeaders.class);
    13. Marshaller marshaller = context.createMarshaller();
    14. marshaller.marshal(authSoapHeaders, soapHeader.getResult());
    15. } catch (Exception e) {
    16. logger.error("error during marshalling of the SOAP headers", e);
    17. }
    18. }
    19. });
  • 相关阅读:
    AI学习教程:AI(Adobe lliustrator)快速入门
    线程中断标志位 interrupt()、interrupted()、isInterrupted() 的认识
    Java遍历Map的5种方法
    flink 8081 web页面无法被局域网内其他机器访问
    走进volatile的世界,探索它与可见性,有序性,原子性之间的爱恨情仇!
    VUE3 <component>“元组件” 渲染$slots传的插槽
    前端例程20220802:玻璃背光按钮
    30岁HR转行软件测试,3个月学习斩获12.8K车联网公司offer
    基于JavaSwing开发学生信息管理系统(SQLServer数据库版本) 毕业设计 课程设计 大作业
    初识Spring
  • 原文地址:https://blog.csdn.net/qq78442761/article/details/127724938