从零构建后端项目-创建基础类

目录

创建自定义异常类

封装Web返回对象

利用Swagger搭建REST API

配置Swagger

一、添加依赖库

二、创建Swagger配置类

三、编写测试Web接口

四、修改全局的配置文件

五、测试Web接口

配置后端验证功能

一、添加依赖

二、创建Form类 

三、修改sayHello()方法

四、执行测试

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

一、XSS攻击的危害

二、导入依赖库

三、定义请求包装类

四、创建过滤器,把所有请求对象传入包装类

五、给主类添加注解

六、测试拦截XSS脚本


创建自定义异常类

        因为后台Java项目是Web工程,所以有异常消息,我们要在原有异常消息的基础之上,封装状态码,所以需要我们自己创建一个异常类。 

        自定义异常类继承的父类,我没有选择Exception。因为Exception类型的异常,我们必须要手动显式处理,要么上抛,要么捕获。我希望我定义的异常采用既可以采用显式处理,也可以隐式处理,所以我选择继承RuntimeException这个父类。RuntimeException类型的异常可以被虚拟隐式处理,这样就省去了我们很多手动处理异常的麻烦。 

        1. 创建 com.example.emos.wx.exception 包

        2. 创建EmosException类

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;
    }
}

封装Web返回对象

        虽然SpringMVC的Controller可以自动把对象转换成JSON返回给客户端,但是我们需要制定一个统一的标准,保证所有Controller返回的数据格式一致。最简便的办法就是定义封装类,来统一封装返回给客户端的数据。 

        1. 修改 pom.xml 文件,添加依赖库。 Apache 的 httpcomponents 库里面的 HttpStatus 类封装了很多状态码,所以我们在Web返回对象中封装状态吗,可以用到这些状态码。添加依赖后Maven重新加载项目。


    org.apache.httpcomponents
    httpcore
    4.4.13

        2. 创建 com.example.emos.wx.common.util 包,然后创建 R 类

        3. 代码

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 static R error() {
        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
    }
    public static R error(String msg) {
        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
    }
    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 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 ok() {
        return new R();
    }
    public R put(String key, Object value) {
        super.put(key, value);
        return this;
    }
}

利用Swagger搭建REST API

        开发前后端分离架构的项目,往往调试后端Web接口需要用到POSTMAN工具。虽然POSTMAN工具的功能非常强大,但是请求参数很多的情况下,我们手写这些参数和数据还是非常麻烦的。因此我们需要一个调试后端Web接口更加简便的方法。恰好Swagger提供了REST API调用方式,我们不需要借助任何工具的情况下,访问Swagger页面,就可以对Web接口进行调用和调试,这种调试方式的效率要远超POSTMAN软件。

配置Swagger

1. (ApiInfoBuilder)定义Swagger页面基本信息

2. (ApiSelectorBuilder)哪些类中的方法会出现在Swagger上面

3. 开启对JWT的支持

        ·List: 用户需要输入什么参数

        ·AuthorizationScope[]: JWT认证在Swagger中的作用域

        ·List: 令牌的作用域

        ·List: 令牌上下文

        ·Docket

把配置信息给Spring

一、添加依赖库

        在 pom.xml 文件中添加Swagger依赖库,这里我们使用的是Swagger2版本,在UI方面,比 Swagger1版本要好看很多。 


    io.springfox
    springfox-swagger2
    2.9.2


    io.springfox
    springfox-swagger-ui
    2.9.2

二、创建Swagger配置类

在 com.example.emos.wx.config 包中创建 SwaggerConfig 类

package com.example.emos.wx.config; 
import io.swagger.annotations.ApiOperation; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 
import springfox.documentation.builders.ApiInfoBuilder; 
import springfox.documentation.builders.PathSelectors; 
import springfox.documentation.builders.RequestHandlerSelectors; 
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.ApiSelectorBuilder;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket createRestApi() {
        Docket docket = new Docket(DocumentationType.SWAGGER_2);
        // ApiInfoBuilder 用于在Swagger界面上添加各种信息
        ApiInfoBuilder builder = new ApiInfoBuilder();
        builder.title("EMOS在线办公系统");
        ApiInfo apiInfo = builder.build();
        docket.apiInfo(apiInfo);
        // ApiSelectorBuilder 用来设置哪些类中的方法会生成到REST API中
        ApiSelectorBuilder selectorBuilder = docket.select();
        selectorBuilder.paths(PathSelectors.any()); //所有包下的类
        //使用@ApiOperation的方法会被提取到REST API中
 selectorBuilder.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class));
        docket = selectorBuilder.build();
        /*
         * 下面的语句是开启对JWT的支持,当用户用Swagger调用受JWT认证保护的方法,
         * 必须要先提交参数(例如令牌)
         */
        //存储用户必须提交的参数
        List apikey = new ArrayList();
        //规定用户需要输入什么参数
        apikey.add(new ApiKey("token", "token", "header"));
        docket.securitySchemes(apikey);
        //如果用户JWT认证通过,则在Swagger中全局有效
        AuthorizationScope scope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] scopeArray = {scope};
        //存储令牌和作用域
        SecurityReference reference = new SecurityReference("token", scopeArray);
        List refList = new ArrayList();
        refList.add(reference);
        SecurityContext context =
SecurityContext.builder().securityReferences(refList).build();
        List cxtList = new ArrayList();
        cxtList.add(context);
        docket.securityContexts(cxtList);
        return docket;
    }
}

三、编写测试Web接口

在 com.example.emos.wx.controller 包中创建 TestController 类。

package com.example.emos.wx.controller; 
import com.example.emos.wx.common.util.R; 
import io.swagger.annotations.Api; 
import io.swagger.annotations.ApiOperation; 
import org.springframework.web.bind.annotation.GetMapping; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RestController; 

@RestController
@RequestMapping("/test")
@Api("测试Web接口")
public class TestController {
    @GetMapping("/sayHello")
    @ApiOperation("最简单的测试方法")
    public R sayHello(){
        return R.ok().put("message","HelloWorld");
    }
}

四、修改全局的配置文件

不修改会导致错误,就下面出现的问题。

because the return value of “springfox.documentation.spi.service.contexts.Orderings.patternsCondition(springfox.documentation.RequestHandler)” is null

在application.yml文件中增加配置,配置内容如下:

spring:
  mvc:
    pathmatch:
      matching-strategy: ant-path-matcher

        如Spring Boot 2.6发行说明中所述,您可以通过在application.properties文件中将Spring.mvc.pathmatch.matching-strategy设置为ant path matcher来恢复Springfox假定将使用的配置。请注意,只有在不使用Spring Boot的执行器时,此功能才起作用。无论配置的匹配策略如何,执行器始终使用基于路径模式的解析。如果您想在Spring Boot 2.6及更高版本中将其与执行器一起使用,则需要对Springfox进行更改。

        因为在springboot2.6之后,将springmvc的默认匹配策略修改为了PathPatternParser,需要将其修改为AntPathMatcher就可以解决问题 

五、测试Web接口

        打开浏览器,访问 http://127.0.0.1:8080/emos-wx-api/swagger-ui.html

配置后端验证功能

库:Validation

创建Form类

·类声明要添加 @ApiModel【因为要出现在Swagger页面里】

·属性声明要添加 @ApiModelProperty【因为要出现在Swagger页面里】

·属性声明要添加验证注解 @NotNull @NotBlank @Min @Max @Range @Pattern

验证数据要使用 @Valid 注解

        当用户提交请求的时候,SpringBoot项目就会把提交的数据封装到Form对象里面。同时执行后端的验证,如果数据满足要求,那么Web方法就可以正常的执行。如果不满足要求就会抛出异常,返回错误信息给客户端。

        对于客户端提交表单或者Ajax中的数据,后端的Controller必须先要做验证,然后才能使用这些数据。既然要验证数据,那么不妨我们来使用一下 Validation 库。

一、添加依赖

在 pom.xml 文件中添加依赖,然后让Maven加载依赖库。 


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

二、创建Form类 

        validation 库在做后端验证的时候,要求必须用封装类(Form类)来保存客户端提交的数据, 然后在封装类中,我们可以定义验证的规则, validation 会执行这些规则,帮我们验证客户端 提交的数据。 

        我们为之前的 TestController 里面的 sayHello() 方法设置一个Form类,接受客户端提交的 name 数据。我们在 com.example.emos.wx.controller.form 包里面创建 TestSayHelloForm 类。 

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}$")
    @ApiModelProperty("姓名")
    private String name;
}

三、修改sayHello()方法

package com.example.emos.wx.controller; 
import com.example.emos.wx.common.util.R; 
import com.example.emos.wx.controller.form.TestSayHelloForm; 
import io.swagger.annotations.Api; 
import io.swagger.annotations.ApiOperation; 
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid; 
import javax.validation.Validation; 

@RestController
@RequestMapping("/test")
@Api("测试Web接口")
public class TestController {
    @PostMapping("/sayHello")
    @ApiOperation("最简单的测试方法")
    public R sayHello(@Valid @RequestBody TestSayHelloForm form){
        return R.ok().put("message","Hello,"+form.getName());
    }
}

四、执行测试

        打开浏览器,访问 http://127.0.0.1:8080/emos-wx-api/swagger-ui.html

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

库:Hutool

对Http请求中的数据转义

·设置过滤器

·覆盖Http请求的方法

        HttpServletRequest是接口,各家服务器厂商会实现它。

        如果直接继承各厂商的请求父类,那么我们的程序就跟厂商绑定在一起。

        HttpServletRequestWrapper类使用了装饰器模式,装饰器封装了厂商的HttpServletRequest,只需要覆盖Wrapper类的方法,就能做到覆盖厂商请求对象里方法。

        创建过滤器,把Request对象传入Wrapper对象。


getInputStream方法

        非常重要。SpringMVC框架就是通过这个方法,从请求里面提取客户端提交的数据,然后把这些数据封装到Form对象里面。如果我们不对 getInputStream 方法读取的数据做转义,那么后端项目就不具备抵御跨站脚本攻击的能力。

Java不支持原生JSON格式


一、XSS攻击的危害

        XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种 内容。 

        例如用户在发帖或者注册的时候,在文本框中输入  ,这段代码 如果不经过转义处理,而直接保存到数据库。将来视图层渲染HTML的时候,把这段代码输出到页面上,那么  ,然后观察返回的结果。

你可能感兴趣的:(在线协同办公小程序,后端)