在Spring 3中是否可以动态设置@ResponseStatus的原因?

时间:2011-12-21 18:35:03

标签: java spring spring-mvc

我有一个自定义的异常类,用于返回给定的HttpStatus

@ResponseStatus(value=HttpStatus.BAD_REQUEST, reason="Invalid parameter")
public class BadRequestException extends RuntimeException
{
  public BadRequestException(String msg)
  {
    super(msg);
  }
}

当我从我的控制器中抛出BadRequestException时,这是有效的,但原因始终是“无效参数”。有没有办法在这个类中设置返回的原因?我想传递一个字符串作为原因。

谢谢!

7 个答案:

答案 0 :(得分:12)

您可以使用response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid foo");

答案 1 :(得分:12)

如果在自定义异常的@ResponseStatus注释中省略'reason'属性,

@ResponseStatus(value = HttpStatus.CONFLICT)  // 409
public class ChildDataExists extends RuntimeException {
...

然后抛出异常

throw new ChildDataExists("Can't delete parent if child row exists.");

异常的消息作为JSON输出中“数据”的“消息”出现。注释中的“原因”似乎会覆盖自定义行为。

答案 2 :(得分:11)

正确的方法是在控制器中引入异常处理程序,然后可以设置任何状态代码的响应主体:

@Controller
@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public class SomeController {
...
  @ExceptionHandler(BadRequestException.class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  public @ResponseBody
   Map<String,Object> handleIndexNotFoundException(BadRequestException bre,
                                           HttpServletRequest request, HttpServletResponse resp) {
     HashMap<String, Object> result = new HashMap<>();
     result.put("error", true);
     result.put("error_message", bre.getMessage());
     return result;
  }
}

移动您不必使用任何Spring Web MVC注释和依赖项污染您的模型/异常类。

如果您想与所有控制器共享处理程序,请查看@ControllerAdvice

答案 3 :(得分:2)

注释是静态的,不能从您的类动态设置。我建议为每种类型的失败场景创建BadRequestException的子类,并以不同的方式对它们进行注释。

这不仅仅是一种解决方法 - 如果您隐藏有关reason消息中出现问题的详细信息,那么您将失去灵活性,因为任何捕获{{1}的代码必须以同样的方式处理所有失败场景。

答案 4 :(得分:2)

从Spring 5.0开始,您可以使用可用的ResponseStatusException

// From https://www.baeldung.com/spring-response-status-exception
@GetMapping("/actor/{id}")
public String getActorName(@PathVariable("id") int id) {
    try {
        return actorService.getActor(id);
    } catch (ActorNotFoundException ex) {
        throw new ResponseStatusException(
          HttpStatus.NOT_FOUND, "Actor Not Found", ex);
    }
}

答案 5 :(得分:1)

设置response.setStatus()的最简单方法。简单而干净,您可以将其更改为您想要的任何状态,而不是ex.getStatusCode()添加您的代码。

返回类型也是您的选择,我正在使用String b / c稍后显示。

顺便说一句,sendError并不是一个好主意,因为JBoss正在为响应添加大量HTML。

@ExceptionHandler(CommunicationException.class)
@ResponseBody()
public String handleCommunicationException(CommunicationException ex, HttpServletResponse response) throws IOException{
    response.setStatus(ex.getStatusCode());
    return ex.getStatusMessage();   
}

答案 6 :(得分:-2)

“reason”是可选的,因此您可以省略它并实现抽象方法public String reason传递Error。 链接:http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/bind/annotation/ResponseStatus.html