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