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

news/2024/5/17 11:28:23/文章来源:https://blog.csdn.net/legend818/article/details/132449232

目录

一、登录功能

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 {@Autowiredprivate 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 {@Autowiredprivate EmpMapper empMapper;/*** 分页查询 pagehelper+组合查询* @param page* @param pageSize* @param name* @param gender* @param begin* @param end* @return*/@Overridepublic 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*/@Overridepublic void delete(List<Integer> ids) {empMapper.delete(ids);}/*** 新增员工* @param emp*/@Overridepublic void save(Emp emp) {emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());empMapper.insert(emp);}/*** 根据ID查询员工* @param id* @return*/@Overridepublic Emp getById(Integer id) {return empMapper.getByID(id);}/*** 修改员工* @param emp*/@Overridepublic void update(Emp emp) {emp.setUpdateTime(LocalDateTime.now());empMapper.update(emp);}/*** 登录* @param emp* @return*/@Overridepublic 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/响应Cookiereturn 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令牌的生成*/@Testpublic 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令牌*/@Testpublic 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*/@Testpublic 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 {@Autowiredprivate 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 {@Overridepublic 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 --------> 阿里巴巴fastJSONString 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 --------> 阿里巴巴fastJSONString 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 {@Autowiredprivate LoginCheckInterceptor loginCheckInterceptor;@Overridepublic 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 --------> 阿里巴巴fastJSONString 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 --------> 阿里巴巴fastJSONString 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 {@Autowiredprivate LoginCheckInterceptor loginCheckInterceptor;@Overridepublic 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.luyixian.cn/news_show_160773.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue 简单实验 v-on html事件绑定

1.代码 <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"event-handling"><p>{{ message }}</p><button v-on:click"reverseMessage">反转 Message</but…

【Unity】Text文本组件的一些操作

Unity的Text组件的几种常见的操作方法 Text组件是Unity中用于在UI界面上显示文本的组件。它包含了一些常见的属性和方法&#xff0c;可以用来控制文本的内容、外观和交互。以下是一些常见的Text组件的操作&#xff1a; 设置文本内容&#xff1a;通过直接在Unity编辑器中的Text…

低压风机单片机方案

低压风机通常由电机、转子、机壳、进气管、出气管、齿轮和减速机等组成。电机带动转子旋转&#xff0c;旋转的转子带动齿轮和减速机转动&#xff0c;进而形成空气被吸入转子内部&#xff0c;通过旋转而产生的离心力把气体压缩&#xff0c;并将气体排出。 低压风机方案的主控型…

“车-路-网”电动汽车充电负荷时空分布预测(matlab)

目录 1 主要内容 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序参考《基于动态交通信息的电动汽车充电负荷时空分布预测》和《基于动态交通信息的电动汽车充电需求预测模型及其对配网的影响分析》文献模型&#xff0c;考虑私家车、出租车和共用车三类交通工具特性和…

无涯教程-PHP - 性能优化

根据Zend小组的说明,以下插图显示了PHP 7与PHP 5.6和基于流行的基于PHP的应用程序上的HHVM 3.7。 Magento 1.9 与执行Magento事务的PHP 5.6相比&#xff0c;PHP 7的运行速度证明是其两倍。 Drupal 7 在执行Drupal事务时&#xff0c;与PHP 5.6相比&#xff0c;PHP 7的运行速度…

小程序运营方式有哪些?如何构建小程序运营框架?

​如今&#xff0c;每个企业基本都做过至少一个小程序&#xff0c;但由于小程序本身不具备流量、也很少有自然流量&#xff0c;因此并不是每个企业都懂如何运营小程序。想了解小程序运营方式方法有哪些&#xff1f; 在正式运营小程序前&#xff0c;了解小程序的功能与企业实际经…

Android相机-架构

引言&#xff1a; 主要是针对CameraAPI v2 HAL3的架构对Android相机系统进行梳理。 相机架构 App和FrameWork Camera API v2位于&#xff1a; packages/apps/Camer2 frameworks/ex/camera2 应用框架级别&#xff0c;使用Camera2 API与相机的硬件进行交互。通过调用Binder接口…

浅析阿里云灵积(平台)模型服务

简介&#xff1a; DashScope灵积模型服务以模型为中心&#xff0c;致力于面向AI应用开发者提供品类丰富、数量众多的模型选择&#xff0c;并为其提供开箱即用、能力卓越、成本经济的模型服务API。DashScope灵积模型服务依托达摩院等机构的优质模型&#xff0c;在阿里云基础设施…

【Adobe After Effects】关于ae点击空格不会播放反而回退一帧的解决方案

最近玩ae的时候遇见了一个小问题&#xff0c;就是有时候敲空格&#xff0c;视频没办法播放&#xff0c;反而会回退一帧&#xff0c;经过摸索发现了一个解决办法&#xff1a; 点击编辑---首选项 然后选择“音频硬件” 然后选择正确的默认输出&#xff0c;点击确定即可

CSS background 背景

background属性为元素添加背景效果。 它是以下属性的简写&#xff0c;按顺序为&#xff1a; background-colorbackground-imagebackground-repeatbackground-attachmentbackground-position 以下所有示例中的花花.jpg图片的大小是4848。 1 background-color background-col…

nginx基本介绍(安装、常用命令、反向代理)

文章目录 引言一、nginx是什么二、nginx的下载和安装1. 下载2. windows下安装3. 运行4. 外部服务器无法访问问题 三、nginx的常用命令四、nginx.config五、FileZilla1. 什么是FileZilla2. FileZilla的下载和安装 六、反向代理1. 什么是nginx的反向代理2. 反向代理工作流程3. 如…

OpenEuler 安装mysql

下载安装包 建议直接使用在openEuler官方编译移植过的mysql-5.7.21系列软件包 参考&#xff1a;操作系统迁移实战之在openEuler上部署MySQL数据库 | 数据库迁移方案 | openEuler社区官网 MySQL 5.7.21 移植指南&#xff08;openEuler 20.03 LTS SP1&#xff09; | 数据库移植…

基于IMX6ULLmini的linux裸机开发系列九:时钟控制模块

时钟控制模块 核心 4个层次配置芯片时钟 晶振时钟 PLL与PFD时钟 PLL选择时钟 根时钟/外设时钟 系统时钟来源 RTC时钟源&#xff1a;32.768KHz 系统时钟&#xff1a;24MHz&#xff0c;作为芯片的主晶振使用 PLL和PFD倍频时钟 7路锁相环电路&#xff08;每个锁相环电路…

2023年国赛 高教社杯数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…

Jmeter常用线程组设置策略

一、前言 ​ 在JMeter压力测试中&#xff0c;我们时常见到的几个场景有&#xff1a;单场景基准测试、单场景并发测试、单场景容量测试、混合场景容量测试、混合场景并发测试以及混合场景稳定性测试 在本篇文章中&#xff0c;我们会用到一些插件&#xff0c;在这边先给大家列出&…

vue中form和table标签过长

form标签过长 效果&#xff1a; 代码&#xff1a; <el-form-item v-for"(item,index) in ticketEditTable1" :label"item.fieldNameCn" :propitem.fieldName :key"item.fieldNameCn" overflow"":rules"form[item.fieldName…

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. …

如何使用NLP库解析Python中的文本

Python是一种强大的面向对象的编程&#xff08;object-oriented programming&#xff0c;OOP&#xff09;语言&#xff0c;在人工智能领域有着广泛的用途。正是鉴于其实用性&#xff0c;以Google为首的大型科技公司&#xff0c;已经对其开发了Tensorflow等代码库&#xff0c;帮…

android外卖点餐界面(期末作业)

效果展示&#xff1a; AndroidMainFest.xml <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"><a…

SpeedBI数据可视化工具:丰富图表,提高报表易读性

数据可视化工具一大作用就是能把复杂数据可视化、直观化&#xff0c;更容易看懂&#xff0c;也就更容易实现以数据驱动业务管理升级&#xff0c;因此一般的数据可视化工具都会提供大量图形化的数据可视化图表&#xff0c;以提高报表的易懂性&#xff0c;更好地服务企业运营决策…