[JavaWeb]【十一】web后端开发-SpringBootWeb案例(登录)

news2025/1/11 12:57:56

目录

一、登录功能

1.1 思路

1.2 LoginController

1.3 EmpService

1.4 EmpServiceImpl

1.5 EmpMapper

1.6 启动服务-测试

1.7 前后端联调

二、登录校验(重点)

2.1 问题

 2.2 问题分析

 2.3 登录校验​编辑

2.4 会话技术

2.4.1 会话技术

 2.4.2 会话跟踪方案对比

2.5 JWT令牌

2.5.1 简介

2.5.2 应用场景 

2.5.3 jwt-生成 

5.5.3.1 引入包

5.5.3.2 生成JWT

 5.5.3.3 解析JWT

2.6 案例实现JWT

 2.6.1 新建JwtUtils工具类

2.6.2 LoginController

2.6.3 启动服务-测试 

2.6.4 前后端联调

2.7 过滤器Filter

2.7.1 概述

2.7.2 快速入门

 2.7.2.1 新增DemoFilter

 2.7.2.2 SpringBootProjectTestApplication

2.7.2.3 启动服务-测试

2.7.2.4 总结

2.7.3 详解(执行流程、拦截路径、过滤器链)

2.7.3.1 执行流程

 2.7.3.2 Filter-拦截路径 ​编辑

2.7.3.3 过滤器链(优先级按过滤器名自然排序)

 2.7.3.4 总结

2.7.4 案例-登录校验-Filter

2.7.4.1 思路

 2.7.4.2 pom.xml引入依赖fastjson

2.7.4.3 新建工具类拦截器LoginCheckFilter 

 2.7.4.4 启动服务-测试

2.8 拦截器Interceptor

2.8.1 简介

2.8.2 快速入门

2.8.2.1 新建LoginCheckInterceptor

 2.8.2.2 WebConfig

2.8.2.3 启动服务测试

2.8.3 详解

2.8.3.1 拦截路径

2.8.3.2  拦截器- 执行流程

2.8.4 案例-登录校验-Interceptor

2.8.4.1 LoginCheckInterceptor

2.8.4.2 WebConfig

2.8.4.3 启动服务-测试

三、异常处理

3.1 异常现象--新增重复名称部门

3.2 思考如何处理

 3.3 全家异常处理

 3.3.1 异常类GlobalExceptionHandler 

3.3.2 启动服务-测试

 3.3.3 总结


前言:实现案例的登录功能、登录校验和异常处理

一、登录功能

1.1 思路

 

 

1.2 LoginController

 

package com.runa.controller;

import com.runa.pojo.Emp;
import com.runa.pojo.Result;
import com.runa.service.EmpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
public class LoginController {

    @Autowired
    private EmpService empService;
    @PostMapping("/login")
    public Result login(@RequestBody Emp emp){
        log.info("登录的用户:{}",emp);
        Emp e = empService.login(emp);
        return e != null ? Result.success():Result.error("用户名或密码错误");

    }
}

1.3 EmpService

package com.runa.service;

import com.runa.pojo.Emp;
import com.runa.pojo.PageBean;
import org.springframework.format.annotation.DateTimeFormat;

import java.time.LocalDate;
import java.util.List;

public interface EmpService {



    /**
     * 分页查询  不带条件
     * @param page
     * @param pageSize
     * @return
     */
//    PageBean page(Integer page, Integer pageSize);

    /**
     * 分页查询 带条件
     * @param page
     * @param pageSize
     * @return
     */
    PageBean page(Integer page, Integer pageSize,String name, Short gender, LocalDate begin, LocalDate end);

    /**
     * 批量删除员工
     * @param ids
     */
    void delete(List<Integer> ids);

    /**
     * 新增员工
     * @param emp
     */
    void save(Emp emp);

    /**
     * 根据id查询员工
     * @param id
     * @return
     */
    Emp getById(Integer id);

    /**
     * 修改员工
     * @param emp
     */
    void update(Emp emp);

    /**
     * 登录
     * @param emp
     * @return
     */
    Emp login(Emp emp);
}

1.4 EmpServiceImpl

package com.runa.service.impl;



import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.runa.mapper.EmpMapper;
import com.runa.pojo.Emp;
import com.runa.pojo.PageBean;
import com.runa.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@Service
public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpMapper empMapper;

    /**
     * 分页查询 pagehelper+组合查询
     * @param page
     * @param pageSize
     * @param name
     * @param gender
     * @param begin
     * @param end
     * @return
     */
    @Override
    public PageBean page(Integer page, Integer pageSize, String name, Short gender, LocalDate begin, LocalDate end) {
        // 1 设置分页参数
        PageHelper.startPage(page, pageSize);

        // 2 执行查询
        List<Emp> empList = empMapper.list(name, gender, begin, end);
        Page<Emp> p = (Page<Emp>) empList;

        // 3 封装PangeBean对象
        PageBean pageBean = new PageBean(p.getTotal(),((Page<Emp>) empList).getResult());
        return pageBean;
    }

    /**
     * 批量删除员工
     * @param ids
     */
    @Override
    public void delete(List<Integer> ids) {
        empMapper.delete(ids);

    }

    /**
     * 新增员工
     * @param emp
     */
    @Override
    public void save(Emp emp) {
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.insert(emp);

    }

    /**
     * 根据ID查询员工
     * @param id
     * @return
     */
    @Override
    public Emp getById(Integer id) {

        return empMapper.getByID(id);
    }

    /**
     * 修改员工
     * @param emp
     */
    @Override
    public void update(Emp emp) {
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.update(emp);

    }

    /**
     * 登录
     * @param emp
     * @return
     */
    @Override
    public Emp login(Emp emp) {

        return empMapper.getByUsernameAndPassword(emp);
    }


    /**
     * 分页查询  加pagehelper
     * @param page
     * @param pageSize
     * @return
     */
//    @Override
//    public PageBean page(Integer page, Integer pageSize) {
//        // 1 设置分页参数
//        PageHelper.startPage(page, pageSize);
//
//        // 2 执行查询
//        List<Emp> empList = empMapper.list();
//        Page<Emp> p = (Page<Emp>) empList;
//
//        // 3 封装PangeBean对象
//        PageBean pageBean = new PageBean(p.getTotal(),((Page<Emp>) empList).getResult());
//        return pageBean;
//    }

    /**
     * 分页查询
     * @param page
     * @param pageSize
     * @return
     */
//    @Override
//    public PageBean page(Integer page, Integer pageSize) {
//        // 1 获取总记录数
//        Long count = empMapper.count();
//
//        // 2 获取分页查询结果列表
//        Integer start = (page - 1) * pageSize;
//        List<Emp> empList = empMapper.page(start, pageSize);
//
//        // 3 封装PangeBean对象
//        PageBean pageBean = new PageBean(count,empList);
//    }


}

1.5 EmpMapper

package com.runa.mapper;

import com.runa.pojo.Emp;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.time.LocalDate;
import java.util.List;

/**
 * 员工管理
 */
@Mapper
public interface EmpMapper {


    /**
     * 查询总记录数
     * @return
     */
//    @Select("select count(*) from emp")
//    public Long count();

    /**
     * 分页查询 获取列表数据
     * @param start
     * @param pageSize
     * @return
     */
//    @Select("select * from emp limit #{start}, #{pageSize}")
//    public List<Emp> page(Integer start, Integer pageSize);
    /**
     * 使用pagehelper的员工信息查询
     * @return
     */
//    @Select("select * from emp")
//    public List<Emp> list();

    /**
     * 使用pagehelper的员工信息查询(带条件)--动态sql
     * 使用xml注解sql
     * @return
     */

    public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);

    /**
     * 批量删除员工
     * @param ids
     */
    void delete(List<Integer> ids);

    /**
     * 新增员工
     * @param emp
     */
    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
            " values(#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime})")
    void insert(Emp emp);

    /**
     * 根据id查询员工
     * @param id
     * @return
     */
    @Select("select * from emp where id = #{id}")
    Emp getByID(Integer id);

    /**
     * 修改员工
     * @param emp
     */
    void update(Emp emp);



    /**
     * 登录
     * @param emp
     * @return
     */
    @Select("select * from emp where username = #{username} and password = #{password}")
    Emp getByUsernameAndPassword(Emp emp);
}

1.6 启动服务-测试

 

1.7 前后端联调

 

二、登录校验(重点)

2.1 问题

 2.2 问题分析

 2.3 登录校验

2.4 会话技术

2.4.1 会话技术

 2.4.2 会话跟踪方案对比

 Cookies与Session例子,启动服务http://localhost:8080/c1 

  

 

package com.runa.controller;

import com.runa.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

/**
 * HttpSession演示
 */
@Slf4j
@RestController
public class SessionController {

    //设置Cookie
    @GetMapping("/c1")
    public Result cookie1(HttpServletResponse response){
        response.addCookie(new Cookie("login_username","itheima")); //设置Cookie/响应Cookie
        return Result.success();
    }

    //获取Cookie
    @GetMapping("/c2")
    public Result cookie2(HttpServletRequest request){
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if(cookie.getName().equals("login_username")){
                System.out.println("login_username: "+cookie.getValue()); //输出name为login_username的cookie
            }
        }
        return Result.success();
    }



    @GetMapping("/s1")
    public Result session1(HttpSession session){
        log.info("HttpSession-s1: {}", session.hashCode());

        session.setAttribute("loginUser", "tom"); //往session中存储数据
        return Result.success();
    }

    @GetMapping("/s2")
    public Result session2(HttpServletRequest request){
        HttpSession session = request.getSession();
        log.info("HttpSession-s2: {}", session.hashCode());

        Object loginUser = session.getAttribute("loginUser"); //从session中获取数据
        log.info("loginUser: {}", loginUser);
        return Result.success(loginUser);
    }
}

2.5 JWT令牌

2.5.1 简介

2.5.2 应用场景 

2.5.3 jwt-生成 

 

 

5.5.3.1 引入包

        <!--JWT令牌-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

5.5.3.2 生成JWT

 

 记得注释他//@SpringBootTest

package com.runa;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

//@SpringBootTest
class SpringBootProjectTestApplicationTests {

//    @Test
//    void contextLoads() {
//    }

    /**
     * 测试JWT令牌的生成
     */
    @Test
    public void testGenJwt(){
        Map<String, Object> claims = new HashMap<>();
        claims.put("id",1);
        claims.put("name","bocai");
        String jwt = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, "runa") // 签名算法 算法有哪些上官网
                .setClaims(claims) //自定义的内容(载荷)
                .setExpiration(new Date(System.currentTimeMillis() + 3600* 1000)) // 设置有效期为1h
                .compact();
        System.out.println(jwt);

    }

}

 

 生成的jwt令牌上官网

 5.5.3.3 解析JWT

package com.runa;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

//@SpringBootTest
class SpringBootProjectTestApplicationTests {

//    @Test
//    void contextLoads() {
//    }

    /**
     * 生成Jwt令牌
     */
    @Test
    public void testGenJwt(){
        Map<String, Object> claims = new HashMap<>();
        claims.put("id",1);
        claims.put("name","bocai");
        String jwt = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, "runa") // 签名算法 算法有哪些上官网
                .setClaims(claims) //自定义的内容(载荷)
                .setExpiration(new Date(System.currentTimeMillis() + 3600* 1000)) // 设置有效期为1h
                .compact();
        System.out.println(jwt);

    }

    /**
     * 解析Jwt
     */
    @Test
    public void testPareJwt(){
        Claims claims = Jwts.parser()
                .setSigningKey("runa") //runa要与前面生成一致
                .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYm9jYWkiLCJpZCI6MSwiZXhwIjoxNjkyNzc3MzAwfQ.KPqgKc5JS8j7GN7aPQ0GwQnUaGm78WWbzf2N7LGq34g")
                .getBody();
        System.out.println(claims);

    }

}

2.6 案例实现JWT

 

 

 

 2.6.1 新建JwtUtils工具类

 

 

package com.runa.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.Map;

public class JwtUtils {

    private static String signKey = "runa";
    private static Long expire = 43200000L;  // 12h

    /**
     * 生成JWT令牌
     * @param claims JWT第二部分负载 payload 中存储的内容
     * @return
     */
    public static String generateJwt(Map<String, Object> claims){
        String jwt = Jwts.builder()
                .addClaims(claims)
                .signWith(SignatureAlgorithm.HS256, signKey)
                .setExpiration(new Date(System.currentTimeMillis() + expire))
                .compact();
        return jwt;
    }

    /**
     * 解析JWT令牌
     * @param jwt JWT令牌
     * @return JWT第二部分负载 payload 中存储的内容
     */
    public static Claims parseJWT(String jwt){
        Claims claims = Jwts.parser()
                .setSigningKey(signKey)
                .parseClaimsJws(jwt)
                .getBody();
        return claims;
    }
}

 

2.6.2 LoginController

package com.runa.controller;

import com.runa.pojo.Emp;
import com.runa.pojo.Result;
import com.runa.service.EmpService;
import com.runa.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
public class LoginController {

    @Autowired
    private EmpService empService;
    @PostMapping("/login")
    public Result login(@RequestBody Emp emp){
        log.info("登录的用户:{}",emp);
        Emp e = empService.login(emp);

        // 登录成功,生成令牌,下发令牌
        if(e != null){
            Map<String, Object> claims = new HashMap<>();
            claims.put("id",e.getId());
            claims.put("name", e.getName());
            claims.put("username", e.getUsername());

            String jwt = JwtUtils.generateJwt(claims);
            return Result.success(jwt);
        }
        // 登录失败,返回错误信息

        return Result.error("用户名或密码错误");

    }
}

2.6.3 启动服务-测试 

2.6.4 前后端联调

 

 

 

2.7 过滤器Filter

2.7.1 概述

2.7.2 快速入门

 2.7.2.1 新增DemoFilter

 

package com.runa.filter;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;

import java.io.IOException;

@WebFilter(urlPatterns = "/*")
public class DemoFilter implements Filter {
    @Override  // 初始化方法,只调用一次
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init初始化方法执行了");
    }

    @Override // 拦截到请求之后调用,调用多次
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截到请求了~~~");
        // 放行
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override // 销毁方法,只调用一次
    public void destroy() {
        System.out.println("destroy方法执行了");
    }
}

 2.7.2.2 SpringBootProjectTestApplication

package com.runa;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@ServletComponentScan  //开启了对servlet组件支持
@SpringBootApplication
public class SpringBootProjectTestApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootProjectTestApplication.class, args);
    }

}

2.7.2.3 启动服务-测试

2.7.2.4 总结

 

   

2.7.3 详解(执行流程、拦截路径、过滤器链)

2.7.3.1 执行流程

 

 2.7.3.2 Filter-拦截路径 

2.7.3.3 过滤器链(优先级按过滤器名自然排序)

 

 

 

package com.runa.filter;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;

import java.io.IOException;

@WebFilter(urlPatterns = "/*")
public class SecondFilter implements Filter {

    @Override // 拦截到请求之后调用,调用多次
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("SecondFilter 拦截---2到请求了~~~放行之前逻辑");
        // 放行
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("SecondFilter拦截---2到请求了~~~放行之后逻辑");
    }
}

 2.7.3.4 总结

 

2.7.4 案例-登录校验-Filter

 

2.7.4.1 思路

 2.7.4.2 pom.xml引入依赖fastjson

        <!--fastJSON-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>

2.7.4.3 新建工具类拦截器LoginCheckFilter 

package com.runa.filter;

import com.alibaba.fastjson.JSONObject;
import com.runa.pojo.Result;
import com.runa.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
//@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        //1.获取请求url。
        String url = req.getRequestURL().toString();
        log.info("请求的url: {}",url);

        //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行。
        if(url.contains("login")){
            log.info("登录操作, 放行...");
            chain.doFilter(request,response);
            return;
        }

        //3.获取请求头中的令牌(token)。
        String jwt = req.getHeader("token");

        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        if(!StringUtils.hasLength(jwt)){
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }

        //5.解析token,如果解析失败,返回错误结果(未登录)。
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {//jwt解析失败
            e.printStackTrace();
            log.info("解析令牌失败, 返回未登录错误信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }

        //6.放行。
        log.info("令牌合法, 放行");
        chain.doFilter(request, response);

    }
}

 2.7.4.4 启动服务-测试

记得将 DemoFilter 与SecondFilter 的@WebFilter(urlPatterns = "/*") 注释掉

 

 

 

2.8 拦截器Interceptor

2.8.1 简介

 

2.8.2 快速入门

2.8.2.1 新建LoginCheckInterceptor

 

package com.runa.interceptor;


import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override //目标资源方法运行前运行, 返回true: 放行, 放回false, 不放行
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, 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...");
    }
}

 2.8.2.2 WebConfig

 

package com.runa.config;

import com.runa.interceptor.LoginCheckInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration //配置类
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LoginCheckInterceptor loginCheckInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");
    }
}

2.8.2.3 启动服务测试

 将过滤器 LoginCheckFilter @WebFilter(urlPatterns = "/*") 注释掉

 

 

2.8.3 详解

2.8.3.1 拦截路径

 

2.8.3.2  拦截器- 执行流程

 

2.8.4 案例-登录校验-Interceptor

2.8.4.1 LoginCheckInterceptor

package com.runa.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.runa.pojo.Result;
import com.runa.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@Slf4j
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override //目标资源方法运行前运行, 返回true: 放行, 放回false, 不放行
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
        //1.获取请求url。
        String url = req.getRequestURL().toString();
        log.info("请求的url: {}",url);

        //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行。
        if(url.contains("login")){
            log.info("登录操作, 放行...");
            return true;
        }

        //3.获取请求头中的令牌(token)。
        String jwt = req.getHeader("token");

        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        if(!StringUtils.hasLength(jwt)){
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }

        //5.解析token,如果解析失败,返回错误结果(未登录)。
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {//jwt解析失败
            e.printStackTrace();
            log.info("解析令牌失败, 返回未登录错误信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }

        //6.放行。
        log.info("令牌合法, 放行");
        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...");
    }
}

2.8.4.2 WebConfig

package com.runa.config;

import com.runa.interceptor.LoginCheckInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration //配置类
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LoginCheckInterceptor loginCheckInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
    }
}

2.8.4.3 启动服务-测试

注释Filter

 

 

三、异常处理

3.1 异常现象--新增重复名称部门

 

 

 

3.2 思考如何处理

 3.3 全家异常处理

 3.3.1 异常类GlobalExceptionHandler 

 

 

package com.runa.exception;

import com.runa.pojo.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局异常处理器
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)//捕获所有异常
    public Result ex(Exception ex){
        ex.printStackTrace();
        return Result.error("对不起,操作失败,请联系管理员");
    }

}

3.3.2 启动服务-测试

新建重复部门

 3.3.3 总结

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/917886.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(6)(6.2) 任务命令

文章目录 前言 6.2.1 概述 6.2.2 导航命令 6.2.3 条件命令 6.2.4 DO命令 前言 本文介绍了 Copter、Plane 和 Rover 切换到自动模式时支持的任务指令。 &#xff01;Warning 这是一项正在进行中的工作&#xff0c;尚未经过全面审核。有关 Copter 的更佳列表&#xff0c;请…

一款word文档编写辅助插件——企升编辑器

面向用户群体&#xff08;官方网址: www.gbtool.cn&#xff09;招投标人员&#xff0c;用统一的模板来编写标书&#xff0c;并最终合并标书。项目经理&#xff0c;编写项目开发计划书&#xff0c;项目验收文档等。开发人员&#xff0c;编写项目需求规格说明书、设计说明书、技术…

SpringMVC入门笔记

一、SpringMVC简介 1. 什么是MVC MVC是一种软件架构的思想&#xff0c;将软件按照模型、视图、控制器来划分 M&#xff1a;Model&#xff0c;模型层&#xff0c;指工程中的JavaBean&#xff0c;作用是处理数据 JavaBean分为两类&#xff1a; 一类称为实体类Bean&#xff1…

Windows11系统安装CUDA和CuDNN

为了方便调试&#xff0c;在Windows上安装了一套CUDA和CuDNN&#xff0c;记录一下过程。 1. 安装显卡驱动&#xff08;已安装驱动可跳过&#xff09; 在一台配有GPU的电脑上安装CUDA&#xff0c;首先要确保电脑已经安装了显卡驱动。若未安装&#xff0c;可在NVIDIA官网下载并…

如何使用ArcGIS进行可视化分析

概述 通视分析是指以某一点为观察点&#xff0c;研究某一区域通视情况的地形分析&#xff0c;利用DEM判断地形上任意两点之间是否可以互相可见的技术方法&#xff0c;分为视线通视分析和视域通视分析&#xff0c;前者判断任意两点之间能否通视&#xff0c;后者从任一点出发&am…

Idea Maven 构建,运行Java程序,二次开发Jmeter

Idea Maven 构建 1. maven下载2. Idea 配置3. 配置Maven镜像4. 在Maven项目pom.xml中添加依赖5. 创建jar包&#xff0c;更新pom&#xff0c;执行代码 1. maven下载 【官网】https://maven.apache.org/download.cgi 【其他版本】https://dlcdn.apache.org/maven/maven-3/ 2. …

【开发】tips:视频汇聚/视频云存储/视频监控管理平台EasyCVR如何提升网络稳定

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

数据结构(5)

堆 堆可以看作一颗完全二叉树的数组对象。 特性&#xff1a; 1.堆是完全二叉树&#xff0c;除了树最后一层不需要满&#xff0c;其余层次都需要满&#xff0c;如果最后一层不是满的&#xff0c;那么要求左满右不满 2.通常使用数组实现&#xff0c;将二叉树结点依次放入数组中…

二、数学建模之整数规划篇

1.定义 2.例题 3.使用软件及解题 一、定义 1.整数规划&#xff08;Integer Programming&#xff0c;简称IP&#xff09;&#xff1a;是一种数学优化问题&#xff0c;它是线性规划&#xff08;Linear Programming&#xff0c;简称LP&#xff09;的一个扩展形式。在线性规划中&…

渗透测试和红队技术解析:分析渗透测试方法、工具和技巧,深入了解红队行动背后的战术和策略

章节一&#xff1a;引言 在当今数字化世界中&#xff0c;信息安全已经成为各个组织和企业的头等大事。为了确保其信息系统的安全性&#xff0c;渗透测试和红队行动变得愈发重要。本文将带您深入探讨渗透测试的方法、工具和技巧&#xff0c;并剖析红队行动的战术和策略。 章节…

【前端实习生备战秋招】—前端性能优化篇,建议收藏

【前端实习生备战秋招】—前端性能优化篇&#xff0c;建议收藏 文章目录 【前端实习生备战秋招】—前端性能优化篇&#xff0c;建议收藏一、CDN1. CDN的概念2. CDN的作用3. CDN的原理4. CDN的使用场景 二、懒加载1. 懒加载的概念2. 懒加载的特点3. 懒加载的实现原理4. 懒加载与…

分类行为的排斥作用

( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有3个节点&#xff0c;AB训练集各由5张二值化的图片组成&#xff0c;让A中有2个1&#xff0c;B中有1个1&#xff0c;且不重合&#xff0c;排列组合&#xff0c;统计迭代次数并排序。 其中有6组数据 构造平均列A 构造平均…

使用扩展函数方式,在Winform界面中快捷的绑定树形列表TreeList控件和

在一些字典绑定中&#xff0c;往往为了方便展示详细数据&#xff0c;需要把一些结构树展现在树列表TreeList控件中或者下拉列表的树形控件TreeListLookUpEdit控件中&#xff0c;为了快速的处理数据的绑定操作&#xff0c;比较每次使用涉及太多细节的操作&#xff0c;我们可以把…

java八股文面试[数据结构]——ArrayList和LinkedList区别

ArrayList和LinkedList的异同 二者的线程都不安全&#xff0c;相对线程安全的Vector,执行效率高。此外&#xff0c;ArrayList时实现了基于动态数组的数据结构&#xff0c;LinkedList基于链表的数据结构&#xff0c;对于随机访问get和set&#xff0c;ArrayList觉得优于LinkedLis…

异地机房容灾备份方案,异地容灾备份方式有哪些

任何时候&#xff0c;我们都不能避免自然灾害、硬件问题、黑客攻击等事故。这些事情可能会导致数据中心的偏瘫&#xff0c;甚至影响整个业务的正常使用。因此&#xff0c; 机房容灾备份计划已成为确保业务连续性的关键对策。 一、异地机房容灾备份方案是什么&#xff1f; 国外…

Shell的一些基础

1.查看某个路径下的目录和文件列表 ls -lR 路径 2.统计某个路径下的文件数量&#xff1a; ls -lR lntest/ | grep “^-” | wc -l 3.找出进程里占用CPU或者内存最高的进程 首先 ps aux 列出来的&#xff0c;cpu是第三列&#xff0c;内存是第四列&#xff0c;所以找出占用cpu最…

word里的文字限制编辑,不知道密码怎么办?

Word文档可以设置加密来保护文件禁止修改&#xff0c;但是在word文档中设置限制编辑功能时对它的作用是否有详细的了解呢&#xff1f;今天为大家介绍word限制编辑功能的作用以及忘记了限制编辑密码该如何解决。 设置限制大家应该都清楚&#xff0c;就是点击工具栏中的审阅 – …

视频集中存储/直播点播平台EasyDSS内核无法启动是什么原因?

视频推拉流EasyDSS视频直播点播平台&#xff0c;集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体&#xff0c;可提供音视频采集、视频推拉流、播放H.265编码视频、存储、分发等视频能力服务。 有用户反馈&#xff0c;下载了视频直播点播平台EasyDSS最新版本&a…

金属氧化物变阻器美国市场估算为13亿美元,中国则将以年复合成长率13.5%增长

金属氧化物变阻器是一种电子元件&#xff0c;它的作用是限制电流过大时对电路的损害。MOV的主要构成材料是金属氧化物&#xff0c;例如氧化锌&#xff08;ZnO&#xff09;。当电路中的电压超过预定值时&#xff0c;MOV会迅速变得导电&#xff0c;从而限制电流的继续增加。这个特…

问题描述:在Windows下没有预装ImageMagick工具

问题描述:在Windows下没有预装ImageMagick工具 # WInR输入cmd回车进入命令行,执行以下命令查看版本信息 magick --version没有预装ImageMagick工具 解决方案&#xff1a;下载安装ImageMagick 官网下载:ImageMagick-7.1.1-15-Q16-x64-dll.exe 下载之后&#xff0c;一路下一步…