Spring MVC - как вернуть 404 по отсутствующим параметрам

Я хочу вызвать страницу 404 всякий раз, когда мне не передавали все параметры. Допустим, у меня есть следующий URI:

/myapp/op?param1=1&[email protected]=3

В случае, если параметр wasn; t invoked, я хочу вернуть страницу 404. Я пробовал:

@ResponseStatus(HttpStatus.NOT_FOUND)
@RequestMapping(value = "op", params = { "!param1" })
public void missingArg() {
}

но затем я получаю исключение, говорящее, что существует двусмысленность между методами, которые обрабатывают отсутствующие второй и третий параметры.

Как я могу выполнить это?

Ответ 1

Если вы используете Spring 3.1, вы можете определить класс исключения следующим образом:

@ResponseStatus(value = HttpStatus.NOT_FOUND)
public final class ResourceNotFoundException extends RuntimeException {
   //  class definition
}

Теперь, когда вы выбрали это исключение, Spring вернет статус http, указанный в аннотации @ResponseStatus. Например:

@RequestMapping(value = "/op")
public void methodWithRequestParams(@RequestParam(value = "param1", required = false) String param1, 
        @RequestParam(value = "param2", required = false) String param2) {
  if (param1 == null || param2 == null) {
    throw new ResourceNotFoundException();
  }
}

возвращает 404, когда param1 или param2 имеет значение null.

Ответ 2

Вам не нужно реализовывать функцию missingArg(). Если для входящего запроса нет метода сопоставления, то Spring HandlerExceptionResolver обработает его и вернет ответ с соответствующим кодом состояния.

Spring автоматически преобразует параметры запроса в параметры метода, если вы используете аннотацию @RequestParam:

@RequestMapping(value = "/op")
public void methodWithRequestParams(@RequestParam("param1") String param1, 
        @RequestParam("param2") String param2, 
        @RequestParam("param3") String param3) {

    // do something with params
}

По соглашению метод methodWithRequestParams() не будет вызываться, если не все параметры являются частью запроса (если для атрибута required для @RequestParam установлено значение false).

Также обратите внимание, что параметры не обязательно должны быть строками.

Ответ 3

Повторяя то, что сказал matsev в комментариях к другому ответу, вы не должны использовать @ResponseStatus(HttpStatus.NOT_FOUND) в этом случае, а скорее @ResponseStatus(HttpStatus.BAD_REQUEST).

@ResponseStatus(HttpStatus.NOT_FOUND) следует использовать, когда запрос был сформирован правильно, но ресурса там нет.