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、三层架构
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() { String file = this.getClass().getClassLoader().getResource("emp.xml").getFile(); System.out.println(file); List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
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(); @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() { 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;
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; }
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); return Result.success(jwt); }
return Result.error("用户名或密码错误"); }
}
|