Spring-MVC использует конвертер для загрузки объекта из переменной пути, но для возврата нужно 404

TL;DR - есть ли способ выдать ошибку из зарегистрированного преобразователя типов во время фазы привязки данных MVC, чтобы он возвращал ответ с определенным кодом состояния HTTP? Т.е. если мой конвертер не может найти объект из источника конверсии, могу ли я вернуть 404?

У меня есть POJO:

public class Goofball {
    private String id = "new";
    // others
    public String getName () { ... }
    public void setName (String name) { ... }
}

и я использую StringToGoofballConverter, чтобы создать пустой объект, когда "new".equals(id) или попробуйте загрузить Goofball из базы данных, если она существует:

public Goofball convert(String idOrNew) {
    Goofball result = null;

    log.debug("Trying to convert " + idOrNew + " to Goofball");

    if ("new".equalsIgnoreCase(idOrNew))
    {
        result = new Goofball ();
        result.setId("new");
    }
    else
    {
        try
        {
            result = this.repository.findOne(idOrNew);
        }
        catch (Throwable ex)
        {
            log.error (ex);
        }

        if (result == null)
        {
            throw new GoofballNotFoundException(idOrNew);
        }
    }

    return result;
}

Этот конвертер используется Spring, когда запрос соответствует этой конечной точке:

@RequestMapping(value = "/admin/goofballs/{goofball}", method=RequestMethod.POST)
public String createOrEditGoofball (@ModelAttribute("goofball") @Valid Goofball object, BindingResult result, Model model) {
    // ... handle the post and save the goofball if there were no binding errors, then return the template string name
}

Это все работает довольно хорошо, поскольку GET запрашивает /admin/goofballs/new а также /admin/goofballs/1234 Плавно работать в контроллере как для создания новых объектов, так и для редактирования существующих. Проблема в том, что если я выдаю запрос с поддельным идентификатором, то это не new и также не существует в базе данных, я хочу вернуть 404. В настоящее время конвертер выдает пользовательское исключение:

@ResponseStatus(value= HttpStatus.NOT_FOUND, reason="Goofball Not Found") //404
public class GoofballNotFoundException extends RuntimeException {

    private static final long serialVersionUID = 422445187706673678L;

    public GoofballNotFoundException(String id){
        super("GoofballNotFoundException with id=" + id);
    }
}

но я начал с простого IllegalArgumentException, как рекомендовано в документации Spring. В любом случае в результате Spring возвращает ответ с HTTP-статусом 400.

Это заставляет меня думать, что я неправильно использую интерфейс Converter, но этот подход рекомендуется в документации @ModelAttribute.

Итак, еще раз вопрос: есть ли способ выдать ошибку из зарегистрированного преобразователя типов во время фазы привязки данных, чтобы он возвращал ответ с определенным кодом состояния HTTP?

1 ответ

Отвечая на мой собственный вопрос:

+ Изменить StringToGoofballConverter просто вернуться null для не найденного лица вместо того, чтобы бросать IllegalArgumentException или пользовательское исключение. @Controller Затем метод будет Goofball объект, который имеет null идентификатор (например, идентификатор не является "новым" или значением элемента пути). В этот момент я могу бросить GoofballNotFoundException или любой другой @ResponseStatus исключение оттуда, в методе контроллера, чтобы повлиять на код состояния ответа.

Другие вопросы по тегам