python做网站是不是特别慢,互联网公司有哪些,如何检测wordpress后台慢的原因,个人网站备案申请一、拦截器
我们在网上发贴子的时候如果没有登录#xff0c;点击发送按钮会提示未进行登录#xff0c;跳转到登录页面。这样的功能是如何实现的。
1、 拦截器的作用 Spring MVC 的处理器拦截器类似于Servlet开发中的过滤器Filter#xff0c;用于对处理器进行预处理和后处理…一、拦截器
我们在网上发贴子的时候如果没有登录点击发送按钮会提示未进行登录跳转到登录页面。这样的功能是如何实现的。
1、 拦截器的作用 Spring MVC 的处理器拦截器类似于Servlet开发中的过滤器Filter用于对处理器进行预处理和后处理。 用户可以自己定义一些拦截器来实现特定的功能。拦截器链Interceptor Chain。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器和过滤器的区别:过滤器是servlet规范中的一部分任何java web工程都可以使用。 拦截器是SpringMVC框架自己的只有使用了SpringMVC框架的工程才能用。 过滤器在url-pattern中配置了/*之后可以对所有要访问的资源拦截。 拦截器它是只会拦截访问的控制器方法如果访问的是jsphtml,css,image或者js是不会进行拦截的。 它也是AOP思想的具体应用。2、拦截器使用步骤 自定义类 implements HandlerInterceptor 重写拦截器接口三个方法 /*** 实现拦截器的步骤* 1. 自定义类实现拦截器接口* 2. 重写接口所有方法* 弄清楚重写三个方法执行顺序【拦截器执行流程】* 3. springmvc配置类配置拦截器指定拦截策略*/
Component
public class MyInterceptor implements HandlerInterceptor {/*** 请求到达控制器之间就会进入preHandle这个方法如果返回值true请求就进入控制器执行* 返回值false请求就不会进入控制器执行直接返回页面就没有控制器查询结果* 几乎大部分功能我们都是借助preHandle处理。*/Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(preHandle执行了....);return true;//不放行请求}/*** postHandle在控制器执行完毕进入jsp之前*/Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(postHandle执行了....);}/*** afterCompletionjsp渲染完毕在浏览器看到数据之前*/Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(afterCompletion执行了....);}
}sprinmvc的配置类配置拦截器拦截策略 /*** 配置自定义拦截器使自己拦截器的代码可以工作* 基于上面方法已经配置不拦截所有的静态资源springmvc只拦截去控制器的请求不拦截静态资源* param registry 注册中心*/Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myInterceptor).addPathPatterns(/**) //拦截的url地址配置 拦截多级目录比如/building/list /edit}注意拦截器拦截的是controller请求所以只有提交请求到controller中时才会进行拦截
HelloController.java编写控制器代码
Controller
public class HelloController {RequestMapping(/hello) //任意类型的请求list都可以public String hello(){System.out.println(Controller接收到客户端发送的请求并处理);return hello;}
}-hello.jsp编写jsp代码
% page contentTypetext/html;charsetUTF-8 languagejava %
html
headtitleTitle/title
/headbody
h1ooooooooooooooooooooooooooooooooooooook/h1
%System.out.println(hello.jsp代码执行了);
%
/body
/html启动服务器在浏览器输入以下地址 http://localhost:8989/hello控制台输出以下结果 preHandle执行了… Controller接收到客户端发送的请求并处理 postHandle执行了… hello.jsp代码执行了 afterCompletion执行了…
根据输出结果我们可以得出以下结论所有的发给控制器的请求都会先进入preHandle方法进行处理preHandle返回true请求才会被放行到Controller执行控制器Controller代码执行完毕后再次进入拦截器执行postHandle执行完毕后才能进入JSP执行代码而JSP代码执行完毕后请求会再一次进入afterCompletion执行最终响应处理完毕浏览器看到响应结果。图解如下
3、案例利用拦截器完成用户登录认证
案例使用拦截器处理登录认证登录成功可以进入主页没有登录过直接导向到login.html进行登录
创建自定义拦截器验证用户登录情况
Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(preHandle执行了....);if (request.getSession().getAttribute(loginUser) ! null) {//登录过return true;//true放行 false:不放行}//没有登录则响应错误消息码便于判断后进入登录页面response.getWriter().write(new ObjectMapper().writeValueAsString(new ResponseResult(401, 尚未登录请先登录)));return false;
}在springmvc配置类中注册自定义拦截器
Override
public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myInterceptor).addPathPatterns(/**) //拦截的url地址配置 拦截多级目录比如/building/list /edit.excludePathPatterns(/user/dologin);//排除不需要拦截的url地址不能拦截处理登录的控制器
}building-list.html发起请求测试拦截器
//查询所有的楼栋分类信息
loadAllTypes(){axios.get(/type/list,{params:{}}).then(resp{if(resp.data.status200){//请求处理成功的码this.typesresp.data.data;}else if(resp.data.status401){ //尚未登录this.$message({message: resp.data.msg,type: warning});setTimeout((){window.parent.location.href/login.html;},1000);}else{ //其他错误情况直接弹窗提示消息this.$message({message: resp.data.msg,type: error});}})
},登录页面代码略
登录控制器代码:使用session保存登录结果
PostMapping(/dologin)
ResponseBody
public ResponseResultUser doLogin(RequestBody User user, HttpSession session){System.out.println(user);try {User loginUser userService.doLogin(user.getPhone(), user.getPassword());//session保存session.setAttribute(loginUser,loginUser);return new ResponseResultUser(200,登录成功,loginUser);} catch (Exception e) {e.printStackTrace();return new ResponseResult(505,e.getMessage(),null);}
}因为前面配置拦截器是拦截了所有的请求如果将登录请求也拦截会造成永远登录不成功所 以要将登录请求设置为不拦截
启动服务器直接访问http://localhost:8989/main.html页面的“楼栋列表”页面会弹出提示“尚未登录请先登录”
细节框架集页面如何实现浏览器地址栏显示登录页面
window.parent.location.href/login.html;二、全局异常处理
异常处理的作用就是当程序在运行过程中出现异常的时候给用户显示一个友好提示。
细节全局异常只监视控制器发生的异常。所以一般来说dao和service发生的异常我们一般就会抛出到controller由全局异常处理
springmvc全局异常处理使用步骤
1 添加创建全局异常处理类
/*** 全局异常处理类其实本质aop切面*/
ControllerAdvice //aop切面
public class MyGlobalException {ExceptionHandler(ArithmeticException.class)ResponseBodypublic ResponseResultVoid handleArithmeticException(ArithmeticException e){//控制台异常消息还是要输出的给自己看e.printStackTrace();return new ResponseResult(501,算术异常异常原因e.getMessage());}ExceptionHandler(NullPointerException.class)ResponseBodypublic ResponseResultVoid handleArithmeticException(NullPointerException e){//e作用用来接收控制器实际抛出异常//控制台异常消息还是要输出的给自己看e.printStackTrace();return new ResponseResult(501,空指针异常异常原因e.getMessage());}
}2 springmvc配置类中开启全局异常处理类所在包扫描
/*** springmvc配置类,作用取代springmvc.xml*/
Configuration
ComponentScan({com.woniu.controller,com.woniu.interceptor,com.woniu.exception})
EnableWebMvc //启用springmvc的内置配置对WebMvcConfigurer接口实现
public class SpringWebConfig implements WebMvcConfigurer {//其他代码略
}3 如果要根据不同的异常出现不同的提示直接在全局异常类中补充对应异常的处理方法即可参考代码如下
ControllerAdvice
public class GlobalException {/*** 400 - Bad Request*/ExceptionHandler(HttpMessageNotReadableException.class)ResponseBodypublic ResponseResultVoid handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {return new ResponseResult(400,参数解析失败);}/*** 405 - Method Not Allowed*/ExceptionHandler(HttpRequestMethodNotSupportedException.class)ResponseBodypublic ResponseResultVoid handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {return new ResponseResult(405,不支持当前请求的方法);}/*** 415 - Unsupported Media Type*/ExceptionHandler(HttpMediaTypeNotSupportedException.class)ResponseBodypublic ResponseResultVoid handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e) {return new ResponseResult(415,不支持当前媒体类型);}/*** 500 - Internal Server Error*/ExceptionHandler(HttpServerErrorException.class)ResponseBodypublic ResponseResultVoid handleServerErrorException(HttpServerErrorException e) {return new ResponseResult(500,服务器异常);}/*** 5001* param e* return*/ExceptionHandler(ArithmeticException.class)ResponseBodypublic ResponseResultVoid handleArithmeticException(ArithmeticException e){return new ResponseResult(5001,除数不能为0);}
}启动服务器浏览器输入URL地址和以前一样发送请求控制器处理请求的过程中只要遇到异常就会去全局异常中找对应的方法执行。
案例利用全局异常处理登录失败的情况 自定义异常LoginException public class LoginException extends RuntimeException{ public LoginException() { } public LoginException(String message) {super(message);}public LoginException(String message, Throwable cause) {super(message, cause);}public LoginException(Throwable cause) {super(cause);}public LoginException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}UserServiceImpl中遇到登录问题就抛出LoginException对象 //登录业务 public User doLogin(String phone, String password) { try { User user userDao.selectUserByPhone(phone); if(!user.getPassword().equals(password)){ //抛出业务异常 throw new LoginException(“密码错误!”); } return user; } catch (Exception e) { if(e instanceof EmptyResultDataAccessException){ throw new LoginException(“账号不存在!”); } throw new RuntimeException(e); } } 在GlobalException中添加LoginException的处理方法