Javaweb学习笔记(三)



第二章 springboot

一、登录校验

1、会话技术

在这里插入图片描述

2、JWT令牌

1、定义:JWT(JSON Web Token),一种简洁的、自包含的格式,用于在通信双方以Json数据格式安全的传输信息。由于数字签名的存在,这些信息是可靠的。
2、组成
(1) 第一部分:Header(头),记录令牌类型、签名算法等。例如:{“alg”:“HS256”,“type”:“WT”}
(2) 第二部分:Payload(有效载荷),携带一些自定义信息、默认信息等。例如:“id".“1”,“username”:"Tom”
(3) 第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload,并加入指定秘钥,通过指定签名算法计算而来。
3、代码

public class JwtUtils {
    private static String signKey = "itheima";
    private static Long expire = 43200000L;
    /**
     * 生成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、过滤器Filter

1、定义:Filter是Javaweb的三大组件(Servlet、Filter、Listener)之一。Filter可以把对资源的请求拦截下来,从而实现一些特殊的功能。
2、拦截路径:

/login
/depts/*
/*

3、过滤器链:一个web应用中,可以配置多个过滤器,这多个过滤器就形成了一个过滤器链。过滤器链优先级是按照过滤器类名(字符串)的自然排序。

在这里插入图片描述
4、登录校验Filter
(1) 定义Filter:定义一个Filter类,实现Filter接口并重写方法
(2) 配置Filter:Filter类上加@WebFilter注解,配置拦截资源的路径。引导类上加@ServletComponentScan 开启Servlet组件支持

<!-- Filter-->
@Slf4j
@WebFilter(urlPatterns = "/*") //拦截资源的路径
public class LoginCheckFilter implements Filter {
    @Override//初始化方法,只调用一次
    public void init(FilterConfig filterConfig) throws ServletException {
    	System.out.println("初始化方法执行");
    }
    @Override//拦截请求之后调用,调用多次
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 	FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //1、获取请求url
        String url = request.getRequestURI().toString();
        log.info("请求的url:{}",url);
        //2、判断请求url是否包含登录操作
        if (url.contains("login")){
            filterChain.doFilter(servletRequest,servletResponse);
            return;
        }
        //3、获取请求头的令牌token
        String jwt = request.getHeader("token");
        //4、判断令牌是否存在
        if(!StringUtils.hasLength(jwt)){
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换对象为json格式
            String notLogin = JSONObject.toJSONString(error);
            response.getWriter().write(notLogin);
            return;
        }
        //5、解析token,如果解析失败,放回错误结果
        try {
            JwtUtils.parseJWT(jwt);
        }catch (Exception e){
            e.printStackTrace();
            log.info("解析失败");
            Result error = Result.error("NOT_LOGIN");
            //手动转换对象为json格式
            String notLogin = JSONObject.toJSONString(error);
            response.getWriter().write(notLogin);
            return;
        }
        //6、放行
        log.info("令牌合法,放行");
        filterChain.doFilter(servletRequest,servletResponse);
    }
    @Override//销毁方法,只调用一次
    public void destroy() {System.out.println("销毁方法执行");
}
<!-- 运行类 -->
@ServletComponentScan //开启了对servlet组件的支持
@SpringBootApplication
public class MybatisApplication {
	public static void main(String[] args) {
		SpringApplication.run(MybatisApplication.class, args);
	}
}

3、拦截器Interceptor

(1) 定义:是一种动态拦截方法调用的机制,类似于过滤器。Spring框架中提供的,用来动态拦截控制器方法的执行。
(2) 作用:拦截请求,在指定的方法调用前,根据业务需要执行预先设定的代码。
(3) 拦截路径
在这里插入图片描述
(4) 执行流程
在这里插入图片描述
(5) Filter和Interceptor的区别
a 接口规范不同: 过滤器需要实现Filter接口,而拦截器需要实现Handlerlnterceptor接口。
b 拦截范围不同: 过滤器Filter会拦截所有的资源,而interceptor只会拦截Spring环境中的资源(interceptor在Spring环境中)。
(6) 登录校验Interceptor

<!-- interceptor.LoginCheckInterceptor -->
@Slf4j
@Component //交给IOC容器管理
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override//目标资源方法运行前运行,返回true: 放行,放回false,不放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object 	handler) throws Exception {
        System.out.println("preHandel...");
        //1、获取请求url
        String url = request.getRequestURI().toString();
        log.info("请求的url:{}",url);
        //2、判断请求url是否包含登录操作
        if (url.contains("login")){
            return true;
        }
        //3、获取请求头的令牌token
        String jwt = request.getHeader("token");
        //4、判断令牌是否存在
        if(!StringUtils.hasLength(jwt)){
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换对象为json格式
            String notLogin = JSONObject.toJSONString(error);
            response.getWriter().write(notLogin);
            return false;
        }
        //5、解析token,如果解析失败,放回错误结果
        try {
            JwtUtils.parseJWT(jwt);
        }catch (Exception e){
            e.printStackTrace();
            log.info("解析失败");
            Result error = Result.error("NOT_LOGIN");
            //手动转换对象为json格式
            String notLogin = JSONObject.toJSONString(error);
            response.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("postHandel...");
    }
    @Override//视图渲染完毕后运行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }
}
<!-- config.Webconfig用于添加LoginCheckInterceptor拦截器 -->
@Configuration //配置类
public class Webconfig implements WebMvcConfigurer {
    @Autowired
    private LoginCheckInterceptor loginCheckInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //addPathPatterns("/**")需要拦截哪些资源 excludePathPatterns("/login")不需要拦截哪些资源
        registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
    }
}

二、异常捕获

1、定义全局异常处理器来处理异常
2、代码

<!-- exception.GlobalExceptionHandler -->
@RestControllerAdvice //开启全局异常捕获
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class) //捕获所有异常
    public Result ex(Exception ex){
        ex.printStackTrace();
        return Result.error("对不起,操作失败,请联系管理员");
    }
}

三、配置文件

1、application.properties

server.port=8080
server.address=127.0.0.1

2、application.yml/application.yaml

server:
	port:8080
	address:127.0.0.1

3、application.yaml

server:
	port:8080
	address:127.0.0.1

第三章 spring

一、事务管理

1、定义:事务是一组操作的集合,它是一个不可分割的工作单位。事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
2、四大特性
在这里插入图片描述
3、事务控制

-- 开启事务(一组操作开始前开启事务)
start transaction; / begin ;
-- 提交事务(这组操作成功前提交事务)
commit;
-- 回滚事务(中间任何一个操作出现异常,回滚事务)
rollback;

4、@注解
(1) 注解:@Transactional,代表方法具有事务
(2) 属性
a、rollbackFor:默认情况下,只有出现 RuntimeException 才回滚异常。rollbackFor属性用于控制出现何种异常类型,回滚事务
b、propagation:事务传播行为,当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制。
在这里插入图片描述

@Transactional(rollbackFor = Exception.class) //指定所有异常都会进行事务回滚
//:当我们不希望事务之间相互影响时,可以使用该传播行为。比如:下订单前需要记录日志,不论订单保存成功与否,都需要保证日志记录能够记录成功。
@Transactional(propagation = Propagation.REQUIRED_NEW)

(2) 位置:业务(service)层的方法上、类上、接口上
(3) 作用:将当前方法交给spring进行事务管理,方法执行前,开启事务,成功执行完毕,提交事务,出现异常,回滚事务。

二、三大核心思想

2.1 控制反转IOC

1、定义:Inversion Of Control控制反转,简称IOC。对象的创建控制权由程序自身转移到外部(容器)
2、bean对象:IOC容器中创建、管理的对象,称之为bean.
3、将对象交给IOC容器管理,需要在对应的类上加上对应的注解
在这里插入图片描述

4、获取bean:默认情况下,Spring项目启动时,会把bean都创建好放在10C容器中,可以通过如下方式来主动获取bean对象。
(1) 根据名字获取bean:Object getBean(String name)
(2) 根据类型获取bean:< T > T getBean(Class< T > requiredType)
(3) 根据name获取bean:< T > T getBean(String name,Class< T > requiredType)

@SpringBootTest
class MybatisApplicationTests {
	@Autowired
	private ApplicationContext applicationContext; //IOC容器对象
	@Test
	void GettestBean(){
		//根据bean的名称获取
		DeptController bean1=(DeptController) applicationContext.getBean("deptController");
		System.out.println(bean1); //com.itheima.controller.DeptController@4a122e68
		//根据bean的类型获取
		DeptController bean2=applicationContext.getBean(DeptController.class);
		System.out.println(bean2); //com.itheima.controller.DeptController@4a122e68
		//根据bean的类型获取
		DeptController bean3=applicationContext.getBean("deptController",DeptController.class);
		System.out.println(bean3); //com.itheima.controller.DeptController@4a122e68
	}

3、bean的作用域:通过@Scope注解来配置作用域
在这里插入图片描述

@Scope(prototype) //设置bean的作用域
@RestController
@RequestMapping("/depts")
public class DeptController{}

4、第三方bean:如果要管理的bean对象来自于第三方(不是自定义的),是无法用@omponent 及衍生注解声明bean的,就需要用到 @Bean注解。若要管理的第三方bean对象,建议对这些bean进行集中分类配置,可以通过 @Configuration 注解声明一个配置类。

//通过@Bean注解的name或value属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名
@Configuration //配置类
public class CommonConfig {
    //声明第三方bean
    @Bean //将当前方法的返网值对象交分IOC容器管理,成为IOC容器bean
    public SAXReader saxReader(){
        return new SAXReader();
    }
    //如果第三方bean需要依赖其它bean对象,直接在bean定义方法中设置形参即可,容器会根据类型自动装配
    //public SAXReader saxReader(DeptController deptController){}
}

2.2 依赖注入DI

1、定义:Dependency Injection依赖注入,简称DI。容器为应用程序提供运行时所依赖的资源。
2、使用方法:使用@Autowired进行依赖注入,默认按照类型进行
3、若同类型的bean存在多个,则使用其他注解来判断优先级
(1) @Primary

@Primary //在bean前加上@Primary
@Service
public class EmpServiceA implements EmpService{}

(2) @Qualifier

@RestController
public class EmpController{
	@Autowired //@Autowired +@Qualifier("bean的名称”)
	@Qualifier("empServiceA")
	private EmpService empService;
}

(3) Resource

@RestController  //@Resource(name="bean的名称”)
public class EmpController{
	@Resource("empServiceA")
	private EmpService empService;
}

2.3 面向切面编程AOP

1、定义:Aspect Oriented Programming (面向切面编程、面向方面编程)其实就是面向特定方法编程。
在这里插入图片描述
2、通知
(1) 通知类型
a、@Around:环绕通知,此注解标注的通知方法在目标方法前、后都被执行
b、@Before:前置通知,此注解标注的通知方法在目标方法前被执行
c、@After:后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行
d、@AfterReturning:返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执行
e、@AfterThrowing :异常后通知,此注解标注的通知方法发生异常后执行
f、@PointCut:将公共的切点表达式抽取出来,需要用到时引用该切点表达式即可
(2) 通知顺序:当有多个切面的切入点都匹配到了目标方法,目标方法运行时,多个通知方法都会被执行。
a、不同切面类中,默认按照切面类的类名字母排序
目标方法前的通知方法:字母排名靠前的先执行
目标方法后的通知方法:字母排名靠前的后执行
b、用 @Order(数字)加在切面类上来控制顺序
目标方法前的通知方法:数字小的先执行
目标方法后的通知方法:数字小的后执行
3、切入点表达式
(1) 作用:主要用来决定项目中的哪些方法需要加入通知
(2) 切入点表达式——execution:主要根据方法的返回值、包名、类名、方法名、方法参数等信息来匹配。 其中“ * ”代表单个独立的任意符号,可以通配任意返回值、包名、类名、方法名、任意类型的一个参数,也可以通配包、类、方法名的一部分。"…"代表多个连续的任意符号,可以通配任意层级的包,或任意类型、任意个数的参数

//其中带?的表示可以省略的部分
execution(访问修饰符? 返回值 包名.类名.? 方法名(方法参数) throws 异常?)
execution(public void com.itheima.service.impl.DeptServiceImpl.delete(java.lang.Integer))
execution(* com.itheima..DeptServiceImpl.*(..))
@PointCut("execution(* com.itheima.service.*.*(..))")
public void pt(){}
@Around("pt()")
public Object recordTime(ProceedingJoinPoint joinPoint) throws Throwable {
}

(3) 切入点表达式——@annotation:用于匹配标识有特定注解的方法。

<!-- 设定一个特定注解annotation:MyLog -->
//使用两个原注解来描述当前注解
@Retention(RetentionPolicy.RUNTIME) //指定运行时生效
@Target(ElementType.METHOD) //指定当前注解的作用范围,METHOD指定在方法上生效
public @interface MyLog {
}
<!-- 在方法上标明特定注解MyLog -->
@MyLog
@Override
public void detete(Integer id) {
	deptMapper.delete(id);
    }
@Slf4j
@Aspect
@Component
public class MysAspect01 {
    @Pointcut("@annotation(com.itheima.aop.MyLog)")
    private void pt(){
    }
    @Before("pt()")
    public void before(){
        log.info("before...");
    }
}

4、连接点
(1) 定义:在Spring中用JoinPoint抽象了连接点,用它可以获得方法执行时的相关信息,如目标类名、方法名、方法参数等。
(2) 连接点的使用
① 对于@Around 通知,获取连接点信息只能使用 ProceedingJoinPoint
② 对于其他四种通知,获取连接点信息只能使用 JoinPoint ,它是 ProceedingJoinPoint的父类型

@Before("execution(* com.itheima.service.*.*(..))")
public void before(){
	String classname = joinPoint.getTarget().getClass().getName(); //获取目标类名
    String signature = joinPoint.getSignature().getName(); //获取目标方法名
    Object[] args = joinPoint.getArgs(); //获取目标方法运行参数
}
  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值