目录
目录
1 引言
2 什么是异常
2.1 Java中的异常体系
3 常见的处理方式
3.1 参数传递结果
3.2 每个方法都返回结果对象,或者状态码
错误码
调用的方法都返回错误码
3.3 自定义异常并捕获处理
异常定义
异常处理
4 spring-boot中处理方式
4.1 controller
4.2 数据传输对象
4.4 解释注解
4.5 全局处理异常
5 效果
5.1 自定义参数异常
5.2 自定义校验注解异常
1 引言
异常处理是程序员开发的必修课。
2 什么是异常程序运行中的非正常行为,例如给用户的录入不符合规范,或者由于疏忽有的对象没有赋值,或者使用数组时调用的下标超标等等都可以称为程序的异常。异常都会造成程序出错中断,是很严重的行为,所以我们要处理可能出现的各种异常。
2.1 Java中的异常体系待补充理论知识
3 常见的处理方式处理异常的方式很多。
3.1 参数传递结果以下代码模拟登录 *** 作,传入的用户名和密码,先后经过用户名校验、密码校验、查询数据库,并返回结果。这里使用Response透传整个处理流程。
package com.param.validate.main; import com.alibaba.fastjson.JSON; import com.param.validate.common.constant.UserConstant; import com.param.validate.common.enums.ResponseCode; import com.param.validate.dto.UserDTO; import com.param.validate.vo.Response; import com.param.validate.vo.UserVO; public class LoginMain { public Response3.2 每个方法都返回结果对象,或者状态码 错误码login(UserDTO userDTO){ // 事先声明一个最终对象,该对象会伴随后续处理 Response response = new Response<>(); checkUsername(userDTO.getUsername(),response); if(response.getCode()!=null){ return response; } checkPassword(userDTO.getUsername(),response); if(response.getCode()!=null){ return response; } UserVO userVO = mockQueryUserInfo(userDTO.getUsername(), userDTO.getPassword()); response.setCode(ResponseCode.OK.getCode()); response.setMessage(ResponseCode.OK.getMessage()); response.setResult(userVO); return response; } public void checkUsername(String username, Response response){ // 不能为空 if(null==username||username.length()==0){ response.setCode(ResponseCode.USERNAME_EMPTY.getCode()); response.setMessage(ResponseCode.USERNAME_EMPTY.getMessage()); return; } // 长度不能超过32位 if(username.length()> UserConstant.USERNAME_LIMIT){ response.setCode(ResponseCode.USERNAME_INVALID.getCode()); response.setMessage(ResponseCode.USERNAME_INVALID.getMessage()); } } public void checkPassword(String password,Response response){ // 不能为空 if(null==password||password.length()==0){ response.setCode(ResponseCode.PASSWORD_EMPTY.getCode()); response.setMessage(ResponseCode.PASSWORD_EMPTY.getMessage()); return; } // 长度不能超过16位 if(password.length()> UserConstant.PASSWORD_LIMIT){ response.setCode(ResponseCode.PASSWORD_INVALID.getCode()); response.setMessage(ResponseCode.PASSWORD_INVALID.getMessage()); } } public UserVO mockQueryUserInfo(String username, String password) { return UserVO.builder().username(username) .password(password) .age(18) .sex("男").build(); } public static void main(String[] args) { UserDTO userDTO = new UserDTO("","123456"); LoginMain loginMain = new LoginMain(); Response login = loginMain.login(userDTO); System.out.println(JSON.toJSonString(login)); } }
package com.param.validate.common.enums; import com.param.validate.vo.Response; import lombok.Getter; import org.springframework.http.HttpStatus; @Getter public enum ResponseCode { OK(HttpStatus.OK, 0, "成功"), USERNAME_EMPTY(HttpStatus.BAD_REQUEST, -100001, "用户名为空"), USERNAME_INVALID(HttpStatus.BAD_REQUEST, -100002, "用户名无效"), PASSWORD_EMPTY(HttpStatus.BAD_REQUEST, -100003, "密码为空"), PASSWORD_INVALID(HttpStatus.BAD_REQUEST, -100004, "密码无效"), PARAM_ERROR(HttpStatus.BAD_REQUEST,-100005,"参数错误"), QUERY_USERNAME_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, -200001, "查询用户名异常"), UNKOWN(HttpStatus.INTERNAL_SERVER_ERROR, -200002, "未知错误"); private HttpStatus httpStatus; private Integer code; private String message; ResponseCode(HttpStatus httpStatus, Integer code, String message) { this.httpStatus = httpStatus; this.code = code; this.message = message; } }调用的方法都返回错误码
package com.param.validate.main; import com.alibaba.fastjson.JSON; import com.param.validate.common.constant.UserConstant; import com.param.validate.common.enums.ResponseCode; import com.param.validate.dto.UserDTO; import com.param.validate.vo.Response; import com.param.validate.vo.UserVO; import org.apache.catalina.User; public class LoginOtherMain { public Response3.3 自定义异常并捕获处理login(UserDTO userDTO){ ResponseCode responseCode = checkUsername(userDTO.getUsername()); if(responseCode!=null){ return Response.error(responseCode); } ResponseCode code = checkPassword(userDTO.getUsername()); if(code!=null){ return Response.error(code); } Response response = new Response (); UserVO userVO = mockQueryUserInfo(userDTO.getUsername(), userDTO.getPassword()); response.setCode(ResponseCode.OK.getCode()); response.setMessage(ResponseCode.OK.getMessage()); response.setResult(userVO); return response; } public ResponseCode checkUsername(String username){ // 不能为空 if(null==username||username.length()==0){ return ResponseCode.USERNAME_EMPTY; } // 长度不能超过32位 if(username.length()> UserConstant.USERNAME_LIMIT){ return ResponseCode.USERNAME_INVALID; } return null; } public ResponseCode checkPassword(String password){ // 不能为空 if(null==password||password.length()==0){ return ResponseCode.PASSWORD_EMPTY; } // 长度不能超过16位 if(password.length()> UserConstant.PASSWORD_LIMIT){ return ResponseCode.PASSWORD_INVALID; } return null; } public UserVO mockQueryUserInfo(String username, String password) { return UserVO.builder().username(username) .password(password) .age(18) .sex("男").build(); } public static void main(String[] args) { UserDTO userDTO = new UserDTO("","123456"); LoginOtherMain loginOtherMain = new LoginOtherMain(); Response login = loginOtherMain.login(userDTO); System.out.println(JSON.toJSonString(login)); } }
自定义异常并捕获处理。
异常定义package com.param.validate.common.exception; import com.param.validate.common.enums.ResponseCode; import lombok.Getter; import lombok.Setter; @Setter @Getter public class LoginExcetion extends RuntimeException{ private ResponseCode code; public LoginExcetion (ResponseCode code) { super(code.getMessage()); this.code = code; } @Override public Throwable fillInStackTrace() { return this; } }异常处理
package com.param.validate.main; import com.alibaba.fastjson.JSON; import com.param.validate.common.constant.UserConstant; import com.param.validate.common.enums.ResponseCode; import com.param.validate.common.exception.LoginExcetion; import com.param.validate.dto.UserDTO; import com.param.validate.vo.Response; import com.param.validate.vo.UserVO; import org.apache.catalina.User; import org.apache.logging.log4j.LoggingException; public class LoginOtherMain { public Response4 spring-boot中处理方式 4.1 controllerlogin(UserDTO userDTO) { checkUsername(userDTO.getUsername()); checkPassword(userDTO.getUsername()); UserVO userVO = mockQueryUserInfo(userDTO.getUsername(), userDTO.getPassword()); Response response = new Response (); response.setCode(ResponseCode.OK.getCode()); response.setMessage(ResponseCode.OK.getMessage()); response.setResult(userVO); return response; } public void checkUsername(String username) { // 不能为空 if (null == username || username.length() == 0) { throw new LoginExcetion(ResponseCode.USERNAME_EMPTY); } // 长度不能超过32位 if (username.length() > UserConstant.USERNAME_LIMIT) { throw new LoginExcetion(ResponseCode.USERNAME_INVALID); } } public void checkPassword(String password) { // 不能为空 if (null == password || password.length() == 0) { throw new LoginExcetion(ResponseCode.PASSWORD_EMPTY); } // 长度不能超过16位 if (password.length() > UserConstant.PASSWORD_LIMIT) { throw new LoginExcetion(ResponseCode.PASSWORD_INVALID); } } public UserVO mockQueryUserInfo(String username, String password) { return UserVO.builder().username(username) .password(password) .age(18) .sex("男").build(); } public static void main(String[] args) { UserDTO userDTO = new UserDTO("", "123456"); LoginOtherMain loginOtherMain = new LoginOtherMain(); Response login = null; try { login = loginOtherMain.login(userDTO); } catch (LoginExcetion e) { login = Response.error(e.getCode()); } catch (Exception e) { login =Response.error(ResponseCode.UNKOWN); } System.out.println(JSON.toJSonString(login)); } }
controller会校验post参数和get参数。
package com.param.validate.controller; import javax.validation.Valid; import javax.validation.constraints.Size; import com.param.validate.dto.UserDTO; import com.param.validate.service.LoginService; import com.param.validate.validator.annotation.ValidPassword; import com.param.validate.vo.Response; import com.param.validate.vo.UserVO; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @Slf4j @RequestMapping("/v1/user/login") @RestController // get校验时需要这个 @Validated public class LoginController { @Autowired private LoginService loginService; @PostMapping public ResponseEntity4.2 数据传输对象> login(@Valid @RequestBody UserDTO userDTO){ UserVO user = loginService.findUser(userDTO.getUsername(), userDTO.getPassword()); return ResponseEntity.ok(Response.ok(user)); } @GetMapping("/{password}") public ResponseEntity > getUserVO(@PathVariable("password") @Size(min = 8,max = 32,message = "密码区间限制") String password){ UserVO userVO = UserVO.builder().username("zhangsansssssss").password(password).build(); return ResponseEntity.ok(Response.ok(userVO)); } }
传入的登录对象,使用自定义注解校验参数
package com.param.validate.dto; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Size; import com.param.validate.validator.annotation.ValidPassword; import lombok.Getter; import lombok.Setter; @Setter @Getter public class UserDTO { @NotEmpty(message = "Username is empty.") @Size(min = 8,max = 32,message = "Username length invalid.") private String username; @NotEmpty(message = "Password is empty.") @Size(min = 8,max = 32,message = "Password length invalid.") @ValidPassword private String password; public UserDTO(String username, String password) { this.username = username; this.password = password; } public UserDTO(){ } }4.3 自定义校验注解
package com.param.validate.validator.annotation; import java.lang.annotation.documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; import com.param.validate.validator.PasswordValidator; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.CONSTRUCTOR; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER}) @Retention(RUNTIME) @documented @Constraint(validatedBy = PasswordValidator.class) public @interface ValidPassword { String message() default "密码只能是数字"; Class>[] groups() default {}; Class extends Payload>[] payload() default {}; }4.4 解释注解
package com.param.validate.validator; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import com.param.validate.validator.annotation.ValidPassword; import lombok.extern.slf4j.Slf4j; @Slf4j public class PasswordValidator implements ConstraintValidator4.5 全局处理异常{ @Override public void initialize(ValidPassword constraintAnnotation) { } @Override public boolean isValid(String value, ConstraintValidatorContext context) { if (value == null) { return true; } boolean matches = value.matches("[0-9]+"); if(matches){ return true; } return false; } }
package com.param.validate.handler; import java.util.List; import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import com.param.validate.common.enums.ResponseCode; import com.param.validate.common.exception.LoginExcetion; import com.param.validate.common.exception.QueryException; import com.param.validate.vo.Response; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.ObjectError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestControllerAdvice; @Slf4j @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ConstraintViolationException.class) @ResponseBody public ResponseEntity handlerConstraintViolationException(HttpServletRequest request, ConstraintViolationException ex) { Set5 效果 5.1 自定义参数异常 5.2 自定义校验注解异常 5.3 get方法校验> errors = ex.getConstraintViolations(); StringBuilder messageBuilder = new StringBuilder(); errors.forEach(constraintViolation -> messageBuilder.append(constraintViolation.getMessage())); return ResponseEntity.status(HttpStatus.BAD_REQUEST) .body(Response.error(ResponseCode.PARAM_ERROR.getCode(), messageBuilder.toString())); } @ExceptionHandler(value = MethodArgumentNotValidException.class) @ResponseBody public ResponseEntity handlerBeanValidationException(HttpServletRequest request, MethodArgumentNotValidException ex) { System.out.println("222"); List errors = ex.getBindingResult().getAllErrors(); StringBuilder messageBuilder = new StringBuilder(); errors.forEach(error -> messageBuilder.append(error.getDefaultMessage()).append(";")); return ResponseEntity.status(HttpStatus.BAD_REQUEST) .body(Response.error(ResponseCode.PARAM_ERROR.getCode(), messageBuilder.toString())); } @ExceptionHandler(LoginExcetion.class) public ResponseEntity handleLoginExcetion(LoginExcetion e) { ResponseCode code = e.getCode(); return ResponseEntity.status(code.getHttpStatus()).body(Response.error(code)); } @ExceptionHandler(QueryException.class) public ResponseEntity handleCombinedException(QueryException e) { ResponseCode code = e.getCode(); return ResponseEntity.status(code.getHttpStatus()).body(Response.error(code)); } @ExceptionHandler(Exception.class) public ResponseEntity handleException(Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Response.error(ResponseCode.UNKOWN)); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)