2011-12-21 32 views
21

Tôi có một lớp ngoại lệ tùy chỉnh chú thích để trả về một trao HttpStatus:Trong Spring 3 có thể tự động đặt lý do của @ResponseStatus không?

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

này hoạt động khi tôi ném một BadRequestException từ bộ điều khiển của tôi nhưng lý do luôn luôn là "tham số không hợp lệ" tất nhiên rồi. Có cách nào để thiết lập lý do trả về trong lớp này không? Tôi muốn vượt qua một chuỗi được sử dụng như là lý do.

Cảm ơn!

Trả lời

12

Bạn có thể sử dụng response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid foo");

+0

Đơn giản nhưng hiệu quả - cảm ơn bạn! – Paul

+0

phản ứng là gì? – user3871754

+0

@ user3871754, 'phản hồi' có thể thu được trong phương pháp điều khiển. Những gì @ Bozho nói rằng thay vì ném một ngoại lệ trong phương pháp điều khiển của tôi, tôi nên gọi 'response.sendError'. – Paul

-2

"Lý do" là tùy chọn, vì vậy bạn có thể bỏ qua và thực hiện phương thức trừu tượng chuỗi công khai lý do truyền lỗi. Link: http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/bind/annotation/ResponseStatus.html

+0

Bạn có ý nghĩa gì bởi * "và triển khai phương thức trừu tượng công khai Chuỗi lý do truyền lỗi" *? Tôi không nghĩ rằng chỉ cần thêm một phương thức 'reason' hoặc' getReason' vào lớp public 'BadRequestException của OP mở rộng RuntimeException' sẽ cho phép một thiết lập tự động một tin nhắn? – Arjan

2

Chú thích có nghĩa là để được tĩnh, và không thể được thiết lập tự động từ lớp học của bạn. Tôi khuyên bạn nên tạo một lớp con của BadRequestException cho mọi loại kịch bản lỗi và chú thích chúng theo cách khác nhau.

Điều này không chỉ phục vụ như một giải pháp - nếu bạn đang ẩn chi tiết về những gì đã xảy ra trong thông báo reason, thì bạn sẽ mất tính linh hoạt vì bất kỳ mã nào bắt được BadRequestException sẽ phải xử lý tất cả kịch bản thất bại theo cùng một cách.

+0

Trong trường hợp này, mã cuối cùng giao dịch với ngoại lệ phải xử lý nó theo cùng một cách ... bộ điều khiển đang phản hồi yêu cầu không đồng bộ từ một giao diện người dùng JavaScript. Trên bất kỳ – Paul

+1

Tôi hiểu ý của bạn là gì. Tôi vẫn cho rằng đó là thiết kế tốt không có hại (ngoài việc giới thiệu một vài lớp ngoại lệ hơn bạn đã có), nhưng nếu bạn có khuynh hướng đi một con đường khác, phương pháp Bozho đã đề cập và/hoặc mô tả ở đây có thể hữu ích: http://forum.springsource.org/showthread.php?100267-Changing-ResponseStatus-from-within-controller-method. Hy vọng rằng sẽ giúp! –

11

Cách đúng là để giới thiệu bộ xử lý ngoại lệ trong điều khiển của bạn, sau đó bạn có thể thiết lập cơ thể phản ứng của bất kỳ mã trạng thái:

@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; 
    } 
} 

Move trên bạn không cần phải làm ô nhiễm các lớp mô hình/ngoại trừ của bạn với bất kỳ Spring Web MVC chú thích và phụ thuộc.

Nếu bạn muốn chia sẻ trình xử lý với tất cả bộ điều khiển, hãy xem @ControllerAdvice.

+0

Câu hỏi đặt ra cụm từ lý do, không phải là nội dung. – Jakub

1

Cách dễ nhất để chỉ đặt response.setStatus(). Dễ dàng và sạch sẽ, bạn có thể thay đổi trạng thái này thành bất kỳ trạng thái nào bạn muốn thay vì ex.getStatusCode() thêm mã của bạn.

Loại trả về cũng là lựa chọn của bạn, tôi đang sử dụng Chuỗi b/c hiển thị sau này.

Bằng cách này, sendError không phải là một ý tưởng hay, bởi vì JBoss chẳng hạn đang thêm rất nhiều HTML vào phản hồi.

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

Nếu bạn bỏ qua thuộc tính 'lý do' trong chú thích @ResponseStatus trên một ngoại lệ tùy chỉnh,

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

sau đó ném ngoại lệ

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

Thông điệp của ngoại lệ đi qua như 'thông điệp' của 'dữ liệu' trong đầu ra JSON. Có vẻ như 'lý do' trong chú thích ghi đè hành vi tùy chỉnh.

+0

Huh, có vẻ như tôi đã sử dụng tính năng này vài lần mà không biết. Cảm ơn! – Mateusz

+2

Đã không làm việc cho tôi. Tôi đặt mã trạng thái thành BAD_REQUEST (400) nhưng đã nhận 'Yêu cầu không hợp lệ' làm cả lỗi và trường thông báo. Ngay cả khi thông báo ngoại lệ được đặt trong đối tượng ngoại lệ của tôi. –

+0

Điều này làm việc tuyệt vời. Cảm ơn bạn. Điều này là dễ dàng hơn nhiều sau đó có bắt đặc biệt để ném lỗi. – gcerkez

Các vấn đề liên quan