2011-12-21 43 views
21

我有一個自定義異常類註釋返回給定HttpStatus在Spring 3中,是否可以動態設置@ResponseStatus的原因?

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

此,當我從我的控制器拋出BadRequestException但原因始終是當然的「無效參數」的作品。有沒有辦法在這個類中設置返回的原因?我想傳遞一個字符串作爲原因。

謝謝!

回答

12

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

+0

簡單而有效 - 謝謝! – Paul 2011-12-21 20:51:24

+0

什麼是響應? – user3871754 2016-10-17 15:35:08

+0

@ user3871754,可以在控制器方法中獲得「響應」。 @ Bozho的說法是,我不應該在我的控制器方法中拋出異常,而應該調用'response.sendError'。 – Paul 2017-05-23 16:31:02

-2

「原因」是可選的,所以你可以省略它並實現抽象方法public String reason傳遞Error。 鏈接:http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/bind/annotation/ResponseStatus.html

+0

你是什麼意思*「並實現了抽象方法public String reason傳遞錯誤」*?我不認爲只給OP的'public class BadRequestException extends RuntimeException'添加一個'reason'或'getReason'方法會允許動態設置一條消息? – Arjan 2013-02-04 15:33:03

2

註解意味着是靜態的,並且不能從你的類動態設置。我建議爲每種類型的故障情況創建一個BadRequestException的子類,並對它們進行不同的註釋。

這不只是作爲一種解決方法 - 如果你隱藏了有關什麼地方出了錯在reason消息,那麼你就失去了靈活性,因爲能夠抓住一個BadRequestException任何代碼都必須處理所有的細節失敗情況也是如此。

+0

在這種情況下,最終處理異常的代碼必須以相同的方式處理它...控制器響應來自JavaScript前端的異步請求。在任何 – Paul 2011-12-21 20:00:42

+1

我明白你的意思。我仍然認爲這是一個好的設計,沒有任何傷害(除了引入幾個比你已經擁有的更多的Exception類),但是如果你傾向於嘗試不同的路線,Bozho提到的方法和/或描述的方法這可能是有用的:http://forum.springsource.org/showthread.php?100267-Changing-ResponseStatus-from-within-controller-method。希望有所幫助! – 2011-12-21 20:21:25

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

+0

問題是關於設置原因短語,而不是正文。 – Jakub 2016-03-15 11:06:04

1

設置response.setStatus()的最簡單方法。簡單而乾淨,您可以將其更改爲任何您想要的狀態,而不是ex.getStatusCode()添加您的代碼。

返回類型也是你的選擇,我用字符串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(); 
} 
8

如果忽略在一個自定義異常的@ResponseStatus註釋的「理由」屬性,

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

然後拋出異常

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

異常的消息出現過的JSON輸出中'data'的'消息'。看起來註解中的「原因」會覆蓋自定義行爲。

+0

呵呵,似乎我幾次都不知道這個功能。謝謝! – Mateusz 2017-01-26 16:45:22

+2

沒有爲我工作。我將狀態碼設置爲BAD_REQUEST(400),但在錯誤和消息字段中都收到了「錯誤的請求」。即使異常消息是在我的異常對象中設置的。 – 2017-06-30 11:21:11

+0

這很好用。謝謝。這是非常容易,然後有特殊的漁獲投擲錯誤。 – gcerkez 2017-08-01 19:04:01

相關問題