Spring 在收到具有带有特殊字符转义斜杠的 xml 声明的 soap 请求时给出 HTTP 状态 400

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

我收到了来自我的供应商的 xml post 请求,其中包含此格式的声明。

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

使用这种类型的 xml 声明(我将 Spring MVC 与 JAXB 一起使用)我收到 HTTP 状态 400 错误,其中指出“The request sent by the client was syntactically incorrect." 我尝试使用 postman 向我的站点 post 发出相同的请求,但我得到了同样的错误。

但是通过删除所有反斜杠来更改 xml 声明(见下文)

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

错误消失,我得到正确的 HTTP 状态响应 200,好的。 我的问题是我如何拦截此请求并通过删除正斜杠来修改 xml 声明(我的供应商不遵守从他们的结尾修改这个)。

下面是我的控制器示例

@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

    }

感谢您的帮助。

您可以扩展 HandlerInterceptorAdapter 即:

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);
    }
}

之后,您通过创建从 WebMvcConfigurerAdapter 扩展的自定义 class 来覆盖 WebMvcConfigurerAdapteraddInteceptors :

@Configuration
public class CustomWebMvc extends WebMvcConfigurerAdapter {

    @Autowired
    MyHandlerInterceptor myHandlerInterceptor;

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

要了解如何从 HttpServletRequest 中检索 xml 内容,请阅读此


编辑

如果您的目标只是检索 http 正文 (xml content),然后在控制器中用它做任何您想做的事,您只需注入一个InputStream 或 @RequestMapping 处理程序方法(这是您的控制器方法)中的 Reader,如下所示:

@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.

我能够解决问题。我必须接收字符串格式的 xml 请求,删除反斜杠,然后将其解组到相应的对象中。感谢@Harry Coder 的提示。这是对我有用的解决方案。

@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

    }