Spring MVC控制器方法返回400(错误请求)以响应jQuery ajax请求

时间:2016-02-11 00:07:07

标签: jquery json ajax spring spring-mvc

我正在向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");
    }
});

以下是弹簧控制器方法:

@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)方法失败。

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

1 个答案:

答案 0 :(得分:0)

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

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

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

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

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

你的对象看起来像这样:

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