全局异常,统一包装类,非空校验

mmall商城:

MMallException:

package com.southwind.exception;

import com.southwind.result.ResponseEnum;
//创建一个自定义异常类实现控制台输出异常信息
public class MMallException extends RuntimeException {
//    定义一个属性和构造方法,
    private ResponseEnum responseEnum;

    public ResponseEnum getResponseEnum() {
        return responseEnum;
    }

    public void setResponseEnum(ResponseEnum responseEnum) {
        this.responseEnum = responseEnum;
    }

    public MMallException(ResponseEnum responseEnum) {
        super(responseEnum.getMsg());
        this.responseEnum = responseEnum;
    }

}

UnifiedExceptionHandler :全局捕获

//捕获全局的异常
@RestControllerAdvice
public class UnifiedExceptionHandler {
//    用来捕获指定的异常 当前的是MMallException 类型的异常
    @ExceptionHandler(value = MMallException.class)
    public ModelAndView handlerException(MMallException e){
        ModelAndView modelAndView = new ModelAndView();
        ResponseEnum responseEnum = e.getResponseEnum();
        switch (responseEnum.getCode()){
            case 301:
                modelAndView.setViewName("register");
                modelAndView.addObject("emailError", responseEnum.getMsg());
                break;
            case 302:
                modelAndView.setViewName("register");
                modelAndView.addObject("mobileError", responseEnum.getMsg());
                break;
            case 303:
                modelAndView.setViewName("register");
                modelAndView.addObject("userNameExists", responseEnum.getMsg());
                break;
            case 305:
                modelAndView.setViewName("login");
                modelAndView.addObject("userNameError",responseEnum.getMsg());
                break;
            case 306:
                modelAndView.setViewName("login");
                modelAndView.addObject("passwordError",responseEnum.getMsg());
            case 308:
                modelAndView.setViewName("login");
                break;
        }
        return modelAndView;
    }

}

ResponseEnum:封装创建的异常


public enum ResponseEnum {

    USER_INFO_NULL(300,"用户信息不能为空"),
    EMAIL_ERROR(301,"邮箱格式错误"),
    MOBILE_ERROR(302,"手机格式错误"),
    USERNAME_EXISTS(303,"用户名已存在"),
    USER_REGISTER_ERROR(304,"用户注册失败"),
    USERNAME_NOT_EXISTS(305,"用户名不存在"),
    PASSWORD_ERROR(306,"密码错误"),
    PARAMETER_NULL(307,"参数为空"),
    NOT_LOGIN(308,"未登录"),
    CART_ADD_ERROR(309,"添加购物车失败"),
    PRODUCT_NOT_EXISTS(310,"商品不存在"),
    PRODUCT_STOCK_ERROR(311,"商品库存不足"),
    CART_UPDATE_ERROR(312,"更新购物车失败"),
    CART_UPDATE_PARAMETER_ERROR(313,"更新购物车参数异常"),
    CART_UPDATE_STOCK_ERROR(314,"更新商品库存失败"),
    CART_REMOVE_ERROR(315,"删除购物车失败"),
    ORDERS_CREATE_ERROR(316,"创建订单主表失败"),
    ORDER_DETAIL_CREATE_ERROR(317,"创建订单详情失败"),
    USER_ADDRESS_ADD_ERROR(318,"添加新地址失败"),
    USER_ADDRESS_SET_DEFAULT_ERROR(319,"默认地址修改失败");

    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    private Integer code;
    private String msg;

    ResponseEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}

拦截器:
UserFilter:

//配置类的逻辑写出来但是没有生效,只有注入到配置类中才能进行生效
public class UserFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest; //请求存储用户数据
        HttpServletResponse response = (HttpServletResponse) servletResponse; //响应用户数据转发
        HttpSession session = request.getSession();
        if(session.getAttribute("user") == null){
            response.sendRedirect("/login");//转发到登录界面
        }else{
            filterChain.doFilter(servletRequest,servletResponse);
        }
    }
}

拦截器需要成功必须告诉配置类需要拦截什么,那些请求是需要放行的。
FilterConfiguration:

@Configuration
public class FilterConfiguration {
//做一张网 网住所有controller请求只循序特定的请求进行访问
    @Bean
    public FilterRegistrationBean registrationBean(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new UserFilter());
        filterRegistrationBean.addUrlPatterns("/cart/*","/user/orderList","/user/addressList");
        return filterRegistrationBean;
    }
}

myblog:

MD5Utils:进行加密:

 /**
     * @Description: MD5加密
     * @Auther: ONESTAR
     * @Param: 要加密的字符串
     * @Return: 加密后的字符串
     */
    public static String code(String str){
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte[]byteDigest = md.digest();
            int i;
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < byteDigest.length; offset++) {
                i = byteDigest[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            //32位加密
            return buf.toString();
            // 16位的加密
            //return buf.toString().substring(8, 24);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }

    }


    public static void main(String[] args) {
        System.out.println(code("111"));
    }
}

自定义异常:

/**
 * @Description: 自定义异常
 * @Author: LIUYANG
 */
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException{
//    定义一个有参合无参的构造函数
    public NotFoundException() {
    }

    public NotFoundException(String message) {
        super(message);
    }

    public NotFoundException(String message, Throwable cause) {
        super(message, cause);
    }

}

全局异常捕获:

/**
 * @Description: 拦截异常处理
 * @Author: LIUYANG
 */
//拦截有Controller注解的控制器
@ControllerAdvice
public class ControllerExceptionHandler {
	private final Logger logger = LoggerFactory.getLogger( this.getClass() );
	//表明异常处理的方法
	@ExceptionHandler(Exception.class)
	public ModelAndView exceptionHander(HttpServletRequest request, Exception e) throws Exception {
		logger.error( "Requst URL : {},Exception : {}", request.getRequestURL(), e );
    //当标识了状态码的时候就不拦截
		if (AnnotationUtils.findAnnotation( e.getClass(), ResponseStatus.class ) != null) {
			throw e;
		}
		ModelAndView mv = new ModelAndView();
		mv.addObject( "url", request.getRequestURL() );
		mv.addObject( "exception", e );
		mv.setViewName( "error/error" );
		return mv;
	}
}

拦截器搭建;LoginInterceptor

/**
 * @Description: 登录过滤拦截 在访问控制器之前首先拉取一张网拦截所有的请求,
 * @Author: LIUYANG

 */
public class LoginInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {
        if (request.getSession().getAttribute("user") == null) {
            response.sendRedirect("/admin");
            return false;
        }
        return true;
    }
}

WebConfig:指定拦截内容的配置类

/**
 * @Description: 指定拦截内容的配置类
 * @Author: LIUYANG

 */
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
//    表示拦截的请求权 但是也要放行 登录
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/admin/**")
                .excludePathPatterns("/admin")
                .excludePathPatterns("/admin/login");
    }
}

crm:项目搭建异常

NoLoginException:
ParamsException:

**
 * 未登录异常
 */
public class NoLoginException extends RuntimeException {
    private Integer code = 300;
    private String msg = "用户未登录!";


    public NoLoginException() {
        super("用户未登录!");
    }


/**
 * 自定义参数异常
 */
public class ParamsException extends RuntimeException {
    private Integer code = 300;
    private String msg = "参数异常!";


    public ParamsException() {
        super("参数异常!");
    }

全局异常捕获;GlobalExceptionResolver


/**
 * 全局异常统一处理
 */
@Component   // 想要这个异常处理类生效,需要加上@Component注解,把它交给IOC处理,让IOC进行实例化
public class GlobalExceptionResolver implements HandlerExceptionResolver {

    /**
     * 异常处理的方法:
     * --controller层中的方法有两种返回值:
     * ----1.返回视图
     * ----2.返回数据(JSON数据)
     * <p>
     * --如何判断controller层中方法的返回值?
     * ----通过方法上是否声明@ResponseBody注解
     * ------如果未声明,则表示返回视图
     * ------如果声明了,则表示返回数据
     * ----然后通过反射来判断方法上有没有@ResponseBody注解
     *
     * @param request  request请求对象
     * @param response response响应对象
     * @param handler  方法对象
     * @param ex       异常对象
     * @return
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

        /**
         * 非法请求拦截:
         * -- 判断是否抛出未登录异常 NoLoginException
         * ---- 如果抛出该异常,则要求用户登录,重定向跳转到登录页面
         */
        if (ex instanceof NoLoginException) {
            // 重定向到登录页面
            ModelAndView mv = new ModelAndView("redirect:/index");
            return mv;
        }

拦截器搭建:NoLoginInterceptor


/**
 * 非法访问拦截
 */
public class NoLoginInterceptor extends HandlerInterceptorAdapter { // 继承HandlerInterceptorAdapter适配器

    // 注入UserMapper
    @Resource
    private UserMapper userMapper;

    /**
     * 拦截判断用户是否是登录状态:
     * --在目标方法(目标资源)执行前,执行的方法
     * <p>
     * 返回 boolean 类型:
     * --如果返回true,表示目标方法可以被执行
     * --如果返回false,表示阻止目标方法执行
     * <p>
     * 如何判断用户是否是登录状态:
     * --1.判断cookie中是否存在用户信息(获取用户ID)
     * --2.数据库中是否存在指定用户ID的值
     * <p>
     * 如果用户是登录状态,则允许目标方法执行;
     * 如果用户是非登录状态,则抛出自定义的未登录异常 NoLoginException
     * (还需要在全局异常中做判断,如果是未登录异常,则跳转到登录页面)
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 获取cookie中的用户ID,因为请求服务器时,浏览器会携带cookie数据,所以这里就可以获取到cookie中的Id
        Integer userId = LoginUserUtil.releaseUserIdFromCookie(request); // 使用封装好的方法从浏览器传回的cookie中获取userId
        // 判断用户Id是否为空,且数据库中存在该ID的用户记录
        if (userId == null || userMapper.selectByPrimaryKey(userId) == null) {
            // 抛出未登录异常
            throw new NoLoginException();
        }
        return true;
    }
}

配置类实现过滤功能:


/**
 * Created by HMF on 2021/07/21 13:57
 */
@Configuration  // 加上@Configuration注解,表示该类是一个配置类
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Bean // @Bean注解:表示将方法的返回值交给IOC维护
    public NoLoginInterceptor noLoginInterceptor() {
        return new NoLoginInterceptor();
    }

    /**
     * 添加拦截器
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 需要一个实现了拦截器功能的实例对象,这里使用的是 noLoginInterceptor,已经通过noLoginInterceptor()方法将NoLoginInterceptor的对象返回交给IOC处理,
        // 将拦截器设置进来
        registry.addInterceptor(noLoginInterceptor())
                /**
                 * 设置需要被拦截的资源
                 */
                // 默认拦截所有的资源
                .addPathPatterns("/**")
                //  设置放行的资源
                .excludePathPatterns("/css/*", "/images/*", "/js/**", "/lib/**", "/index", "/user/login");

    }
}

同意返回类型;


/**
 *
 */
public class ResultInfo {

    private Integer code = 200;
    private String msg = "success";
    private Object result;

    public Object getResult() {
        return result;
    }

    public void setResult(Object result) {
        this.result = result;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值