【问题标题】:Spring MVC controller method returns 400 (bad request) in response to jQuery ajax requestSpring MVC 控制器方法返回 400(错误请求)以响应 jQuery ajax 请求
【发布时间】:2016-02-11 00:07:06
【问题描述】:

我正在向 Spring MVC 控制器方法发送一个 jQuery ajax 请求并得到以下响应:

 { "timestamp" : "2016-02-10T23:47:14.770+0000",
 "status" : 400,↵  "error" : "Bad Request",
 "exception" : "org.springframework.http.converter.HttpMessageNotReadableException",
"message" : "Bad Request",
"path" : "/chart/add" }

这是请求:

$.ajax({
    type : "POST",
    contentType : "application/json; chartset=utf-8",
    url : "/chart/add",
    data : '{"id":"1","title":"ajax","description":"ajax"}',
    dataType : 'json',
    timeout : 100000,
    success : function(data) {
        console.log("SUCCESS: ", data);
    },
    error : function(e) {
        console.log("ERROR: ", e);
    },
    done : function(e) {
        console.log("DONE");
    }
});

以下是spring控制器的方法:

@Controller
public class DatasetController {

    @Autowired private DatasetRepository datasetRepository;
    @Autowired private ChartSpecRepository chartSpecRepository;
    @Autowired private CustomerRepository customerRepository;
    @Autowired private ObjectMapper objectMapper;

    @RequestMapping(value="chart/add", method=RequestMethod.POST)
    public ModelAndView newChart(@RequestBody String json) {
        try {
            ModelAndView ret = new ModelAndView("chart");
            ObjectNode node = objectMapper.readValue(json, ObjectNode.class);
            ChartSpec chart = new ChartSpec();
            NewChartRequest request = objectMapper.convertValue(node, NewChartRequest.class);
            ChartSpec.ChartType chartType = toEnum(request.getChartType());
            String datasetName = request.getDatasetName();
            String customerId = request.getCustomerId();
            Integer bins = request.getBins();
            String[] columns = request.getColumns();
            CustomerDataset dataset = datasetRepository
                .findByCustomerIdAndName(customerId, datasetName);

            chart.setChartType(chartType);
            chart.setDatasetId(dataset.getId());
            chart.setColumns(columns);
            chart.setOptions(request.getOptions());
            chart.setBins(bins);

            if(chartType == ChartSpec.ChartType.HISTOGRAM && bins != null && columns.length > 0) {
                ret.addObject("dataset", histogram(dataset, bins, columns[0]));
            } else if(chartType == ChartSpec.ChartType.BAR && columns.length > 0) {
                ret.addObject("dataset", barChart(dataset, columns[0]));
            } else if(chartType == ChartSpec.ChartType.LINE && columns.length > 2) {
                ret.addObject("dataset", dataset.getColumns(columns[0], columns[1]));
            }

            if(ret.getModel().isEmpty())
                return new ModelAndView("error");

            chartSpecRepository.save(chart);
            return ret;

        } catch(JsonMappingException jme) {
            return new ModelAndView("error");
        } catch(JsonParseException jpe) {
            jpe.printStackTrace();
            return new ModelAndView("error");
        } catch(IOException ioe) {
            return new ModelAndView("error");
        }   
    }
}

我在这个主题上看到的其他帖子似乎围绕着意外使用@RequestParam 而不是@ResquestBody,或者没有对 JSON 进行字符串化。上面的ajax方法使用的是文字json而不是我打算使用的字符串化对象,只是为了排除Json不正确的可能性。

有趣的是,如果我使用

$.post("/chart/add", '{"id":"1","title":"ajax","description":"ajax"}')

请求通过。但是,我想了解我在 ajax 方法中做错了什么,因为我希望能够准确地指定我的请求。

关于抛出的具体异常,HttpMessageNotReadableException,Spring 文档中这样说:

由 HttpMessageConverter 实现时抛出 HttpMessageConverter.read(java.lang.Class, org.springframework.http.HttpInputMessage) 方法失败。

但是,在那之后我并没有特别关注文档。如果我需要提供更多信息,请告诉我。任何帮助表示赞赏。

【问题讨论】:

  • 您是否尝试过使用@RestController 注释或将consumes='application/json' 添加到您的映射中?
  • @cjstehno 我没有。现在就去试试。
  • @cjstehno 好点,但最终并没有解决这个问题。感谢您的建议。
  • 使用 json 键创建对象应该映射请求。而produces,consumes = 'application/json'也应该解决这个问题,

标签: jquery json ajax spring spring-mvc


【解决方案1】:

您的问题是您在 ajax 调用中强制使用内容类型。

contentType : "application/json; chartset=utf-8"

由于您的控制器正在接受 String 对象,因此表示不正确。

您应该使用@RequestBody Document document 将您的@RequestBody String json 更改为真实对象,或者从您的ajax 调用中删除内容类型

我建议创建一个对象以避免在控制器中解析 json

您的对象可能看起来像这样:

public class Document{
    int id;
    String title;
    String description;
    //getters /setters
}

【讨论】:

    猜你喜欢
    • 2015-12-02
    • 2014-12-31
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    • 1970-01-01
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多