赞
踩
可以利用分页插件PageHelper
1.引入依赖
- <dependency>
- <groupId>com.github.pagehelper</groupId>
- <artifactId>pagehelper-spring-boot-starter</artifactId>
- <version>1.4.2</version>
- </dependency>
2.EmpMapper
- @Mapper
- public interface EmpMapper {
- //获取当前页的结果列表
- public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
- }
3. EmpServiceImpl
- @Slf4j
- @Service
- public class EmpServiceImpl implements EmpService {
- @Autowired
- private EmpMapper empMapper;
-
- @Override
- public PageBean page(Integer page, Integer pageSize, String name, Short gender, LocalDate begin, LocalDate end) {
- //设置分页参数
- PageHelper.startPage(page, pageSize);
- //执行条件分页查询
- List<Emp> empList = empMapper.list(name, gender, begin, end);
- //获取查询结果
- Page<Emp> p = (Page<Emp>) empList;
- //封装PageBean
- PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
- return pageBean;
- }
- }
- @Slf4j
- @RestController
- @RequestMapping("/emps")
- public class EmpController {
-
- @Autowired
- private EmpService empService;
-
- //条件分页查询
- @GetMapping
- public Result page(@RequestParam(defaultValue = "1") Integer page,
- @RequestParam(defaultValue = "10") Integer pageSize,
- String name, Short gender,
- @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
- @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
- //记录日志
- log.info("分页查询,参数:{},{},{},{},{},{}", page, pageSize,name, gender, begin, end);
- //调用业务层分页查询功能
- PageBean pageBean = empService.page(page, pageSize, name, gender, begin, end);
- //响应
- return Result.success(pageBean);
- }
- }
1 引入依赖
- <dependency>
- <groupId>com.aliyun.oss</groupId>
- <artifactId>aliyun-sdk-oss</artifactId>
- <version>3.15.1</version>
- </dependency>
-
- <dependency>
- <groupId>javax.xml.bind</groupId>
- <artifactId>jaxb-api</artifactId>
- <version>2.3.1</version>
- </dependency>
- <dependency>
- <groupId>javax.activation</groupId>
- <artifactId>activation</artifactId>
- <version>1.1.1</version>
- </dependency>
- <!-- no more than 2.3.3-->
- <dependency>
- <groupId>org.glassfish.jaxb</groupId>
- <artifactId>jaxb-runtime</artifactId>
- <version>2.3.3</version>
- </dependency>
2 引入阿里云oss上传文件工具类
- import com.aliyun.oss.OSS;
- import com.aliyun.oss.OSSClientBuilder;
- import org.springframework.stereotype.Component;
- import org.springframework.web.multipart.MultipartFile;
-
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.UUID;
-
- @Component
- public class AliOSSUtils {
- private String endpoint = "https://oss-cn-shanghai.aliyuncs.com";
- private String accessKeyId = "LTAI5t9MZK8iq5T2Av5GLDxX";
- private String accessKeySecret = "C0IrHzKZGKqU8S7YQcevcotD3Zd5Tc";
- private String bucketName = "web-framework01";
-
- /**
- * 实现上传图片到OSS
- */
- public String upload(MultipartFile multipartFile) throws IOException {
- // 获取上传的文件的输入流
- InputStream inputStream = multipartFile.getInputStream();
-
- // 避免文件覆盖
- String originalFilename = multipartFile.getOriginalFilename();
- String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));
-
- //上传文件到 OSS
- OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
- ossClient.putObject(bucketName, fileName, inputStream);
-
- //文件访问路径
- String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;
-
- // 关闭ossClient
- ossClient.shutdown();
- return url;// 把上传到oss的路径返回
- }
- }
3 controller代码
- import com.itheima.pojo.Result;
- import com.itheima.utils.AliOSSUtils;
- 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.RestController;
- import org.springframework.web.multipart.MultipartFile;
- import java.io.IOException;
-
- @Slf4j
- @RestController
- public class UploadController {
-
- @Autowired
- private AliOSSUtils aliOSSUtils;
-
- @PostMapping("/upload")
- public Result upload(MultipartFile image) throws IOException {
- //调用阿里云OSS工具类,将上传上来的文件存入阿里云
- String url = aliOSSUtils.upload(image);
- //将图片上传完成后的url返回,用于浏览器回显展示
- return Result.success(url);
- }
-
- }
可以将阿里云里的配置信息放到配置文件里面 定义一个配置类,加入注解component让他自动注入上面的类中,加一个configurationproperties能够解析出yml中的阿里云,Data是要在aliossutil中引入get函数得到文件中的内容,同时还要引入一个依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
- @Data
- @Component
- @ConfigurationProperties(prefix = "aliyun.oss")
- public class AliOSSProperties {
- private String endpoint;
- private String accessKeyId;
- private String accessKeySecret;
- private String bucketName;
- }
jwt:json web token由三个部分组成,header记录令牌类型,签名算法,payload携带自定义信息,signature加入指定秘钥
要使用jwt令牌要先引入依赖<!-- JWT依赖-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
jwt工具类:
- 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)//指定令牌Token
- .getBody();
- return claims;
- }
- }
-
Logincontroller:注入业务层的对象
- @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); //jwt包含了当前登录的员工信息
- return Result.success(jwt);
- }
-
- //登录失败, 返回错误信息
- return Result.error("用户名或密码错误");
- }
-
- }
第一步:定义过滤器,定义一个类实现Filter接口,并重写方法
第二步:配置过滤器,Filter类加入@WebFilter注解,配置拦截资源的路径,写在其中的urlPatterns中,引导类上加@ServletComponentScan注解,开启Servlet组件支持
过滤器操作:
- @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);
-
- }
- }
配置类 需要加一个配置类注解
- @Configuration //配置类
- public class WebConfig implements WebMvcConfigurer {
-
- @Autowired
- private LoginCheckInterceptor loginCheckInterceptor;
-
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
- }
- }
设置拦截器:
- @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...");
- }
- }
拦截器和过滤器区别:
1.接口规范不同,过滤器需要实现Filter接口,拦截器需要实现HandlerInterceptor接口
2.拦截范围不同,Filter会拦截所有资源,Interceptor只会拦截Spring环境中的资源
建议使用全局异常处理器 主要两个注解,@RestControllerAdvice,表示当前类为全局异常处理器,@ExceptionHandler,指定要捕获的异常对象列别
- @RestControllerAdvice
- public class GlobalExceptionHandler {
-
- @ExceptionHandler(Exception.class)//捕获所有异常
- public Result ex(Exception ex){
- ex.printStackTrace();
- return Result.error("对不起,操作失败,请联系管理员");
- }
- }
@Transactional注解:在当前这个方法执行开始之前来开启事务,方法执行完毕之后提交事务,如果在这个方法执行的过程当中出现的异常,就会对事务进行回滚操作,可以写在方法上,类上,接口上。
可以在yml文件中开启事务管理日志,就可以看到事务的日志信息了
#spring事务管理日志
logging:
level:
org.springframework.jdbc.support.JdbcTransactionManager: debug
@Transactional注解里面可以传递两个属性,rollbackfor可以指定异常的类型,默认为运行时异常,我们可以将其设置成Exception.class。第二个属性是propagation用来配置事务的传播行为,常用的有以下几个,required:默认值,有则加入事务,无则创建事务。requires_new无论事务有无都创建一个新事务。
- @Service
- public class DeptLogServiceImpl implements DeptLogService {
-
- @Autowired
- private DeptLogMapper deptLogMapper;
-
- @Transactional(propagation = Propagation.REQUIRES_NEW)//事务传播行为:不论是否有事务,都新建事务
- @Override
- public void insert(DeptLog deptLog) {
- deptLogMapper.insert(deptLog);
- }
- }
- @Slf4j
- @Service
- //@Transactional //当前业务实现类中的所有的方法,都添加了spring事务管理机制
- public class DeptServiceImpl implements DeptService {
- @Autowired
- private DeptMapper deptMapper;
-
- @Autowired
- private EmpMapper empMapper;
-
- @Autowired
- private DeptLogService deptLogService;
-
-
- //根据部门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);
- }
- }
-
- //省略其他代码...
- }
这样无论操作成功还是失败,都会打印日志
首先要导入pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
1.连接点 JoinPoint,可以被AOP控制的方法
2.通知Advice,共性逻辑,最终体现为一个方法
3.切入点PointCut,匹配连接点的条件,仅会在切入点方法执行时被应用
4.切面Aspect,通知+切入点,被@Aspect注解标识的类称为切面类
5.目标对象,通知所应用的对象
通知类型:
@Around:环绕通知,此注解标注的通知方法在目标方法前、后都被执行
@Before:前置通知,此注解标注的通知方法在目标方法前被执行
@After :后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行
@AfterReturning : 返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执行
@AfterThrowing : 异常后通知,此注解标注的通知方法发生异常后执行
里面可以有以下参数:
execution:execution(访问修饰符? 返回值 包名.类名.?方法名(方法参数) throws 异常?)
简化:annotation自定义注解
- @Target(ElementType.METHOD)
- @Retention(RetentionPolicy.RUNTIME)
- public @interface MyLog {
- }
新建pojo模块并引入lombok依赖,删掉tlias里的pojo包,util模块同理,然后再tlias的pom.xml里引入依赖
创建一个父工程parent,让上面三个都继承他
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.7.5</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
-
- <groupId>com.itheima</groupId>
- <artifactId>tlias-parent</artifactId>
- <version>1.0-SNAPSHOT</version>
- <packaging>pom</packaging>
在子工程里,配置继承关系
- <parent>
- <groupId>com.itheima</groupId>
- <artifactId>tlias-parent</artifactId>
- <version>1.0-SNAPSHOT</version>
- <relativePath>../tlias-parent/pom.xml</relativePath>
- </parent>
-
- <artifactId>tlias-utils</artifactId>
- <version>1.0-SNAPSHOT</version>
- <!--统一管理依赖版本-->
- <dependencyManagement>
- <dependencies>
- <!--JWT令牌-->
- <dependency>
- <groupId>io.jsonwebtoken</groupId>
- <artifactId>jjwt</artifactId>
- <version>0.9.1</version>
- </dependency>
- </dependencies>
- </dependencyManagement>
注意父工程中的dependencyManagement只能统一管理依赖版本,并不会直接引入依赖,所以子工程如果要使用这个依赖,依旧需要引入,只是此时无需指定版本号了
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>${lombok.version}</version>
- </dependency>
- <properties>
- <maven.compiler.source>11</maven.compiler.source>
- <maven.compiler.target>11</maven.compiler.target>
-
- <lombok.version>1.18.24</lombok.version>
- <jjwt.version>0.9.1</jjwt.version>
- <aliyun.oss.version>3.15.1</aliyun.oss.version>
- <jaxb.version>2.3.1</jaxb.version>
- <activation.version>1.1.1</activation.version>
- <jaxb.runtime.version>2.3.3</jaxb.runtime.version>
- </properties>
-
-
- <dependencies>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>${lombok.version}</version>
- </dependency>
- </dependencies>
-
- <!--统一管理依赖版本-->
- <dependencyManagement>
- <dependencies>
- <!--JWT令牌-->
- <dependency>
- <groupId>io.jsonwebtoken</groupId>
- <artifactId>jjwt</artifactId>
- <version>${jjwt.version}</version>
- </dependency>
-
- <!--阿里云OSS-->
- <dependency>
- <groupId>com.aliyun.oss</groupId>
- <artifactId>aliyun-sdk-oss</artifactId>
- <version>${aliyun.oss.version}</version>
- </dependency>
- <dependency>
- <groupId>javax.xml.bind</groupId>
- <artifactId>jaxb-api</artifactId>
- <version>${jaxb.version}</version>
- </dependency>
- <dependency>
- <groupId>javax.activation</groupId>
- <artifactId>activation</artifactId>
- <version>${activation.version}</version>
- </dependency>
- <!-- no more than 2.3.3-->
- <dependency>
- <groupId>org.glassfish.jaxb</groupId>
- <artifactId>jaxb-runtime</artifactId>
- <version>${jaxb.runtime.version}</version>
- </dependency>
- </dependencies>
- </dependencyManagement>
在parent中配置
- <!--聚合其他模块-->
- <modules>
- <module>../tlias-pojo</module>
- <module>../tlias-utils</module>
- <module>../tlias-web-management</module>
- </modules>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。