前端发送json对象给后台spring mvc报错


 let personInsertDO={
        name:$('#name').val(),
        sex:$('#sex').val(),
        nation:$('nation').val(),
        peopleId:$('#peopleId').val(),
        phoneOne:$('#phoneOne').val(),
        phoneTwo:$('#phoneTwo').val(),
        workUnit:$('#workUnit').val(),
        householdPeopleId:$('#householdPeopleId').val(),
        relationWithHousehold:$('#relationWithHousehold').val()
     };

     let properties=[];


     let select = $('.selectpicker')[0];
     for (let i = 0; i < select.options.length; i++) {
        if (select.options[i].selected) {
            let property={
                id:select.options[i].value,
                value:""
            };
            properties.push(property);
        }
      }

      personInsertDO['properties']=properties;
      personInsertDO=JSON.stringify(personInsertDO);

      console.log(personInsertDO);
      $.ajax({
        type: "post",
        url: "/addPersonConfirm",
        data: personInsertDO,
        dataType: "json",
        contentType: "application/json",
        headers: {
            'Content-Type': 'application/json'
        },
        success: function (response) {
            if(response.code == 200){
                layer.msg(response.message,{
                    icon:1,
                    shade:0.01
                });
                parent.refreshTable();
                parent.layer.closeAll();
            }
            else if(response.code==500){
                alert("请检查你的信息");
            }
            else if(response.code==401){
                alert("没有查询到你的户主");
            }
        }
    });

 @PostMapping("/addPersonConfirm")
    @ResponseBody
    public Result addPersonConfirm(@RequestBody PersonInsertDO personInsertDO) {
        LOG.info(personInsertDO.getHouseholdPeopleId()+" "+personInsertDO.getName());
        Result returnData = new Result<>();

        if (personInsertDO.getName()==null || personInsertDO.getHouseholdPeopleId()==null){
            returnData.setCode(Constant.CODE_500);
            returnData.setMessage("请检查你的信息");
        }
        else if (personService.findByPersonIdIsHousehold(personInsertDO.getHouseholdPeopleId())==null){
            returnData.setCode(Constant.CODE_401);
            returnData.setMessage("你填写的户主不存在");
        }
        else {
            personService.addPerson(personInsertDO);
            returnData.setMessage("成功添加一条居民信息");
            returnData.setSuccess(true);
            returnData.setData(true);
            returnData.setCode(Constant.CODE_200);
        }

        return returnData;
    }

前面是前端代码,后面是后端代码,为什么始终得到报错Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported]

img

前面的回答都说是content-type的问题,实际上你也意识是这个问题,
但是你可能不知道入手去查找或解决这个问题。


你需要的是有人帮你调试代码,你说对不?

如果需要,我们可以聊聊。

参考:
https://blog.csdn.net/feiyst/article/details/88431621

在Spring MVC中出现HttpMediaTypeNotSupportedException异常通常是由于客户端请求的Content-Type与服务器端的接收类型不匹配所引起的。

在默认情况下,Spring MVC使用ContentNegotiatingViewResolver来解析响应,以根据客户端接受的媒体类型确定返回的响应类型。如果请求的Content-Type与支持的媒体类型不匹配,就会出现HttpMediaTypeNotSupportedException异常。

一种可能的解决方案是在Spring MVC的控制器方法上添加consumes属性,以指定控制器方法支持的媒体类型。例如:

@RequestMapping(value = "/someEndpoint", method = RequestMethod.POST, consumes = "application/x-www-form-urlencoded;charset=UTF-8")
public ResponseEntity<String> someMethod(@RequestBody SomeRequestBody requestBody) {
    // 处理请求
}

上面consumes属性指定控制器方法支持的Content-Type为application/x-www-form-urlencoded;charset=UTF-8。如果客户端请求的Content-Type不匹配,将会返回HttpMediaTypeNotSupportedException异常。

另一个可能的解决方案是确保客户端请求的Content-Type与控制器方法支持的Content-Type匹配。如果使用application/x-www-form-urlencoded格式提交表单数据,那么客户端请求的Content-Type应该为application/x-www-form-urlencoded。

是不是前端js更改没生效?重新启动服务了吗

报错信息提示的是Content-Type为'application/x-www-form-urlencoded;charset=UTF-8'不受支持,说明请求头中的Content-Type并未设置为'application/json'。需要确认前端发送的请求头中是否设置了Content-Type为'application/json'。可以在浏览器的Network中查看请求头,也可以在前端代码中添加headers选项来设置请求头。

原因:后端接口API需要的参数格式为json,但我们前端提交的数据格式为form表单。
思路1:把接口API的参数接收格式修改为接收form表单。
思路2:传递的参数格式转换为 json 格式,http请求头设置为 content-type : application/json;charset=UTF-8

你好题主,根据你的问题和错误反馈来看,其实你是想通过解决后端的异常来解决,那么我改动你的前端代码,后端也可以不改动,要么就只改后端代码,不过需要稍微修正一下后端逻辑处理。
有兴趣可以往下看,你的问题我之前也遇到过。
甚至以后遇到 WebKitFormBoundary、Convert转换器不支持复杂等这类问题都可以完全避开,当然也花费了一些时间总结了出来。

分析问题:
你这个问题就是你前端可以传数据回来,但你接收时,@RequestBody 并没有如你期待转换生效,因为前端是 设置了 dataType: json。
而且 json 其实就是字符串,而 @RequestBody 处理的是前端传的对象,所以有两种解决方法:

前端解决:
你需要删除 dataType: "json", 这一行,让它默认通过对象传过去,那么 后端自然可以通过 @RequestBody 接收。

后端解决:
你在后端需要处理 json 字符串,可以去实现 Converter<String, List> 接口
实现方法 convert(String PersonInsertDO ) 并且 更改 Controller 入参

@PostMapping("/addPersonConfirm")
    @ResponseBody
    // 前端 传的 字段就是 @RequestParam 的 value 属性
    public Result<Boolean> addPersonConfirm(@RequestParam(value = "personInsertDO") personInsertDO) {
}

添加一个转换器

img

贴上代码

@Configuration
public class PersonInsertDOConverter implements Converter<String, PersonInsertDO>> {
    // 因为 json 是字符串 用它接收
    @Override
    public PersonInsertDO convert(String personInsertDO) {
        return JsonUtils.jsonToList(personInsertDO , PersonInsertDO.class);
    }
}

我自己写的JSON工具

package cn.fyupeng.utils;

import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.List;

/**
 * 
 * @Title: JsonUtils.java
 * @Package com.lee.utils
 * @Description: 自定义响应结构, 转换类
 * Copyright: Copyright (c) 2016
 * Company:Nathan.Lee.Salvatore
 *
 * @author leechenxiang
 * @date 2016年4月29日 下午11:05:03
 * @version V1.0
 */
public class JsonUtils {

    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 字符串转JSONObject
     * @param str 传入的json格式字符串
     * @return  JSONObject
     */
    public static JSONObject stringToJSONObject(String str){
        JSONObject jsonObject = JSONObject.parseObject(str);
        return jsonObject;
    }

    /**
     * 将对象转换成json字符串。
     * <p>Title: pojoToJson</p>
     * <p>Description: </p>
     * @param data
     * @return
     */
    public static String objectToJson(Object data) {
        try {
            String string = MAPPER.writeValueAsString(data);
            return string;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 将json结果集转化为对象
     * 
     * @param jsonData json数据
     * @param beanType 对象中的object类型
     * @return
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 将json数据转换成pojo对象list
     * <p>Title: jsonToList</p>
     * <p>Description: </p>
     * @param jsonData
     * @param beanType
     * @return
     */
    public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
        try {
            List<T> list = MAPPER.readValue(jsonData, javaType);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }

}

这个错误提示意味着后端无法处理发送的JSON数据,因为它期望的是application/x-www-form-urlencoded类型的数据。这通常是由于未正确设置请求头引起的。

您的前端代码已经设置了正确的请求头,即contentType为application/json。但是,由于您的请求头中还包含一个Content-Type,它覆盖了先前的内容类型。您可以尝试将headers配置中的'Content-Type'字段删除,然后看看是否仍然出现这个错误。如果仍然有这个错误,您可以尝试去掉dataType配置,并将返回类型改为String类型,如下所示:

$.ajax({
        type: "post",
        url: "/addPersonConfirm",
        data: personInsertDO,
        contentType: "application/json",
        success: function (response) {
            // handle response
        }
});

同时,在您的后端代码中,也需要确保已正确配置接收JSON数据的解析器。具体来说,您可以在Spring MVC配置文件中添加以下配置:

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
  <property name="messageConverters">
    <list>
      <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="supportedMediaTypes">
          <list>
            <value>application/json</value>
          </list>
        </property>
      </bean>
    </list>
  </property>
</bean>

这将确保Spring MVC使用MappingJackson2HttpMessageConverter来解析发送的JSON数据。

https://blog.csdn.net/qq_57581439/article/details/124311520

img


前端解决方案:
1、 把传参类型改为:Content-Type:pplication/x-www-form-urlencoded;charset=UTF-8
2、传的参数用new formData() 来构建
后端解决方案:
把接受参数改为Content-Type为application/json类型的,因为你前端现在代码传的就是json类型的

我简单看了一下你的代码,我觉得可能是因为你的请求头中没有指定正确的Content-Type,Spring MVC默认只支持application/json类型的请求,所以你需要在请求头中指定Content-Type为application/json,这样Spring MVC才能正确处理你的请求