当前位置: 首页 > 知识库问答 >
问题:

Spring的rest控制器同时支持application/json和application/x-www-form-urlencoded

华佐
2023-03-14

我正在编写一个RESTendpoint,它需要同时支持application/x-www-form-urlencoded和application/json作为请求体。我做了以下配置,

@RequestMapping(method = RequestMethod.POST, produces = { MediaType.APPLICATION_JSON_VALUE }, consumes = {          
        MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.APPLICATION_JSON_VALUE }, path = Constants.ACCESS_TOKEN_V1_ENDPOINT)
public OAuth2Authorization createAccessTokenPost(
        @RequestBody(required = false) MultiValueMap<String, String> paramMap) { ..

虽然它单独支持application/x-www-form-urlencoded或application/json(当我从consumes={}中注释掉一种内容类型时),但它不同时支持这两种类型。有什么想法吗?

共有1个答案

张建华
2023-03-14

根据我的发现,spring不同时支持内容类型“application/x-www-form-urlencoded”、“application/json”和“application/xml”。

我认为原因是:Spring通过解析JSON和XML类型并将它们注入到标记有@requestbodySpring注释的java pojo中来处理它们。但是,x-www-form-urlencoded必须注入到标记为@requestbodymultivaluemap<>对象中。不会同时支持用@requestbody标记的两个不同的java类型,因为spring可能不知道在哪里注入有效负载。

一个可行的解决方案:

API中可以支持“application/x-www-form-urlencoded”。也就是说,它可以使用@RequestBody注释注入到Spring的MultiValueMap<>中。

为了在相同的方法上支持JSON和XML,我们可以利用servlet规范和Spring的类来提取有效负载作为流。

示例代码:

import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.util.MultiValueMap;

// usual REST service class

@Autowired
private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;

@Autowired
private Jaxb2RootElementHttpMessageConverter jaxb2RootElementHttpMessageConverter;

public ResponseEntity<Object> authorizationRequestPost(HttpServletResponse response, HttpServletRequest request,@RequestBody(required = false) MultiValueMap<String, String> parameters) {

    // this MultiValueMap<String,String> will contain key value pairs of "application/x-www-form-urlencoded" parameters.

    // payload object to be populated
    Authorization authorization = null;

    HttpInputMessage inputMessage = new ServletServerHttpRequest(request) {
                    @Override
                    html" target="_blank">public InputStream getBody() throws IOException {
                        return request.getInputStream();
                    }
                };

    if (request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)) {
        authorization = (Authorization) mappingJackson2HttpMessageConverter.read(Authorization.class, inputMessage);
    } 
    else if (request.getContentType().equals(MediaType.APPLICATION_XML_VALUE)) {
        authorization = (Authorization)jaxb2RootElementHttpMessageConverter.read(Authorization.class, inputMessage);
    }
    else{
        // extract values from MultiValueMap<String,String> and populate Authorization
    }

// remaining method instructions
}

请注意,使用这种方法可以支持任何自定义数据类型/标记/格式。Spring的org.springframework.http.converter.HttpMessageConverter<>可以扩展以编写解析逻辑。

另一种可能的方法是AOP风格的解决方案,它将执行相同的逻辑:通过从HttpServlet输入流中提取有效负载并注入有效负载对象来解析有效负载。

第三种方法是编写执行逻辑的过滤器。

 类似资料:
  • 问题内容: 之间有什么区别 request.ContentType =“ application / json; charset = utf-8”; 和 webRequest.ContentType =“ application / x-www-form-urlencoded”; 问题答案: 第一种情况是告诉Web服务器您正在发布JSON数据,如下所示: 第二个选项是告诉Web服务器您将对URL中

  • 我将请求作为内容类型发送给我的控制器类请求:application/json和application/x-www-form-urlencoded格式,它应该允许这两种类型。 但是当我使用请求类型作为应用程序/x-www-form-urlencoded时,它正在工作,但当我使用请求应用程序/json时,该代码不工作,它给出400响应状态。如何解决这个问题。

  • 问题内容: 我曾经有ElasticSearch 5.2,并且刚升级到6.0。 我正在尝试按照此处的指南创建索引模板,但出现错误 我的查询是 问题答案: 要解决此问题,请添加curl选项 这个错误是由于 严格的内容类型检查 在ElasticSearch 6.0中引入,在解释这个岗位 从Elasticsearch 6.0开始,所有包含主体的REST请求也必须提供该主体的正确内容类型。

  • 我试图编写一个restendpoint,它接收application/x-www-form-urlencoded。但是endpoint不接受@requestbody或@requestparam的请求参数 我已经尝试使用MultiValueMap来获取请求参数。但我总是得到0个参数。是否有一种方法可以获取MultiValueMap或其他POJO类的请求值。 -这是application/x-www-

  • 问题内容: 我已经将Elasticsearch(5.5版)集成到Gitlab中并尝试使用它。这是我从外部Windows客户端发送的命令: 但这不起作用。在客户端上,我得到以下错误: {“错误”:“不支持Content-Type标头[应用程序/ x-www-form-urlencoded]”,“状态”:406} curl:(6)无法解析主机:text curl:(3)[globbing ]第1列 c

  • @PostMapping public UserResponse createUser(@RequestBody UserRequest userDetail){ 这是我收到的错误代码 } 我尝试了很多不同的方法仍然没有得到解决方案这是来自邮递员的图片来自邮递员的图片