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
在控制器中顺利工作以创建新对象和编辑现有对象。问题是,如果我发出一个带有虚假 id 的请求,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);
}
}
但我从Spring docs中推荐的简单 IllegalArgumentException 开始。无论哪种情况,结果都是 Spring 返回一个 HTTP 状态为 400 的响应。
这让我觉得我在滥用 Converter 接口,但@ModelAttribute docs 似乎推荐了这种方法。
那么,问题又来了:有没有办法在数据绑定阶段从已注册的类型转换器中抛出错误,以便它返回带有特定 HTTP 状态代码的响应?