标签:ttl err 场景 对象 exception ext color 信息 客户
@RequestMapping(value = "/{id}", method = RequestMethod.GET) public @ResponseBody Spittle spittleById(@PathVariable Long id) { return spittleRepository.findOne(id); }
上述方法是查找一个Spittle对象。
假设找不到,则返回null,这时候,返回给客户端的HTTP状态码是200(OK),代表事情正常运行,但是数据是空的。
而我们希望这种情况下或许可以使状态码未404(Not Found),这样客户端就知道发生了什么错误了。
要实现这种功能,Spring提供了一下几种方式:
a、使用@ResponseStatus注解指定状态码
b、控制器方法可以返回ResponseEntity对象,改对象能够包含更多响应相关元数据
c、异常处理器能够应对错误场景,这样处理器方法就能关注于正常的状况
使用ResponseEntity对象替代@ResponseBody
@RequestMapping(value = "/{id}", method = RequestMethod.GET) public ResponseEntity<Spittle> spittleById(@PathVariable Long id) { return spittleRepository.findOne(id); HttpStatus status = spittle != null ? HttpStatus.OK : HttpStatus.NOT_FOUND; return new ResponseEntity<Spittle>(spittle, status); }
使用ResponseEntity,可以指定HTTP状态码,而且本身也包含@ResponseBody的定义,相当于使用了@ResponseBody。
接下来,我们希望如果找不到Spittle对象时,返回错误信息
可以创建一个Error类,然后使用泛型,在找不到Spittle对象时,返回一个Error对象
@RequestMapping(value = "/{id}", method = RequestMethod.GET) public ResponseEntity<?> spittleById(@PathVariable Long id) { return spittleRepository.findOne(id); if (spittle == null){ Error error = new Error(4, "Spittle [" + id + "] not found"); return new ResponseEntity<Error>(error, HttpStatus.NOT_FOUND); } return new ResponseEntity<Spittle>(spittle, HttpStatus.OK); }
但是,这种写法貌似使代码变得有点复杂,我们可以考虑使用错误处理器。
步骤1:创建一个异常类
public class SpittleNotFoundException extends RuntimeException { private static final long serialVersionUID = 1L; private long spittleId; public SpittleNotFoundException(long spittleId) { this.spittleId = spittleId; } public long getSpittleId() { return spittleId; } }
步骤2:在控制器下创建一个错误处理器的处理方法
@ExceptionHandler(SpittleNotFoundException.class) public ResopnseEntity<Error> spittleNotFound(SpittleNotFoundException e) { long spittleId = e.getSpittleId(); Error error = new Error(4, "Spittle [" + spittleId + "] not found"); return new ResponseEntity<Error>(error, HttpStatus.NOT_FOUND); }
@ExceptionHandler注解加到控制器方法中,可以处理对应的异常。
如果请求A发生异常,被这个方法捕获到该异常, 那么请求的返回值就是这个异常处理器的返回值。
步骤3:原来的业务控制器方法可以得到简化
@RequestMapping(value = "/{id}", method = RequestMethod.GET) public ResponseEntity<Spittle> spittleById(@PathVariable Long id) { return spittleRepository.findOne(id); if (spittle == null) { throw new SpittleNotFoundException(id); } return new ResponseEntity<Spittle>(spittle, HttpStatus.OK); }
又因为此时任何时候,这个控制方法都有数据返回,所以HTTP状态码始终是200,所以可以不使用ResponseEntity,二使用@ResponseBody;如果控制器上面还使用了@RestController,我们又可以把@ResponseBody省掉, 最后得到代码
@RequestMapping(value = "/{id}", method = RequestMethod.GET) public Spittle spittleById(@PathVariable Long id) { return spittleRepository.findOne(id); if (spittle == null) { throw new SpittleNotFoundException(id); } return Spittle; }
步骤4:同理,可以简化一下错误处理器
@ExceptionHandler(SpittleNotFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public Error spittleNotFound(SpittleNotFoundException e) { long spittleId = e.getSpittleId(); return new Error(4, "Spittle [" + spittleId + "] not found"); }
在简化过程中,我们都希望避免使用ResponseEntity,因为他会导致代码看上来很复杂。
但是有的情况必须使用ResponseEntity才能实现某些功能。
要使用到ResponseEntity,比如说我新建一个Spittle后,系统通过HTTP的Location头部信息,返回这个Spittle的URL资源地址。
这里暂时不讨论
标签:ttl err 场景 对象 exception ext color 信息 客户
原文地址:https://www.cnblogs.com/LiveYourLife/p/9145667.html