JavaWeb基础2-1

JavaWeb基础2-1

一、SpringBoot

1、Spring

Spring官网:https://spring.io/

Spring当中的各种框架:https://spring.io/projects

Spring 发展到今天已经形成了一种开发生态圈,Spring 提供了若干个子项目,每个项目用于完成特定的功能。

基本都基于Spring Framework框架

2、SpringBoot

1.基础

Spring Boot可以帮助我们非常快速的构建应用程序、简化开发、提高效率。

构建的时候,选择Spring框架,选择Web,完成框架搭建。

使用SpringBoot的相关简单方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.itheima.springboot_start.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
System.out.println("hello world~");
return "hello world";
}
}

2.传输参数

数组集合参数:

数组 : 请求参数名与形参中数组变量名相同 , 可以直接使用数组封装
集合 : 请求参数名与形参中集合变量名相同 , 通过@RequestParam绑定参数关系

日期参数:

使用注解完成日期参数格式转换@DateTimeFormat

JSON参数:

JSON参数:JSON数据键名与形参对象属性名相同,定义pojo类型形参即可接收参数,需要使用@RequestBody标识

路径参数:

路径参数:通过请求 URL 直接传递参数,使用 {…} 来标识该路径参数,需要使用 @PathVariable获取路径参数

案例:
1

请求参数总结:

统一响应结果:

让前后端接受的数据类型只有一种

二、分层解耦

1、三层架构

2、拆分实例

直接调用相应的服务方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 @RestController
public class EmpController {
private EmpService empService = new EmpServiceA();

@RequestMapping("/listEmp")
public Result list() {
//1.加载解析xml
String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
System.out.println(file);
List<Emp> empList = XmlParserUtils.parse(file, Emp.class);

//2.对数据进行解析
empList.stream().forEach(emp ->{
String gender = emp.getGender();
if("1".equals(gender)) {
emp.setGender("男");
} else if("2".equals(gender)) {
emp.setGender("女");
}
String job = emp.getJob();
if("1".equals(job)) {
emp.setJob("讲师");
} else if("2".equals(job)) {
emp.setJob("班主任");
} else if("3".equals(job)) {
emp.setJob("班主任");
}
});
return Result.success(empList);
}

拆分为三层构架的方法

Controller(接受请求,响应数据)

1
2
3
4
5
6
7
8
9
10
@RestController
public class EmpController {
private EmpService empService = new EmpServiceA();

@RequestMapping("/listEmp")
public Result list() {
List<Emp> empList = empService.ListEmp();
return Result.success(empList);
}
}

Service(逻辑处理)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class EmpServiceA implements EmpService {
private EmpDao empDao = new EmpDaoA();
//2.对数据进行解析
@Override
public List<Emp> ListEmp() {
List<Emp> empList = empDao.ListEmp();
empList.stream().forEach(emp ->{
String gender = emp.getGender();
if("1".equals(gender)) {
emp.setGender("男");
} else if("2".equals(gender)) {
emp.setGender("女");
}
String job = emp.getJob();
if("1".equals(job)) {
emp.setJob("讲师");
} else if("2".equals(job)) {
emp.setJob("班主任");
} else if("3".equals(job)) {
emp.setJob("班主任");
}
});
return empList;
}
}

Dao(数据处理)

1
2
3
4
5
6
7
8
9
10
public class EmpDaoA implements EmpDao {
@Override
public List<Emp> ListEmp() {
//1.加载解析xml
String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
System.out.println(file);
List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
return empList;
}
}

Service和Dao层次:需要写一个接口,然后再写一个实现类,便于之后更新管理

Service接口

1
2
3
public interface EmpService {
public List<Emp> ListEmp();
}

Dao接口

1
2
3
public interface EmpDao {
public List<Emp> ListEmp();
}

三层架构前后对比

3、分层解耦

控制反转:lnversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。
依赖注入:Dependency lnjection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
Bean对象:IOC容器中创建、管理的对象,称之为beano

IOC&DI 入门

1.Service 层及 Dao 层的实现类交给IOC 容器管理 。

->Service 层及 Dao 层上加上注解@Component

2.为 Controller 及 Service 注入运行时,依赖的对象 。

->Service 层及 Dao 层上加上注解@Autowired

3.运行测试 。

4.切换实现类

将不需要的@Component注释掉

注释 说明 位置
@Component 声明bean的基础注解 不属于以下三类时,用此注解
@Controller @Component的衍生注解 标注在控制器类上
@Service @Component的衍生注解 标注在业务类上
@Repository @Component的衍生注解 标注在数据访问类上(由于与mybatis整合,用的少)

声明bean的时候,可以通过value属性指定bean的名字, 如果没有指定,默认为类名首字母小写。

使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。

4、Bean组件扫描

前面声明bean的四大注解,要想生效,还需要被组件扫描注解@ComponentScan扫描。

@ComponentScan注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解

@SpringBootApplication中,默认扫描的范围是启动类所在包及其子包。

@Autowired 注解,默认是按照类型进行,如果存在多个相同类型的bean,将会报出错误

通过以下几种方案来解决:

设置优先级:@Primary

指定类:@QuaIifier(“”)

@Resource(name = “”)

@Autowired是spring框架提供的注解,而@Resource是JDK提供的注解。

@Autowired默认是按照类型注入,而@Resource默认是按照名称注入。

三、MySQL

1、SQL语句通常被分为四大类:

分类 全称 说明
DDL Data Definition Language 数据定义语言,用来定义数据库对象(数据库,表,字段)
DML Data Manipulation Language 数据操作语言,用来对数据库表中的数据进行增删改
DQL Data Query Language 数据查询语言,用来查询数据库中表的记录
DCL Data Control Language 数据控制语言,用来创建数据库用户、控制数据库的访问权限

四、文件上传

1、文件上传三要数

method设置为post

enctype设置为multipart/form-data

type设置为file

五、JWT

1、JWT简介

全称:JSON Web Token

官网:https://jwt.io/

定义了一种简洁的、自包含的格式,用于在通信双方以json数据格式安全的传输信息。由于数字签名的存在,这些信息是可靠的。

组成:
第一部分: Header(头),记录令牌类型、签名算法等。例如: {“alg”:”HS256”,”type’ ‘:”WT”}
第二部分: Payload(有效载荷) ,携带一些自定义信息、 默认信息等。例如: {“id”:”I”,”username”:”Tom”}
第三部分: Signature(签名) ,防止Token被篡改、确保安全性。将header. payload, 并加入指定秘钥,通过指定签名算法计算而来。

场景:登录认证。
①登录成功后,生成令牌
②后续每个请求,都要携带JWT令牌,系统在每次请求处理之前,先校验令牌,通过后,再处理

创造一个JWT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void testGenJwt() {
Map<String, Object> claims = new HashMap<>();
claims.put("id",1);
claims.put("name","tom");

String jwt = Jwts.builder()
.signWith(SignatureAlgorithm.HS256,"itheimaitheimaitheimaitheimaitheimaitheimaitheimaitheima")
.setClaims(claims)
.setExpiration(new Date(System.currentTimeMillis()+ 3600 * 1000))
.compact();
System.out.println(jwt);

}

解析上面的JWT

1
2
3
4
5
6
7
8
9
@Test
public void testParseHwt() {
Claims claims = Jwts.parser()
.setSigningKey("itheimaitheimaitheimaitheimaitheimaitheimaitheimaitheima")
.parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoidG9tIiwiaWQiOjEsImV4cCI6MTY4NTUxODc1OX0.G-3TTiHeKaCvdv_l7qGS_pSOtwt0lPBEe95d4cGQPyQ\n")
.getBody();
System.out.println(claims);

}

JWT过期之后失效无法解析

2、JWT实例

JWTUtils工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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;
}
}

实现登录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@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("用户名或密码错误");
}

}

JavaWeb基础2-1
https://davidpenn888.github.io/2023/05/29/JavaWeb_2_1/
作者
David Penn
发布于
2023年5月29日
许可协议