【问题标题】:Omit ModelAttribute from view从视图中省略 ModelAttribute
【发布时间】:2012-08-20 12:05:57
【问题描述】:

我有一个返回 json/xml 的休息应用程序。我使用 jackson 和 jaxb 进行转换。有些方法需要接受一个 query_string。我已经使用@ModelAttribute 将 query_string 映射到一个对象中,但这会强制该对象进入我的视图。我不希望对象出现在视图中。

我想我需要使用@ModelAttribute 以外的东西,但我不知道如何进行绑定,但不修改视图。如果我省略了@ModelAttribute 注释,该对象将作为变量名出现在视图中(例如:“sourceBundleRequest”)。

示例网址:

http://localhost:8080/rest/sourcebundles/?updateDate=20100501&label=urgent

控制器方法:

@RequestMapping(value = {"", "/"}, method = RequestMethod.GET)
public String getAll(@ModelAttribute("form") SourceBundleRequest sourceBundleRequest, BindingResult result, ModelMap model) throws ApiException {
    // Detect and report errors.
    if (result.hasErrors()) {
       // (omitted for clarity)
    }

    // Fetch matching data.
    PaginatedResponse<SourceBundle> sourceBundleResponse = null;
    try {
        int clientId = getRequestClientId();
        sourceBundleResponse = sourceBundleService.get(clientId, sourceBundleRequest);
    } catch (ApiServiceException e) {
        throw new ApiException(ApiErrorType.INTERNAL_ERROR, "sourceBundle fetch failed");
    }

    // Return the response.
    RestResponse<PaginatedResponse> restResponse = new RestResponse<PaginatedResponse>(200, "OK");
    restResponse.setData(sourceBundleResponse);
    model.addAttribute("resp", restResponse);
    // XXX - how do I prevent "form" from appearing in the view?
    return "restResponse";
}

示例输出:

"form": {
    "label": "urgent",
    "updateDate": 1272697200000,
    "sort": null,
    "results": 5,
    "skip": 0
},
"resp": {
    "code": 200,
    "status": "OK",
    "data": {
        "totalAvailable": 0,
        "resultList": [ ]
    }
}

期望的输出:

"resp": {
    "code": 200,
    "status": "OK",
    "data": {
        "totalAvailable": 0,
        "resultList": [ ]
    }
}

省略@ModelAttribute("form")

如果我简单地省略 @ModelAttribute("form"),我仍然会得到不希望的响应,但传入的表单是由对象名称命名的。响应如下所示:

"resp": {
    "code": 200,
    "status": "OK",
    "data": {
        "totalAvailable": 0,
        "resultList": [ ]
    }
},
"sourceBundleRequest": {
    "label": "urgent",
    "updateDate": 1272697200000,
    "sort": null,
    "results": 5,
    "skip": 0
}

【问题讨论】:

    标签: spring-mvc modelattribute


    【解决方案1】:

    如果您不希望表单返回视图,则无需使用@ModelAttribute 注释表单,即使没有@ModelAttribute 注释,它也会干净利落地绑定到SourceBundleRequest

    现在,使用 Spring MVC 返回 JSON/XML 响应的标准方法是直接返回类型(在您的情况下为 PaginatedResponse),然后使用 @ResponseBody 注释方法,然后底层 HttpMessageConverter根据来自客户端的 Accept 标头将响应转换为 XML/JSON。

    @ResponseBody
    public RestResponse<PaginatedResponse> getAll(SourceBundleRequest sourceBundleRequest, BindingResult result, ModelMap model)
    ...
    

    【讨论】:

    • 不幸的是,简单地省略 @ModelAttribute 对我不起作用。我已经用详细信息更新了我的 OP。我目前不想走@ResponseBody 路线。我喜欢我的显式视图映射,不想陷入 Accept 标头问题。
    【解决方案2】:

    不知何故,我错过了解决此问题的最明显方法。我专注于属性,忘记了我可以只修改底层地图。

      // Remove the form object from the model map.
      model.remove("form");
    

    按照 Biju 的建议省略 @ModelAttribute 然后删除 sourceBundleRequest 对象可能会更有效一些。我怀疑@ModelAttribute 有一些额外的开销。

    【讨论】:

      【解决方案3】:

      使用@JsonIgnore 怎么样?

      @ModelAttribute("foo")
      @JsonIgnore
      public Bar getBar(){}
      

      没有测试过

      【讨论】:

        猜你喜欢
        • 2013-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-09
        • 2011-08-02
        • 2011-07-02
        • 1970-01-01
        相关资源
        最近更新 更多