JavaEE学习日志持续更新----> 必看!JavaEE学习路线(文章总汇)
SSM整合
引入日志
一、引入依赖
<!--日志开始-->
<!-- 日志工具包 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.10.0</version>
</dependency>
<!--日志核心包-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.10.0</version>
</dependency>
<!--web相关的功能包-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.9.1</version>
</dependency>
<!--为java做简单的日志记录-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!--slf4j的log4j实现类-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.9.1</version>
</dependency>
<!--程序运行的时候检测用了哪种日志实现类-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>2.9.1</version>
</dependency>
<!--日志结束-->
二、log4j2配置文件:日志文件输入到d:/log/ssm.log
,注意需要写绝对路径,相对路径不好找日志文件
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" monitorInterval="30" strict="true" schema="Log4J-V2.2.xsd">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<!-- 将日志输出到控制台 -->
<PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %level [%C{36}.%M] - %msg%n"/>
</Console>
<!--将日志输出到文件中-->
<file name="myLogFile" fileName="d:/log/ssm.log" append="true">
<PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %level [%C{36}.%M] - %msg%n"/>
</file>
</Appenders>
<Loggers>
<!-- 全局配置 -->
<root level="info">
<!--普通日志要在哪里显示-->
<appenderRef ref="Console"/>
<appender-ref ref="myLogFile"/>
</root>
<!-- 业务层日志 -->
<logger name="com.itheima.service" level="debug" additivity="false">
<appender-ref ref="Console"/>
<appender-ref ref="myLogFile"/>
</logger>
<!-- 持久层日志 -->
<logger name="com.itheima.dao" level="debug" additivity="false">
<appender-ref ref="Console"/>
<appender-ref ref="myLogFile"/>
</logger>
<!-- 事务日志 -->
<logger name="org.springframework.jdbc" level="debug" additivity="false">
<appender-ref ref="Console"/>
<appender-ref ref="myLogFile"/>
</logger>
</Loggers>
</Configuration>
拦截器
拦截器的概念
一、拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
二、拦截器链(Interceptor Chain)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
三、 拦截器,过滤器,监听器的区别
-
过滤器:是servlet的一部分,任何web项目都可以使用
配置 /* 后会过滤所有的资源(请求) -
拦截器:是springMVC的一部分,只能在springMVC中使用
配置了/* 只会拦截请求,不会拦截静态资源。但需要注意,有时候可能会拦截静态资源,所以最好给静态资源放行 -
监听器:Web监听器是Servlet规范中的一种特殊类,用于监听ServletContext、HttpSession和 ServletRequest等域对象的创建与销毁事件,当Web应用启动时启动,当Web应用销毁时销毁。用于监听域对象的属性发生修改的事件,可以在事件发生前、发生后做一些必要的处理
四、底层采用的是aop的思想
拦截器配置流程
一、写一个类,实现HandlerInterceptor接口
package com.itheima.inteceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 创建自己的拦截器类,需要实现接口HandlerInterceptor
*/
public class MyInterceptor1 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
二、在spring-mvc.xml中配置拦截器链
- 配置拦截哪些请求,
/**
代表拦截所有请求 - 指定拦截器类
<!--引入拦截器:配置拦截器链-->
<mvc:interceptors>
<!--配置单个拦截器对象-->
<mvc:interceptor>
<!--拦截所有请求-->
<mvc:mapping path="/**"/>
<!--指定拦截器类-->
<bean class="com.itheima.inteceptor.MyInterceptor1"></bean>
</mvc:interceptor>
</mvc:interceptors>
拦截器的三个方法
一、preHandle
- 执行顺序:在控制器方法执行前执行。
- 作用:拦截所有的请求,判断是否可以进行下一步执行。
- 如:判断登录是否成功,登录成功,则放行,返回值配置为true;如果登录失败,则拦截,返回false。
二、postHandle
- 执行的顺序:preHandle放行操作之后可以执行。在控制器方法返回值之前执行
- 作用:可以对返回的数据进行过滤验证
三、afterCompletion
- 执行的顺序:执行完postHandle之后执行。
- 作用:释放资源
拦截器链的执行顺序
一、preHandler
:按照拦截器的配置顺序正序
执行,如果返回的都是true,则执行控制器方法
二、postHandler
:所有的preHandler执行完之后,返回的都是ture,则按照拦截器配置顺序倒序
执行
三、afterCompletion
:所有的postHandler执行完之后,则按照拦截器配置顺序倒序
执行
两个拦截器的配置顺序
<!--引入拦截器:配置拦截器链-->
<mvc:interceptors>
<!--配置单个拦截器对象-->
<mvc:interceptor>
<!--拦截所有请求-->
<mvc:mapping path="/**"/>
<!--指定拦截器类-->
<bean class="com.itheima.inteceptor.MyInterceptor1"></bean>
</mvc:interceptor>
<!--配置单个拦截器对象-->
<mvc:interceptor>
<!--拦截所有请求-->
<mvc:mapping path="/**"/>
<!--指定拦截器类-->
<bean class="com.itheima.inteceptor.MyInterceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
执行顺序
ssm的登录拦截
一、登录页面
<%--
Created by IntelliJ IDEA.
User: admin
Date: 2020/5/11
Time: 17:22
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css">
</head>
<body>
<form class="form-horizontal" role="form" method="post" action="${pageContext.request.contextPath}/login">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">用户名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="name" name="username"
placeholder="请输入用户名">
</div>
</div>
<div class="form-group">
<label for="money" class="col-sm-2 control-label">密码</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="money" name="password"
placeholder="请输入密码">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">登录</button>
</div>
</div></form>
</body>
<!-- 引入JS文件 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
</html>
二、登录的控制器
@Controller
public class LoginController {
/**
* 模拟登录操作
* 判断用户名和密码是否在数据库中存在,如果存在,登录成功,跳转查询
* 登录失败,跳转登录页面
* @param username
* @param password
* @return
*/
@RequestMapping("/login")
public String login(String username, String password, HttpServletRequest request){
if("zhangsan".equals(username) && "123".equals(password)){
//登录成功
System.out.println("登录成功");
//将登录信息存储到session
request.getSession().setAttribute("username",username);
return "redirect:account/findAll";
} else {
System.out.println("登录失败");
//进入登录页面
return "redirect:/login.jsp";
}
}
}
三、拦截器类
package com.itheima.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor implements HandlerInterceptor {
/**
* 登录验证
* 如果session中有登录信息,则放行
* 如果session中没有登录信息,则拦截
* 判断是否是登录请求,如果是登录请求,放行。
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//获取请求路径
String requestURI = request.getRequestURI();
//判断是否是登录请求
if (requestURI.contains("login")){
//如果是登录请求,直接放行
return true;
}
//从session中获取登录信息
Object username = request.getSession().getAttribute("username");
if(username != null){
//session中有登录信息
return true;
} else {
//没有登录信息,跳转到登录页面
response.sendRedirect("/login.jsp");
return false;
}
}
}
四、配置文件
注意:拦截器有时会拦截静态资源,所以需要添加放行静态资源的配置
<!--拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<!--如果拦截了静态资源,需要配置放行-->
<mvc:exclude-mapping path="/js/*"/>
<mvc:exclude-mapping path="/css/*"/>
<mvc:exclude-mapping path="/fonts/*"/>
<bean class="com.itheima.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>