java web(2)

1.异常全局处理
2.事务
3.aop技术
4.mtbits
5.三大存储技术

1.异常全局处理

点击查看代码
import com.example.program.pojo.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
//全局异常处理
@RestControllerAdvice
public class ycbg {
@ExceptionHandler
    public Result ex(Exception e)
    {
        e.printStackTrace();
        return  Result.error("对不起,操作失败,请联系管理员");
    }
}

这段代码实现了一个全局异常处理器,在应用程序发生异常时会进行捕获和处理,并返回一个统一的结果给前端。
RestControllerAdvice注解,用于声明一个控制器通知对象,可以对控制器中出现的异常进行处理。
@ExceptionHandler注解对所有的异常进行捕获,并返回一个包含错误信息的Result对象。
需要注意的是,该全局异常处理器只适用于Spring框架中的控制器层,

2.事务是什么

点击查看代码
@Transactional(rollbackFor = Exception.class)//运行异常报错
    public void delete(Integer id) {
try
{
    deptMapper.delete(id);
    //模拟:异常发生

    empMapper.deletea(id);

}finally {
    DeptLog deptLog=new DeptLog();
    deptLog.setCreateTime(LocalDateTime.now());
    deptLog.setDescription("执行了解散部门的操作,此时解散的是"+id+"号部门");
    //调用其他业务类中的方法
    adeptLog.loh(deptLog);
}
事务 ->一旦有异常出现就会执行回滚 @Transactional是一个用于声明事务的注解,在Spring框架中被广泛应用。通过在方法或类上使用@Transactional注解,可以将方法或类的执行过程封装在一个事务中,以保证数据库操作的一致性和完整性。

在@Transactional注解中,可以设置rollbackFor属性指定需要回滚的异常类型。当方法执行过程中抛出了指定的异常类型时,事务将会回滚。在示例中,rollbackFor = Exception.class表示当发生任何异常时都将进行事务回滚。

如果没有指定rollbackFor属性,默认情况下,Spring事务管理器只会对运行时异常进行回滚。

事务有很多 这里仅仅介绍了sping中的事务使用 当然 一般的事务我也写过 但是因为一直连接不上数据库整串代码没跑通
读取不了文件流 ->我直接键值对一个个写进去的 可能有问题 ->晚上我看看能不能解决 不能就放弃

事务传播行为
看代码即可

@Slf4j
@Service
//@Transactional //当前业务实现类中的所有的方法,都添加了spring事务管理机制
public class DeptServiceImpl implements DeptService {
   
    //根据部门id,删除部门信息及部门下的所有员工
    @Override
    @Log
    @Transactional(rollbackFor = Exception.class) 
    public void delete(Integer id) throws Exception {
        try {
            //根据部门id删除部门信息
            deptMapper.deleteById(id);
            //模拟:异常
            if(true){
                throw new Exception("出现异常了~~~");
            }
            //删除部门下的所有员工信息
            empMapper.deleteByDeptId(id);
        }finally {
            //不论是否有异常,最终都要执行的代码:记录日志
            DeptLog deptLog = new DeptLog();
            deptLog.setCreateTime(LocalDateTime.now());
            deptLog.setDescription("执行了解散部门的操作,此时解散的是"+id+"号部门");
            //调用其他业务类中的方法
            deptLogService.insert(deptLog);//这个就涉及事务的传播 是新开启一个事务还是继承上一个事务
        }
    }
    
    //省略其他代码...
}

继续

点击查看代码
@Service
public class DeptLogServiceImpl implements DeptLogService {

    @Autowired
    private DeptLogMapper deptLogMapper;

    @Transactional //事务传播行为:有事务就加入、没有事务就新建事务
    @Override
    public void insert(DeptLog deptLog) {
        deptLogMapper.insert(deptLog);
    }
}

事务传播注解

属性值 含义
REQUIRED 【默认值】需要事务,有则加入,无则创建新事务
REQUIRES_NEW 需要新事务,无论有无,总是创建新事务
SUPPORTS 支持事务,有则加入,无则在无事务状态中运行
NOT_SUPPORTED 不支持事务,在无事务状态下运行,如果当前存在已有事务,则挂起当前事务
MANDATORY 必须有事务,否则抛异常
NEVER 必须没事务,否则抛异常

3.AOP技术

spring aop技术应用

点击查看代码
@Component
@Aspect //当前类为切面类
@Slf4j
public class timeAOP {
@Autowired
private HttpServletRequest request;
@Autowired
   private OperateLogMapper operateLogMapper;
    @Around("@annotation(com.example.program.anno.LOg)")
    public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {
//获取令牌中的id
        String jwt=request.getHeader("token");
        Claims claims= JWT.parseJWT(jwt);
        Integer operateUser=(Integer) claims.get("id");
//操作时间
        LocalDateTime operateTime=LocalDateTime.now();
//操作类名
        String className=pjp.getTarget().getClass().getName();
        //操作方法名
        String methodName=pjp.getSignature().getName();
        //操作方法参数
        Object[] args=pjp.getArgs();
        String methodParams= Arrays.toString(args);
        //调用原始方法
        long begin = System.currentTimeMillis();
        Object result=pjp.proceed();
        long end = System.currentTimeMillis();
        //返回值
        String returnValue= JSONObject.toJSONString(result);
//耗时
        Long cost=end-begin;

        //操作日志
        OperateLog operateLog=new  OperateLog(null,operateUser,operateTime,className,methodName,methodParams,returnValue,cost);
operateLogMapper.insert(operateLog);
return result;

    }
}

这是一个基于Spring AOP实现的切面类,用于记录方法的执行时间和操作日志。以下是对代码的分析和解释: AOP思维导图

image

日后如果我忘了就按照思维导图来复习

4.mtbits

ps:
spring中用myBits还是简单 不需要搞什么配置只需要接口 并且加个注解就可以了

其他地方还需要读配置 麻烦的一匹

@Mapper注解是MyBatis框架的注解之一,它的作用是标识一个Java接口或类为MyBatis的映射器(Mapper)。

在MyBatis中,Mapper是实现数据访问层(DAO)的关键组件,用于定义数据库操作的接口。通过在Mapper接口上使用@Mapper注解,MyBatis会自动为该接口生成实现类,并将该实现类注册到Spring容器中。

使用@Mapper注解后,我们不再需要编写Mapper接口的实现类,MyBatis会帮我们动态生成对应的实现类。这样可以方便地进行数据库的增删改查操作,提高开发效率。同时,@Mapper注解也简化了配置文件的编写,不再需要手动配置Mapper接口的映射关系。

日后脱离了spring框架还需要用mybatis就看这个文章吧
https://blog.csdn.net/qq_45832961/article/details/128781026

5.三大存储技术

1.jwt
2.cookie
3.Session

这里只对jwt进行代码演示 cookie and session 我会学习servlet进行再次学习
后续再进行笔记

jwt
令牌的安全性和灵活性更高
1.对原文进行哈希签名 比对防篡改
2.支持多平台

结构
签名算法 原文(base64编码) 用密钥和签名算法对原文计算得到的签名

载荷里面记录的是含有三大声明,注册声明:iss(发行者)、exp(到期时间)、sub(主题)、sub(受众)。公开声明、私有声明,这三个声明都是非必要的,如果不声明,载荷里面也会自动生成数据代替载荷。

前后端联调的话估计能进行非对称加密 使得原文加密

具体思考方法
服务器接受到数据 对数据封装得到载荷->进行非对称加密 ->进行公钥加密分发客户端
客户端收到后拿到了也解密不了 有哈希签名也可以防止它改原文
后续如果需要看看token里的内容 私钥解密即可

点击查看代码
package com.example.program.utils;

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

public class JWT {
    private static String signKey = "xiaoyu";
    private static Long expire = 43200000L;

    public JWT() {
    }

    public static String retunJwt(Map<String, Object> claims) {
        String jwt = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS256, "xiaoyu").setExpiration(new Date(System.currentTimeMillis() + expire)).compact();
        return jwt;
    }

    public static Claims parseJWT(String jwt) {
        Claims claims = (Claims)Jwts.parser().setSigningKey(signKey).parseClaimsJws(jwt).getBody();
        return claims;
    }
}

return Result.success(token); ---

在前后端分离的架构中,客户端可以通过查看服务器响应的HTTP头部来确定是否返回了JWT。通常,在进行身份验证或授权过程后,服务器会将JWT令牌放在响应的头部中,例如使用名为"Authorization"的字段。

客户端可以通过检查响应的HTTP头部中是否包含"Authorization"字段,并获取该字段的值来判断是否返回了JWT令牌。如果确实返回了JWT令牌,客户端可以将该令牌保存在本地,以备将来在每次请求中携带。

对于常见的前端技术,例如JavaScript或移动端应用,可以使用相应的框架或库来处理HTTP请求和响应。例如,在JavaScript中,可以使用XHR对象(XMLHttpRequest)或Fetch API来发送HTTP请求并获取服务器的响应数据。通过检查响应头部,客户端可以确定是否返回了JWT令牌。

需要注意的是,客户端需要谨慎处理和保存JWT令牌,避免信息泄露和恶意篡改。通常,可以将JWT令牌保存在本地存储(localStorage或sessionStorage)或内存中,以便在每次请求中携带。同时,建议在客户端进行一些安全措施,例如设置合适的过期时间、使用HTTPS协议传输等,以增强JWT的安全性。

posted @ 2023-10-18 17:01  大橘|博客  阅读(41)  评论(0)    收藏  举报