当前位置:   article > 正文

SpringBootWeb案例

SpringBootWeb案例

主要写一些学到的知识

开发规范

开发规范-REST

基于前后端的开发,所以现在都是基于REST风格的api接口来进行交互

什么是REST风格呢?

  • REST(Representational State Transfer),表述性状态转换,它是一种软件架构风格。

REST风格的URL,通过四种请求方式来进行增删改查

  • GET : 查询

  • POST :新增

  • PUT :修改

  • DELETE :删除

开发规范-统一响应结果

前后端工程进行交互时,需要统一响应结果Result

Result类包含

code  //响应码:1代表成功,0代表失败

msg   //响应信息,描述字符串:比如“发送成功”

data   //后端返回前端的数据;

开发流程

1. 查看页面原型明确需求,编写接口文档,前端需要后端响应的接口;

2. 阅读接口文档

3. 思路分析

4. 功能接口开发

5. 功能接口测试

6. 前后端联调

分页查询

PageHelper

PageHelper是Mybatis的一款功能强大、方便易用的分页插件,支持任何形式的单标、多表的分页查询。

官网:MyBatis 分页插件 PageHelper

select * from emp 语句,怎么能够实现分页操作呢?

  1. 先获取到要执行的SQL语句:select * from emp

  2. 把SQL语句中的字段列表,变为:count(*)

  3. 执行SQL语句:select count(*) from emp //获取到总记录数

  4. 再对要执行的SQL语句:select * from emp 进行改造,在末尾添加 limit ? , ?

  5. 执行改造后的SQL语句:select * from emp limit ? , ?

使用

1.在pom.xml中引入依赖、

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.4.2</version>
</dependency>

2. 例如在mapper层中

@Mapper
public interface EmpMapper {
    //获取当前页的结果列表
    @Select("select * from emp")
    public List<Emp> page(Integer start, Integer pageSize);
}

3. 在service层中

@Override
public PageBean page(Integer page, Integer pageSize) {
    // 设置分页参数
    PageHelper.startPage(page, pageSize);  //page是当前是多少页,pageSize是当前页展示多少数据;
    
    // 执行分页查询
    List<Emp> empList = empMapper.list(page,pageSize);//调用mapper层的查询; 
    
    // 获取分页结果
    Page<Emp> p = (Page<Emp>) empList;   //将查询的结果变为分页查询
    
    //封装PageBean
    PageBean pageBean = new PageBean(p.getTotal(), p.getResult());

    //p.getTotal()是得到分页查询的总数

    //p.getReslt()是得到分页查询的结果
    return pageBean;
}

4.controller层中

//调用业务层分页查询功能
PageBean pageBean = empService.page(page, pageSize); 

//page是当前是多少页,pageSize是当前页展示多少数据;

文件上传

使用现有的云服务来存贮文件:如图片

阿里云OSS

简单使用步骤

1. 打开阿里云官网阿里云-计算,为了无法计算的价值 (aliyun.com) 

2. 页面点击控制台-->搜索“OSS管理控制台”-->开通对象存储服务OSS-->点击左侧“Bucket列表”,创建一个Bucket-->注意将读写权限设置为“公共读”

3. 左侧列表找到SDK下载

在java-对象/文件-上传文件-简单上传中-找到上传文件流

4. 修改代码

在以上代码中,需要替换的内容为:

  • accessKeyId:阿里云账号AccessKey

  • accessKeySecret:阿里云账号AccessKey对应的秘钥

  • bucketName:Bucket名称

  • objectName:对象名称,在Bucket中存储的对象的名称

  • filePath:文件路径

5. 获取AccessKey:点击右上角的头像就会出现AccessKey管理

实际项目中使用

引入阿里云OSS上传文件工具类(由官方的示例代码改造而来)

@Component //用于加入springboot容器中,方便后面自动注入

//需要修改

        bucketName

        accessKeyId

        accessKeySecret为自己的

  1. import com.aliyun.oss.OSS;
  2. import com.aliyun.oss.OSSClientBuilder;
  3. import org.springframework.stereotype.Component;
  4. import org.springframework.web.multipart.MultipartFile;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.util.UUID;
  8. @Component
  9. public class AliOSSUtils {
  10. private String endpoint = "https://oss-cn-shanghai.aliyuncs.com";
  11. private String accessKeyId = "LTAI5t9MZK8iq5T2Av5GLDxX";
  12. private String accessKeySecret = "C0IrHzKZGKqU8S7YQcevcotD3Zd5Tc";
  13. private String bucketName = "web-framework01";
  14. /**
  15. * 实现上传图片到OSS
  16. */
  17. public String upload(MultipartFile multipartFile) throws IOException {
  18. // 获取上传的文件的输入流
  19. InputStream inputStream = multipartFile.getInputStream();
  20. // 避免文件覆盖
  21. String originalFilename = multipartFile.getOriginalFilename();
  22. String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));
  23. //上传文件到 OSS
  24. OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
  25. ossClient.putObject(bucketName, fileName, inputStream);
  26. //文件访问路径
  27. String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;
  28. // 关闭ossClient
  29. ossClient.shutdown();
  30. return url;// 把上传到oss的路径返回
  31. }
  32. }

controller层中

@Autowired
    private AliOSSUtils aliOSSUtils;

@PostMapping("/upload")
    public Result upload(MultipartFile image) throws IOException {
        //调用阿里云OSS工具类,将上传上来的文件存入阿里云
        String url = aliOSSUtils.upload(image);
        //将图片上传完成后的url返回,用于浏览器回显展示
        return Result.success(url);
    } 

配置文件

参数配置化

在我们之前编写的程序中进行文件上传时,需要调用AliOSSUtils工具类,将文件上传到阿里云OSS对象存储服务当中。而在调用工具类进行文件上传时,需要一些参数:

  • endpoint //阿里云OSS域名

  • accessKeyID //用户身份ID

  • accessKeySecret //用户密钥

  • bucketName //存储空间的名字

我们可以将参数配置在配置文件中,为了方便后面修改阿里云的参数

则阿里云工具类则由 

变为

yml配置文件

application.properties

server.port=8080
server.address=127.0.0.1

application.yml

server:
  port: 8080
  address: 127.0.0.1 

yml格式的数据有以下特点:

  • 容易阅读

  • 容易与脚本语言交互

  • 以数据为核心,重数据轻格式

@ConfigurationProperties

就是更加简化参数的配置化

@ConfigurationProperties注解,并通过perfect属性来指定配置参数项的前缀

将原来的配置由

变为

登录校验--JWT令牌

JWT全称:JSON Web Token (官网:JSON Web Tokens - jwt.io

使用

1. 要想使用JWT令牌,需要先引入JWT的依赖

<!-- JWT依赖-->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

2. 调用工具包中提供的API来完成JWT令牌的生成和校验----工具类:Jwts

 测试生成一个

@Test
public void genJwt(){
    Map<String,Object> claims = new HashMap<>();
    claims.put("id",1);
    claims.put("username","Tom");
    
    String jwt = Jwts.builder()
        .setClaims(claims) //自定义内容(载荷)          
        .signWith(SignatureAlgorithm.HS256, "itheima") //签名算法        
        .setExpiration(new Date(System.currentTimeMillis() + 24*3600*1000)) //有效期   
        .compact();
    
    System.out.println(jwt);
}

实际项目中使用

登录成功之后生成JWT令牌,并且把令牌返回给前端。

  1. 引入JWT工具类

    • 在项目工程下创建utils包,并把提供JWT工具类复制到该包下

  2. 登录完成后,调用工具类生成JWT令牌并返回

1. 创建JWT工具类

  1. public class JwtUtils {
  2. private static String signKey = "itheima";//签名密钥
  3. private static Long expire = 43200000L; //有效时间
  4. /**
  5. * 生成JWT令牌
  6. * @param claims JWT第二部分负载 payload 中存储的内容
  7. * @return
  8. */
  9. public static String generateJwt(Map<String, Object> claims){
  10. String jwt = Jwts.builder()
  11. .addClaims(claims)//自定义信息(有效载荷)
  12. .signWith(SignatureAlgorithm.HS256, signKey)//签名算法(头部)
  13. .setExpiration(new Date(System.currentTimeMillis() + expire))//过期时间
  14. .compact();
  15. return jwt;
  16. }
  17. /**
  18. * 解析JWT令牌
  19. * @param jwt JWT令牌
  20. * @return JWT第二部分负载 payload 中存储的内容
  21. */
  22. public static Claims parseJWT(String jwt){
  23. Claims claims = Jwts.parser()
  24. .setSigningKey(signKey)//指定签名密钥
  25. .parseClaimsJws(jwt)//指定令牌Token
  26. .getBody();
  27. return claims;
  28. }
  29. }

 2. controller层

  1. //依赖业务层对象
  2. @Autowired
  3. private EmpService empService;
  4. @PostMapping("/login")
  5. public Result login(@RequestBody Emp emp) {
  6. //调用业务层:登录功能
  7. Emp loginEmp = empService.login(emp);
  8. //判断:登录用户是否存在
  9. if(loginEmp !=null ){
  10. //自定义信息
  11. Map<String , Object> claims = new HashMap<>();
  12. claims.put("id", loginEmp.getId());
  13. claims.put("username",loginEmp.getUsername());
  14. claims.put("name",loginEmp.getName());
  15. //使用JWT工具类,生成身份令牌
  16. String token = JwtUtils.generateJwt(claims);
  17. return Result.success(token);
  18. }
  19. return Result.error("用户名或密码错误");
  20. }

事务

事务是一组操作的集合,它是一个不可分割的工作单位。

Transactional注解

@Transactional作用:就是在当前这个方法执行开始之前来开启事务,方法执行完毕之后提交事务。 如果在这个方法执行的过程当中出现了异常,就会进行事务的回滚操作。

可以在application.yml配置文件中开启事务管理日志,这样就可以在控制看到和事务相关的日志信息了

#spring事务管理日志
logging:
  level:
    org.springframework.jdbc.support.JdbcTransactionManager: debug

AOP

AOP英文全称:Aspect Oriented Programming(面向切面编程、面向方面编程)

AOP的作用:在程序运行期间在不修改源代码的基础上对已有方法进行增强(无侵入性: 解耦)

Spring中AOP的通知类型:

  • @Around:环绕通知,此注解标注的通知方法在目标方法前、后都被执行

  • @Before:前置通知,此注解标注的通知方法在目标方法前被执行

  • @After :后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行

  • @AfterReturning : 返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执行

  • @AfterThrowing : 异常后通知,此注解标注的通知方法发生异常后执行

使用

1. 在pom.xml中导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency> 

2. 自定义注解

/**
 * 自定义Log注解
 */
@Target({ElementType.METHOD})//主要用于方法中
@Documented
@Retention(RetentionPolicy.RUNTIME)//在方法运行时
public @interface Log {

3. service层业务方法上添加@Log注解

    @Override
    @Log
    public void update(Emp emp) {
        emp.setUpdateTime(LocalDateTime.now()); //更新修改时间为当前时间

        empMapper.update(emp);
    }

 

4. 定义切面类,完成操作

@Aspect //切面类

@Around("@annotation(com.itheima.anno.Log)")//环绕通知 

//annotation切入点:主要用来决定项目中的哪些方法需要加入通知

//本段代码表示在Log注解这为切入点

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号