黑马旅游网-学习笔记Part06
大约 5 分钟
黑马旅游网-学习笔记Part06
今日目标
- 登录过滤器 🍐✏️
- 主页导航栏实现 ❤️
- Redis优化导航栏查询所有
知识储备
- 了解session和cookie的缺陷
- 已经完成过滤器拦截登录代码
1. 登录过滤器
登录过滤器
访问页面详情时候,需要校验是否登录,如果未登录,直接跳转到登录页面
点击查看过滤器流程 👈 👈
代码操作
- 在filter包创建
LoginCheckFilter
类 实现Filter接口,配置拦截路径为所有
@Slf4j 注解是日志注解,导入下列依赖
log.info中{} 是占位符的意思,逗号后面的值即为变量
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
/**
* 检查用户是否已经完成登录
* filterName:过滤器在对象容器中的名字
* urlPatterns:匹配路径
*/
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//todo 书写拦截逻辑
System.out.println("我被拦截了");
}
@Override
public void destroy() {
}
}
2. 在doFilter方法中书写拦截逻辑
filterChain.doFilter(servletRequest, servletResponse)
方法是放行,不拦截的意思
🍍 下面代码还缺点东西,用你的调试技术,解决一下吧!! 🍭
/**
* 检查用户是否已经完成登录
* filterName:过滤器在对象容器中的名字
* urlPatterns:匹配路径
*/
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest; //获取session中值
HttpServletResponse response = (HttpServletResponse) servletResponse; //重定向
//1、获取本次请求的URI
String requestURI = request.getRequestURI();
// {}占位符
log.info("接受到的请求路径:{}", requestURI);
//定义不需要处理的请求路径--白名单
String[] urls = new String[]{
"login.html",
"register.html",
"register_ok.html",
"index.html",
"/css",
"/image",
"/error",
"/fonts",
"/img",
"/js",
"/loginServlet",
"/registUserServlet",
"/checkCode",
"/categoryServlet"
};
for (String url : urls) {
if (requestURI.contains(url)) {
//如果不需要处理,则直接放行
log.info("路径:{} 不需要拦截", requestURI);
// filterChain.doFilter 放行
filterChain.doFilter(servletRequest, servletResponse);
return;
}
}
//4、判断登录状态,如果已登录,则直接放行
HttpSession session = request.getSession();
Object user = session.getAttribute("user");
// 如果用户id不等于空,说明已经登陆过,直接放行
if (user != null) {
log.info("用户已经登录,直接放行");
filterChain.doFilter(servletRequest, servletResponse);
// 直接返回该方法,下面的代码不要执行了
return;
}
log.info("用户未登录");
//5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
// JSON.toJSONString 将对象 转成 JSON字符串 给前端使用 返回的数据一定是NOTLOGIN 且code 为0
response.sendRedirect(request.getContextPath() + "/login.html");
}
@Override
public void destroy() {
}
}

2. 主页导航栏实现
主页导航栏实现
需求效果: 👇

接口信息: 👇
- 请求路径:
/travel/categoryServlet
- 请求方式:GET
- 请求参数:无参数
- 返回数据:category集合的json字符串
代码操作
- 检查pom.xml是否有Alibaba的fastjson依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
- 在控制层CategoryServlet中书写接受参数、查询数据、返回数据等逻辑s
@WebServlet("/categoryServlet")
public class CategoryServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//从数据库中拿到 所有的数据 回显给前端
CategoryService categoryService = new CategoryServiceImpl();
List<Category> list = categoryService.findAll();
String json = JSON.toJSONString(list);
//设置响应头信息
resp.setContentType("application/json;charset=utf-8");
resp.getWriter().write(json);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
CategoryService接口
public interface CategoryService {
//查询所有旅游路线
List<Category> findAll();
}
CategoryServiceImpl接口实现类:
public class CategoryServiceImpl implements CategoryService {
@Override
public List<Category> findAll() {
//创建list集合
List<Category> categoryList = new ArrayList<>();
SqlSession session = MybatisUtils.getSqlSessionFactory().openSession();
CategoryMapper mapper = session.getMapper(CategoryMapper.class);
categoryList = mapper.findAll();
return categoryList;
}
}
CategoryMapper接口
public interface CategoryMapper {
List<Category> findAll();
}
CategoryMapper映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.itcast.travel.mapper.CategoryMapper">
<select id="findAll" resultType="category">
SELECT * from tab_category ORDER BY cid
</select>
</mapper>
3.Redis优化导航栏查询所有
前言
背景: 门户网站每次访问时候查询的分类数据是一样的,且每次都要查询数据库,如果用户激增,会造成数据库访问压力,因此需要使用redis进行优化
核心逻辑: 先查询缓存,如果存在,直接返回数据,如果不存在,然后查询数据库,存入缓存,并返回
点击查看核心逻辑图解 👈 👈
代码操作
1.检查redisclient依赖是否导入
<!--jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.0</version>
</dependency>
2.检查JedisUtil工具类是否导入成功!
public final class JedisUtil {
private static JedisPool jedisPool;
static {
//读取配置文件
InputStream is = JedisPool.class.getClassLoader().getResourceAsStream("jedis.properties");
//创建Properties对象
Properties pro = new Properties();
//关联文件
try {
pro.load(is);
} catch (IOException e) {
e.printStackTrace();
}
//获取数据,设置到JedisPoolConfig中
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));
//初始化JedisPool
jedisPool = new JedisPool(config, pro.getProperty("host"), Integer.parseInt(pro.getProperty("port")));
}
/**
* 获取连接方法
*/
public static Jedis getJedis() {
return jedisPool.getResource();
}
/**
* 关闭Jedis
*/
public static void close(Jedis jedis) {
if (jedis != null) {
jedis.close();
}
}
}
3.检查redis服务端是否启动,并且配置文件是否配置正确
host=127.0.0.1
port=6379
maxTotal=50
maxIdle=10
- fastjson的JSONObject类作用是将JSON数组转换成List集合
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
CategoryServiceImpl代码 👇
public class CategoryServiceImpl implements CategoryService {
//不要求 所有人都用这种方式, 如果你觉得难 那么就用上一节课的 直接查询数据库的方式
@Override
public List<Category> findAll() {
//创建list集合
List<Category> categoryList = new ArrayList<>();
//获取redis连接
Jedis jedis = JedisUtil.getJedis();
String categorystr = jedis.get("category");
if (categorystr==null || categorystr.length()==0) {
//redis中数据为空,那么查询数据库并且将数据插入到缓存
//查询所有旅游路线
//查询数据库获取所有数据
System.out.println("从数据库中查询!!");
SqlSession session = MybatisUtils.getSqlSessionFactory().openSession();
CategoryMapper mapper = session.getMapper(CategoryMapper.class);
categoryList = mapper.findAll();
//存入redis缓存中
String jsonString = JSON.toJSONString(categoryList);
jedis.set("category",jsonString);
return categoryList;
} else {
System.out.println("从缓存redis中查询!!!");
List<Category> categories = JSONObject.parseArray(categorystr, Category.class);
return categories;
}
}
}

