EMOS个人教程-第2章 从零构建后端项目基础篇


1 本章介绍

2 创建 SpringBoot 项目

将application.properties改为application.yml

配置tomcat

server:
  tomcat:
    uri-encoding: UTF-8
    threads:
      max: 200
      min-spare: 30
    connection-timeout: 5000ms
  port: 8080
  servlet:
    context-path: /emos-wx-api
    

配置数据连接池

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/emos?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
      username: root
      password: 123456
      initial-size: 8
      max-active: 16
      min-idle: 8
      max-wait: 60000
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false

在pom.xml中添加配置

        
            com.alibaba
            druid-spring-boot-starter
            1.2.8
        

配置redis数据源

  redis:
    database: 0
    host: localhost
    port: 6379
    password: 123456
    jedis:
      pool:
        max-active: 1000
        max-wait: -1ms
        max-idle: 16
        min-idle: 8

配置mongo数据源

  data:
    mongodb:
      host: localhost
      port: 27017
      database: emos
      authentication-database: admin
      username: admin
      password: 123456

3 配置MyBatis

3.1 创建数据库连接

3.2 选中数据表,生成MyBatis文件

注意: - dao文件添加@Mapper,去除文件中的方法 - dao文件对应的mapper, 去除文件中的sql操作配置

3.3 修改yml文件,添加MyBatis配置信息

mybatis:
  mapper-locations: classpath*:mapper/*.xml
  type-aliases-package: com.example.emos.wx.db.pojo
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true

3.4 设置日志输出

logging:
  level:
    root: info
    com.example.emos.wx.db.dao: warn
  pattern:
    console: "%d{HH:mm:ss}  %-5level  %msg%n"

4 创建自定义异常类

  • 为什么要继承RuntimeException?
    • Exception类型的异常必须手动处理
    • RuntimeException异常既可以自动处理,也可以手动处理
  • 包含的属性
    • 状态码
    • 异常消息
package com.example.emos.wx.exception;

import lombok.Data;

@Data
public class EmosException extends RuntimeException {
    private String msg;
    private int code = 500;

    public EmosException(String msg) {
        super(msg);
        this.msg = msg;
    }

    public EmosException(String msg, Throwable e) {
        super(msg, e);
        this.msg = msg;
    }

    public EmosException(String msg, int code) {
        super(msg);
        this.msg = msg;
        this.code = code;
    }

    public EmosException(String msg, int code, Throwable e) {
        super(msg, e);
        this.msg = msg;
        this.code = code;
    }
}

5 封装Web返回对象

  • JavaWeb项目需要统一数据返回格式
    • 业务状态码
    • 业务消息
    • 业务数据
  • 导入httpcomponents库
    • 定义了很多HTTP状态码
    • 免去我们自定义状态码常量
  • R类继承自HashMap
  • 封装方法
    • ok方法
    • error方法

    org.apache.httpcomponents
    httpcore
    4.4.14

package com.example.emos.wx.common.util;

import org.apache.http.HttpStatus;

import java.util.HashMap;
import java.util.Map;

public class R extends HashMap {
    public R(){
        put("code", HttpStatus.SC_OK);
        put("msg","success");
    }
    public R put(String key,Object value){
        super.put(key,value);
        return this;
    }
    public static R ok(){
        return new R();
    }
    public static R ok(String msg){
        R r=new R();
        r.put("msg",msg);
        return r;
    }
    public static R ok(Map map){
        R r=new R();
        r.putAll(map);
        return r;
    }

    public static R error(int code,String msg){
        R r=new R();
        r.put("code",code);
        r.put("msg",msg);
        return r;
    }
    public static R error(String msg){
        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR,msg);
    }
    public static R error(){
        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR,"未知异常,请联系管理员");
    }
}

6 利用Swagger搭建 REST API

6.1 本课程使用Swagger2

6.2 添加依赖库

        
            io.springfox
            springfox-swagger2
            2.9.2
        
        
            io.springfox
            springfox-swagger-ui
            2.9.2

6.3 配置Swagger

  • (ApiInfoBuilder )定义Swagger页面基本信息
  • (ApiSelectorBuilder )哪些类中的方法会出现在Swagger上面
  • 开启对JWT的支持
    • Listhttp://127.0.0.1:8080/emos-wx-api/swagger-ui.html

      8 配置后端验证功能

      8.1 使用Validation库

      8.2 添加依赖库

              
                  org.springframework.boot
                  spring-boot-starter-validation
              
      

      8.3 创建Form类

      • 类声明要添加@ApiModel
      • 属性声明要添加@ApiModelProperty
      • 属性声明要添加验证注解
        • @NotNull
        • @NotBlank
        • @Min
        • @Max
        • @Range
        • @Pattern

      8.4 验证数据要使用@Valid注解

      package com.example.emos.wx.controller.form;
      
      import io.swagger.annotations.ApiModel;
      import io.swagger.annotations.ApiModelProperty;
      import lombok.Data;
      
      import javax.validation.constraints.NotBlank;
      import javax.validation.constraints.Pattern;
      
      @ApiModel
      @Data
      public class TestSayHelloForm {
          @NotBlank
          @Pattern(regexp = "^[\\u4e00-\\u9fa5]{2,15}$",message = "不符合正则表达式")
          @ApiModelProperty("姓名:2-15中文")
          private String name;
      }
      

      9 抵御即跨站脚本(XSS)攻击

      9.1 原因

      • XSS攻击通常指的是通过利用网站系统保存数据的漏洞,通过巧妙的方法把恶意指令注入到网页,用户加载网页的时候就会自动执行恶意脚本。
      • 如果黑客能在你的浏览器上执行javaScript,那么就能窃取Cookie或者Token

      9.2 导入Hutool依赖

              
                  cn.hutool
                  hutool-all
                  5.7.14
              
      
      package com.example.emos.wx.config.xss;
      public class  XssHttpServletRequestWrapper extends HttpServletRequestWrapper {}
      public class XssFilter implements Filter {}
      

      EmosWxApiApplication启动类添加@ServletComponentScan

      9.3 对Http请求中的数据转义

      • 设置过滤器
      • 覆盖Http请求的方法
        • HttpServletRequest是接口,各家服务器厂商会实现它
        • 如果直接继承各厂商的请求父类,那么我们的程序就跟厂商绑定在一起
        • HttpServletRequestWrapper类
          • 使用了装饰器模式
          • 装饰器封装了厂商的Request实现类
          • 只需要覆盖Wrapper类的方法,就能做到覆盖厂商请求对象里方法
      • 创建过滤器,把Request对象传入Wrapper对象

      10 测试跨站脚本攻击

      11 本章总结