简体   繁体   中英

Spring gives HTTP Status 400 when receiving a soap request having an xml declaration with special character escape slashes

I am receiving an xml post request from my vendor having a declaration of this format.

<?xml version=\"1.0\" encoding=\"utf-8\"?>

With this type of xml declarion (I am using Spring MVC with JAXB) I am getting the HTTP Status 400 error which states that " The request sent by the client was syntactically incorrect." I tried to post the same request to my site using postman and i get the very same error.

But on changing the xml declarion by removing all the backslashes( see below)

<?xml version="1.0" encoding="utf-8"?>

the error vanishes and i get the correct response with HTTP Status 200 , Ok. My question is how can i intercept this request and modify the xml declaration by removing the forward slashes (My vendor does not comply with modify this from their end).

Below is the sample of my controller

@RequestMapping(method = {RequestMethod.GET,RequestMethod.POST}, value ="/listeningurl", consumes = "application/xml", produces = "application/xml") 
     public ResponseObject lodgementNotifications(@RequestBody RequesObject reqObject)
     {

        //do stuffs with reqObject;
                // Initialize ResponseObject
              return responseObject

    }

Thanks for the help.

You can extends the HandlerInterceptorAdapter which is :

Abstract adapter class for the AsyncHandlerInterceptor interface, for simplified implementation of pre-only/post-only interceptors.

@Component
public class MyHandlerInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // then access your request body (xml content) to update it
        // see link bellow for how to retrieve an xml content from the HttpServletRequest
        return super.preHandle(request, response, handler);
    }
}

After that you override the addInteceptors of WebMvcConfigurerAdapter by creating a custom class that extends from WebMvcConfigurerAdapter :

@Configuration
public class CustomWebMvc extends WebMvcConfigurerAdapter {

    @Autowired
    MyHandlerInterceptor myHandlerInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myHandlerInterceptor);
        super.addInterceptors(registry);
    }
}

To know how to retrieve the xml content from your HttpServletRequest read this Get Posted XML from HttpServletRequest Object


Edit

If your goal is simply to retrieve the http body ( xml content ) and then do what ever you want with it inside your controller you can simply inject an InputStream or a Reader in the @RequestMapping handler method (which is your controller method) like so :

@PostMapping(value = "/topics/xml", consumes = "application/xml")
public void getXmlRequest(InputStream data) throws IOException {
    String requestBody = IOUtils.toString(data);
    // format the xml and do something with it
}

Spring web doc : Handler Methods :

@RequestMapping handler methods have a flexible signature and can choose from a range of supported controller method arguments and return values. 在此处输入图片说明

I was able to resolve the issue. I had to receive the xml request in String format, removed the backslashes then unmarshalled it into its corresponding object. Thanks to @Harry Coder for the hints. Here is the solution that worked for me.

@RequestMapping(method = {RequestMethod.GET,RequestMethod.POST}, value ="/listeningurl", consumes = "application/xml", produces = "application/xml") 
     public ResponseObject lodgementNotifications(@RequestBody String reqObjectXMLStr)
     {

          //Replace the backslashes from the xml string
          String cleanReqObjectXMLStr = reqObjectXMLStr.replaceAll("\\\\", "");

        //Unmarshal the string into the corresponding object using JAXB library 
         RequestObject reqObject = JAXB.unmarshal(new StringReader(cleanReqObjectXMLStr), RequestObject.class);

        //do stuffs with reqObject;

                // Initialize and set ResponseObject
              return responseObject

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM