【问题标题】:Spring: Bind a collection on controller parameterSpring:在控制器参数上绑定一个集合
【发布时间】:2017-01-11 13:12:45
【问题描述】:

我看到了很多与我类似的问题,但是到目前为止我找不到解决这个问题的方法。

我正在 Spring + Hibernate 上实现网格过滤和分页。 load() 方法必须接收分页的具体参数(pagestartlimit)和用于过滤的键值参数列表,这就是问题所在。

参数是这样来的:

page:1
start:0
limit:23
filter:[{"operator":"like","value":"tes","property":"desc"},{"operator":"like","value":"teste","property":"model_desc"}]

或(编码版本):

page=1&start=0&limit=23&filter=%5B%7B%22operator%22%3A%22like%22%2C%22value%22%3A%22tes%22%2C%22property%22%3A%22desc%22%7D%2C%7B%22operator%22%3A%22like%22%2C%22value%22%3A%22teste%22%2C%22property%22%3A%22model_desc%22%7D%5D

过滤器参数以String 的形式出现,问题是让Spring 将其解析为ArrayList<Map<String,String>>ArrayList<SomeFilterClass>

这是我的控制器方法的签名(注释的行都不起作用,它们在这里只是为了展示我到目前为止所做的尝试):

public Map<String, Object> loadData(@RequestParam(value = "page", required = true) int page,
            @RequestParam(value = "start", required = true) int start,
            @RequestParam(value = "limit", required = true) int limit,
//          @ModelAttribute("filter") ArrayList<Map<String, String>> filter) {
//          @RequestParam(value = "filter", required = false) Map<String, Object>[] filter) {
//          @RequestParam(value = "filter", required = false) List<Map<String, String>> filter) {
            @ModelAttribute("filter") RemoteFilter filter) 

这个类 RemoteFilter 是我根据其他帖子的建议构建的包装类,但是它也不起作用。它的结构是:

public class RemoteFilter {

    private ArrayList<Filter> filter;

    //Getters and Setters....

    class Filter {
        private String operator;

        private String value;

        private String property;

        //Getters and Setters....
    }
}

如果有人帮助我,我将非常高兴。

谢谢!

【问题讨论】:

  • 听起来您正在通过 Ajax 调用控制器,您是否有任何理由使用 GET(并且必须对 JSON 进行 URL 编码)而不是 POST 并使用 Spring @RequestBody 将 JSON 转换为 Java 对象?

标签: java spring data-binding collections


【解决方案1】:

尝试发布数据而不是使用 GET,Spring 仅在发布数据时提供 JSON 到 Java 的转换。

发帖

{ 
    page:1
    start:0
    limit:23
    filter:[{"operator":"like","value":"tes","property":"desc"},{"operator":"like","value":"teste","property":"model_desc"}]
}

让控制器使用@RequestBody

@RequestMapping(method = RequestMethod.POST, value = "url", 
    produces = MimeTypeUtils.APPLICATION_JSON_VALUE, 
    consumes = MimeTypeUtils.APPLICATION_JSON_VALUE)
public Map<String, Object> loadData(@RequestBody RemoteFilter filter) {

}

响应使用 Object 作为 Map 值类型。这会起作用,但通常使用未键入的返回值是一件坏事。

【讨论】:

  • 嗨@KlausGroenbaek 感谢您的回复。我忘了放@RequestMapping 注释,但它已经是POST 请求:@RequestMapping(value="/load", method=RequestMethod.POST)。我将其更改为 @RequestBody(required=false) RemoteFilter filter 并收到错误 415(不支持的媒体类型)。我认为这是因为在第一次加载时,没有发送参数过滤器,这就是 required 设置为 false 的原因。
  • 415 表示 Content-type 不正确。如果您从浏览器发布,它应该自动添加 content-type=application/json,在 Spring 中您可以配置控制器方法消耗和产生的内容。我会将其添加到答案中。
  • 它以Content-Type:application/x-www-form-urlencoded; charset=UTF-8 发送。但是有一个问题,我仍然收到其他参数(pagestartlimit)。 @RequestBody 在这种情况下仍然有效吗? @RequestParam(value = "page", required = false) int page, @RequestParam(value = "start", required = false) int start, @RequestParam(value = "limit", required = false) int limit, @RequestBody(required=false) RemoteFilter filter)
  • Content-Type:application/x-www-form-urlencoded 用于表单提交。 filter 参数建议您发送 JSON。换页时是否重新加载页面,还是使用 JavaScript 加载新数据,然后替换部分页面?
  • hmm 明白了。首先页面加载(不带filter 参数),然后用户在列过滤器上键入任何文本,并将带有过滤器数据的新请求发送到服务器。然后服务器返回新数据和页面刷新..但是,在所有情况下,发送其他参数(页面、开始和限制)这就是为什么我认为@RequestBody 可能不起作用,对吧?
猜你喜欢
  • 2016-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多