内容类型为 application/x-www-form-urlencoded 的 Http Post 请求在 Spring 中不起作用

Posted

技术标签:

【中文标题】内容类型为 application/x-www-form-urlencoded 的 Http Post 请求在 Spring 中不起作用【英文标题】:Http Post request with content type application/x-www-form-urlencoded not working in Spring 【发布时间】:2016-04-19 07:58:55 【问题描述】:

我是 spring 的新手,目前我正在尝试执行 HTTP POST 请求应用程序/x-www-form-url 编码,但是当我将其保留在我的标头中时,spring 无法识别它并说 415 Unsupported Media Typex-www-form-urlencoded

org.springframework.web.HttpMediaTypeNotSupportedException:内容 类型 'application/x-www-form-urlencoded' 不支持

有人知道怎么解决吗?请给我评论。

我的控制器的一个例子是:

@RequestMapping(
    value = "/patientdetails",
    method = RequestMethod.POST,
    headers="Accept=application/x-www-form-urlencoded")
public @ResponseBody List<PatientProfileDto> getPatientDetails(
        @RequestBody PatientProfileDto name
)  
    List<PatientProfileDto> list = new ArrayList<PatientProfileDto>();
    list = service.getPatient(name);
    return list;

【问题讨论】:

【参考方案1】:

问题是当我们使用 application/x-www-form-urlencoded 时,Spring 并不将其理解为 RequestBody。所以,如果我们想使用这个 我们必须删除 @RequestBody 注释。

然后尝试以下操作:

@RequestMapping(value = "/patientdetails", method = RequestMethod.POST,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public @ResponseBody List<PatientProfileDto> getPatientDetails(
        PatientProfileDto name) 


    List<PatientProfileDto> list = new ArrayList<PatientProfileDto>();
    list = service.getPatient(name);
    return list;

注意去掉了注释@RequestBody

【讨论】:

这是正确的。但对于 PATCH 方法,我需要 @RequestBody 或我的对象为空(所有字段均为空) 找到了一个解决方案,不使用@RequestBody 在这里添加一个过滤器:docs.spring.io/spring/docs/4.0.x/spring-framework-reference/…【参考方案2】:

您应该将 @RequestBody 替换为 @RequestParam,并且不要接受带有 java 实体的参数。

那么你的控制器大概是这样的:

@RequestMapping(value = "/patientdetails", method = RequestMethod.POST, 
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public @ResponseBody List<PatientProfileDto> getPatientDetails(
    @RequestParam Map<String, String> name) 
   List<PatientProfileDto> list = new ArrayList<PatientProfileDto>();
   ...
   PatientProfileDto patientProfileDto = mapToPatientProfileDto(mame);
   ...
   list = service.getPatient(patientProfileDto);
   return list;

【讨论】:

【参考方案3】:

可以在这里找到解决方案https://github.com/spring-projects/spring-framework/issues/22734

您可以创建两个单独的发布请求映射。例如。

@PostMapping(path = "/test", consumes = "application/json")
public String test(@RequestBody User user) 
  return user.toString();


@PostMapping(path = "/test", consumes = "application/x-www-form-urlencoded")
public String test(User user) 
  return user.toString();

【讨论】:

【参考方案4】:

最简单的做法是将您的ajax 请求的内容类型设置为"application/json; charset=utf-8",然后让您的API 方法使用JSON。像这样:

var basicInfo = JSON.stringify(
    firstName: playerProfile.firstName(),
    lastName: playerProfile.lastName(),
    gender: playerProfile.gender(),
    address: playerProfile.address(),
    country: playerProfile.country(),
    bio: playerProfile.bio()
);

$.ajax(
    url: "http://localhost:8080/social/profile/update",
    type: 'POST',
    dataType: 'json',
    contentType: "application/json; charset=utf-8",
    data: basicInfo,
    success: function(data) 
        // ...
    
);


@RequestMapping(
    value = "/profile/update",
    method = RequestMethod.POST,
    produces = MediaType.APPLICATION_JSON_VALUE,
    consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseModel> UpdateUserProfile(
    @RequestBody User usersNewDetails,
    HttpServletRequest request,
    HttpServletResponse response
) 
    // ...

我猜问题是 Spring Boot 在通过 ajax 请求提交不是 JSON 的表单数据时遇到问题。

注意:ajax 的默认内容类型是"application/x-www-form-urlencoded"

【讨论】:

【参考方案5】:

从方法中的使用参数中删除 @ResponseBody 注释。像这样;

   @Autowired
    ProjectService projectService;

    @RequestMapping(path = "/add", method = RequestMethod.POST)
    public ResponseEntity<Project> createNewProject(Project newProject)
        Project project = projectService.save(newProject);

        return new ResponseEntity<Project>(project,HttpStatus.CREATED);
    

【讨论】:

【参考方案6】:

您必须告诉 Spring 您的服务支持哪种输入内容类型。您可以使用与您的请求的“Content-Type”标头相对应的“consumes”注释元素来执行此操作。

@RequestMapping(value = "/", method = RequestMethod.POST, consumes = "application/x-www-form-urlencoded")

如果您发布代码会很有帮助。

【讨论】:

状态 415 不支持的媒体类型消息显示 不支持内容类型'application/x-www-form-urlencoded' 你是否添加了带有“consumes”参数的请求映射注解? @RequestMapping(value = "/patientdetails", method = RequestMethod.POST,consumes = "application/x-www-form-urlencoded") org.springframework.web.HttpMediaTypeNotSupportedException: 内容类型'application/x-www-form-urlencoded' 不支持 我应该在配置 xml 中添加任何内容吗? ?【参考方案7】:

将 contentType : "application/x-www-form-urlencoded" 替换为 dataType : "text" 因为 wildfly 11 不支持提到的 contenttype..

【讨论】:

以上是关于内容类型为 application/x-www-form-urlencoded 的 Http Post 请求在 Spring 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用axios请求发送数据

bibli直播弹幕实时爬取

cocos2d-js网络教程篇cocos2d-js http网络请求

自动将 drupal 7 内容类型转换为代码。内容类型生成器代码?

为同一端点使用任何类型的内容类型

drupal7 为视图添加 过滤标准 内容类型