docker启动mysql

docker run —name mysql -e MYSQL_ROOT_PASSWORD=123qwe -d mysql

映射端口
docker rm -f mysql
映射本机的3303端口到docker的3306端口
docker run —name mysql -p 3303:3306 -e MYSQL_ROOT_PASSWORD=123qwe -e MYSQL_DATABASE=xdml -d mysql
image.png

查看进程
docker ps
杀掉进程
docker rm -f 51b (container id的前三位)
启动:
docker run

设置数据库

新建一个controller包,新建一个authcontroller
加注解,加GETMAPPING
响应:返回一个字节流 JSON
image.png
后端返回的是一个对象,所以需要写一个Result对象

加一个ResponseBody注解

Application和Controller要在同一个package下

例如,application是hello.application
那么controller就要在hello.xxxx包下面
image.png

万里长征第一步:返回同一个JSON

  1. @RestController
  2. public class AuthController {
  3. @GetMapping("/auth")
  4. public Object auth() {
  5. return new Result();
  6. }
  7. private static class Result {
  8. public String getStatus(){
  9. return "ok";
  10. }
  11. public Boolean isLogin(){
  12. return false;
  13. }
  14. }
  15. }

Get 请求localhost:8080/auth就可以得到 “{“status”:”ok”,”login”:false}”

处理Post

  1. @PostMapping("/auth/login")
  2. public void login(@RequestBody String usernameAndPassword){
  3. System.out.println(usernameAndPassword);
  4. }

注意啊注意啊,发送过来的JSON是字符串,所以这里的类型是String
所以可以用Map, Springboot可以直接反序列化为Map

  1. @PostMapping("/auth/login")
  2. public void login(@RequestBody Map<String, Object> usernameAndPassword){
  3. System.out.println(usernameAndPassword);
  4. }

增加鉴权

  1. @Configuration
  2. @EnableWebSecurity
  3. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  4. }

这样会拦截所有请求

修改拦截的配置

  1. @Configuration
  2. @EnableWebSecurity
  3. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  4. @Override
  5. protected void configure(HttpSecurity http) throws Exception {
  6. http.authorizeRequests()
  7. .antMatchers("/", "/auth/**").permitAll();
  8. }
  9. }

post里需要禁止csrf

有两类对象
一类是存储数据的
一类是提供服务的,这种需要声明Bean

找不到服务
image.png
解决办法:加一个@Service注解

碰到问题:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id “null”

Cookie

cookie跟着域名走,同一域名下的所有请求都会带上cookie
httponly 只有浏览器发起的才带cookie, JS自己写的请求不带cookie
用户登录后set cookie

  1. try {
  2. authenticationManager.authenticate(token);
  3. SecurityContextHolder.getContext().setAuthentication(token);
  4. return new Result("success","登录成功",true, new User(1, "张三","",password, Instant.now(), Instant.now()));
  5. } catch (BadCredentialsException e) {
  6. return new Result("fail", "密码不正确",false);
  7. }

SecurityContextHolder.getContext().setAuthentication(token);
就是把用户信息(cookie)保存在内存的某个地方
权威的cookie资料:rfc cookie

登录以后每次发请求都带有cookie

怎么有条件的返回数据?

怎么连接数据库?

用Mapper

User模型和数据库里的表的列的顺序要完全一致,否则报错

数据库表的下划线 created_at 怎么才能直接映射为User模型里的createdAt呢
增加一行配置

  1. mybatis.configuration.map-underscore-to-camel-case=true

image.png

数据库返回时间与前端显示时间差8个小时问题

修改之前,数据库的时间是:2021-11-07 23:10:55
前端返回显示的时间是:2021-11-07 15:10:55Z 【UTC时间】
发现从数据库里取出来, new User时就已经是UTC时间了,
所以只需要把UTC时间转换成GMT+8时间即可:
把类型从Instant 修改为ZonedDateTime, 然后增加注解修改timezone即可
image.png

  1. public class User {
  2. Integer id;
  3. String username;
  4. String avatar;
  5. @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
  6. @JsonProperty("createdAt")
  7. ZonedDateTime createdAt;
  8. @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
  9. @JsonProperty("updatedAt")
  10. ZonedDateTime updatedAt;
  11. String password;

修改前的代码是:

  1. public class User {
  2. Integer id;
  3. String username;
  4. String avatar;
  5. Instant createdAt;
  6. Instant updatedAt;
  7. String password;

数据库约束Unique保证数据原子性

image.png
解决方案:
在数据库中设置username列为Unique,如果出现重名就会抛出DuplicateKeyException异常
image.png
代码:
https://github.com/dandanloveJM/spring-boot-blog/commit/568124348aec20ab83e372a521ffc9bffd9abef2