当我尝试在 spring 引导应用程序中将自定义错误传递给客户端时出现异常
Exception occurs when I try to pass a custom error to client in spring boot application
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
如上所述,我在行响应 .sendError() 方法中遇到错误。我已经在互联网上搜索了 4 天。但我无法弄清楚问题所在。这个问题的原因是什么?
我有一个自定义异常 class。
在下面的代码中,catch 块成功捕获了我的自定义异常。但是当我尝试将它发送到客户端时,它 returns 上面提到的异常。
我已经试过了
解决方案 1 – Controller 级别的@ExceptionHandler
解决方案 2 – HandlerExceptionResolver
解决方案 3 – @ControllerAdvice
解决方案 4 – ResponseStatusException
解决上述问题的方法。但是对我不起作用:(
我已将错误代码和错误消息添加到响应正文中。然后我就可以成功获取错误了。但这不是我想要的方式。
@RequestMapping(value="/getMemberID/", method=RequestMethod.POST ,headers ="Accept=application/json")
public ResponseMemberID getMemberID(@RequestBody RequestMemberID request,HttpServletResponse response, @Context HttpServletRequest _request ) throws Exception {
Member_info memberinfo = new Member_info();
ResponseMemberID _response =new ResponseMemberID();
try {
memberinfo = memberinfoservice.getMemberID(request.getPin(),request.getMsisdn());
_response.setMember_id(memberinfo.getMember_id());
}catch(MemberNotFoundException exp) {
response.sendError(exp.getErrorCode(), exp.getErrorMessage());
}
return _response;
}
我需要使用上述 sendError() 方法获取错误代码和错误消息作为 JSON 响应。异常成功进入 catch 块。
在这里,
1)您需要为自定义异常添加错误处理程序
2) 并且错误处理程序将抛出异常
一些有用的link:
注意:此方法已经过测试,我正在我的应用程序中使用它。
@RestControllerAdvice
@RequestMapping(produces = "application/json")
public class DefaultExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(MemberNotFoundException .class)
@ResponseStatus(value = HttpStatus.CONFLICT)
public Map<String, String> handleConstraintViolationException(ConstraintViolationException ex) {
Map<String, String> response = new HashMap);
// set your response
return new ResponseEntity<>(response, ex.getStatus());
}
}
来自 getMemberID
,删除 try
和 catch
块。
@RestController
@CrossOrigin(origins = "*")
public class MemberController {
@Autowired
MemberInfoService memberinfoservice;
@RequestMapping(value="/getMemberID/", method=RequestMethod.POST ,headers = "Accept=application/json")
public ResponseMemberID getMemberID(@RequestBody RequestMemberID request) throws Exception{
Member_info memberinfo = new Member_info();
ResponseMemberID _response =new ResponseMemberID();
memberinfo = memberinfoservice.getMemberID(request.getPin(),request.getMsisdn());
if(memberinfo == null) {
throw new PINNotValidException();
}
_response.setMember_id(memberinfo.getMember_id());
return _response;
}
@ExceptionHandler(PINNotValidException.class)
public ResponseEntity<ErrorResponse> exceptionHandler(Exception ex) {
ErrorResponse error = new ErrorResponse();
error.setErrorCode(PSAExceptionCodes.PIN_VALIDATION_FAIL);
error.setMessage(ex.getMessage());
return new ResponseEntity<ErrorResponse>(error, HttpStatus.OK);
}
上面提到的是我根据link http://www.jcombat.com/spring/exception-handling-in-spring-restful-web-service修改的代码,它满足了我的问题。
此外,我还尝试在我创建的应用程序中使用 HttpServletResponse class 的 sendError() 方法,但是它总是返回空响应。
但是通过在创建单独的 PINNotValidException.class,ErrorResponse.class 时将 @ExceptionHandler 用于自定义异常,PSAException.class 和 PSAExceptionCodes.class 我可以很容易地解决我提到的 problem.Below 分别是那些 classes。
PINNotValidException.class
public class PINNotValidException extends PSAException{
private static final long serialVersionUID = 1L;
private static String errorMessage = "Pin Number and Mobile Number mismatch.";
private static int errorCode = PSAExceptionCodes.PIN_VALIDATION_FAIL;
public PINNotValidException() {
super(errorMessage, errorCode);
}
}
ErrorResponse.class
public class ErrorResponse {
private int errorCode;
private String message;
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
PSAException.class
public class PSAException extends Exception {
private static final long serialVersionUID= 100L;
private String errorMessage;
private int errorCode;
public String getErrorMessage() {
return errorMessage;
}
public int getErrorCode(){
return errorCode;
}
public PSAException(String errorMessage) {
super(errorMessage);
this.errorMessage = errorMessage;
}
public PSAException(String errorMessage, int errorCode) {
super(errorMessage);
this.errorMessage = errorMessage;
this.errorCode=errorCode;
}
public PSAException() {
super();
}
}
PSAExceptionCodes.class
public class PSAExceptionCodes {
public static final int PIN_VALIDATION_FAIL = 251; //Pin and mobile mismatch
public static final int ACCOUNT_TYPE_NOT_FOUND = 300; //Account type mismatch
public static final int NO_MEMBER_FOUND = 250; //Member Not Found
public static final int MEMBER_NOT_REGISTERED = 256; //Member not registered
}
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
如上所述,我在行响应 .sendError() 方法中遇到错误。我已经在互联网上搜索了 4 天。但我无法弄清楚问题所在。这个问题的原因是什么?
我有一个自定义异常 class。 在下面的代码中,catch 块成功捕获了我的自定义异常。但是当我尝试将它发送到客户端时,它 returns 上面提到的异常。
我已经试过了 解决方案 1 – Controller 级别的@ExceptionHandler 解决方案 2 – HandlerExceptionResolver 解决方案 3 – @ControllerAdvice 解决方案 4 – ResponseStatusException
解决上述问题的方法。但是对我不起作用:(
我已将错误代码和错误消息添加到响应正文中。然后我就可以成功获取错误了。但这不是我想要的方式。
@RequestMapping(value="/getMemberID/", method=RequestMethod.POST ,headers ="Accept=application/json")
public ResponseMemberID getMemberID(@RequestBody RequestMemberID request,HttpServletResponse response, @Context HttpServletRequest _request ) throws Exception {
Member_info memberinfo = new Member_info();
ResponseMemberID _response =new ResponseMemberID();
try {
memberinfo = memberinfoservice.getMemberID(request.getPin(),request.getMsisdn());
_response.setMember_id(memberinfo.getMember_id());
}catch(MemberNotFoundException exp) {
response.sendError(exp.getErrorCode(), exp.getErrorMessage());
}
return _response;
}
我需要使用上述 sendError() 方法获取错误代码和错误消息作为 JSON 响应。异常成功进入 catch 块。
在这里, 1)您需要为自定义异常添加错误处理程序 2) 并且错误处理程序将抛出异常
一些有用的link:
注意:此方法已经过测试,我正在我的应用程序中使用它。
@RestControllerAdvice
@RequestMapping(produces = "application/json")
public class DefaultExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(MemberNotFoundException .class)
@ResponseStatus(value = HttpStatus.CONFLICT)
public Map<String, String> handleConstraintViolationException(ConstraintViolationException ex) {
Map<String, String> response = new HashMap);
// set your response
return new ResponseEntity<>(response, ex.getStatus());
}
}
来自 getMemberID
,删除 try
和 catch
块。
@RestController
@CrossOrigin(origins = "*")
public class MemberController {
@Autowired
MemberInfoService memberinfoservice;
@RequestMapping(value="/getMemberID/", method=RequestMethod.POST ,headers = "Accept=application/json")
public ResponseMemberID getMemberID(@RequestBody RequestMemberID request) throws Exception{
Member_info memberinfo = new Member_info();
ResponseMemberID _response =new ResponseMemberID();
memberinfo = memberinfoservice.getMemberID(request.getPin(),request.getMsisdn());
if(memberinfo == null) {
throw new PINNotValidException();
}
_response.setMember_id(memberinfo.getMember_id());
return _response;
}
@ExceptionHandler(PINNotValidException.class)
public ResponseEntity<ErrorResponse> exceptionHandler(Exception ex) {
ErrorResponse error = new ErrorResponse();
error.setErrorCode(PSAExceptionCodes.PIN_VALIDATION_FAIL);
error.setMessage(ex.getMessage());
return new ResponseEntity<ErrorResponse>(error, HttpStatus.OK);
}
上面提到的是我根据link http://www.jcombat.com/spring/exception-handling-in-spring-restful-web-service修改的代码,它满足了我的问题。
此外,我还尝试在我创建的应用程序中使用 HttpServletResponse class 的 sendError() 方法,但是它总是返回空响应。
但是通过在创建单独的 PINNotValidException.class,ErrorResponse.class 时将 @ExceptionHandler 用于自定义异常,PSAException.class 和 PSAExceptionCodes.class 我可以很容易地解决我提到的 problem.Below 分别是那些 classes。
PINNotValidException.class
public class PINNotValidException extends PSAException{
private static final long serialVersionUID = 1L;
private static String errorMessage = "Pin Number and Mobile Number mismatch.";
private static int errorCode = PSAExceptionCodes.PIN_VALIDATION_FAIL;
public PINNotValidException() {
super(errorMessage, errorCode);
}
}
ErrorResponse.class
public class ErrorResponse {
private int errorCode;
private String message;
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
PSAException.class
public class PSAException extends Exception {
private static final long serialVersionUID= 100L;
private String errorMessage;
private int errorCode;
public String getErrorMessage() {
return errorMessage;
}
public int getErrorCode(){
return errorCode;
}
public PSAException(String errorMessage) {
super(errorMessage);
this.errorMessage = errorMessage;
}
public PSAException(String errorMessage, int errorCode) {
super(errorMessage);
this.errorMessage = errorMessage;
this.errorCode=errorCode;
}
public PSAException() {
super();
}
}
PSAExceptionCodes.class
public class PSAExceptionCodes {
public static final int PIN_VALIDATION_FAIL = 251; //Pin and mobile mismatch
public static final int ACCOUNT_TYPE_NOT_FOUND = 300; //Account type mismatch
public static final int NO_MEMBER_FOUND = 250; //Member Not Found
public static final int MEMBER_NOT_REGISTERED = 256; //Member not registered
}