Исключить ModelAttribute из представления

У меня есть приложение для отдыха, которое возвращает json/xml. Я использую jackson и jaxb для преобразования. Некоторые методы должны принимать query_string. Я использовал @ModelAttribute для сопоставления строки запроса с объектом, но это вынуждает объект отображаться в моем представлении. Я не хочу, чтобы объект отображался в представлении.

Я думаю, что мне нужно использовать что-то другое, кроме @ModelAttribute, но я не могу понять, как сделать привязку, но не изменить представление. Если я опускаю аннотацию @ModelAttribute, объект отображается в представлении как имя переменной (например: «sourceBundleRequest»).

Пример URL:

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
}

person John Vinopal    schedule 24.08.2012    source источник


Ответы (3)


Вам не нужно аннотировать форму с помощью @ModelAttribute, если вы не хотите, чтобы форма возвращалась в представление, она будет четко привязана к SourceBundleRequest даже без аннотации @ModelAttribute.

Теперь стандартный способ вернуть ответ JSON/XML с использованием Spring MVC состоит в том, чтобы вернуть тип напрямую (в вашем случае PaginatedResponse), а затем аннотировать метод с помощью @ResponseBody , базовый HttpMessageConverter затем преобразует ответ в XML/JSON на основе в заголовке Accept от клиента.

@ResponseBody
public RestResponse<PaginatedResponse> getAll(SourceBundleRequest sourceBundleRequest, BindingResult result, ModelMap model)
...
person Biju Kunjummen    schedule 25.08.2012
comment
К сожалению, простое исключение @ ModelAttribute у меня не работает. Я обновил свой OP с подробностями. В настоящее время я бы предпочел не идти по маршруту @ ResponseBody. Мне нравится мое явное сопоставление представлений, и я не хочу вдаваться в проблемы с заголовком Accept. - person John Vinopal; 31.08.2012

Как-то я пропустил самый очевидный способ исправить это. Я сосредоточился на атрибутах и ​​забыл, что могу просто изменить базовую карту.

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

Возможно, было бы немного эффективнее опустить @ModelAttribute, как предложил Биджу, а затем удалить объект sourceBundleRequest. Я подозреваю, что @ModelAttribute имеет некоторые дополнительные накладные расходы.

person John Vinopal    schedule 30.08.2012

Как насчет использования @JsonIgnore?

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

Не тестировал это

person Marc    schedule 27.04.2014