• idea创建springBoot项目


    v1.0.0

    最普通SpringWeb版本,只有一空的项目

    如图,如果我们勾选Spring Web了,意味着这是一个springWeb项目,毕竟Spring又不是只可以做web端。
    我们来对比下,勾选与否的区别。

    勾选吗? resources目录 pom.xml
    - spring-boot-starter
    多出空文件夹templates、static spring-boot-starter-web

    也就是说,springWeb项目会多出一些存放页面相关的文件结构,并且依赖也升级到spring-boot-starter-web。
    spring-boot-starter-web包含spring-boot-starter,并再此基础上多出了一些web相关的其它模块。

    1.0.1

    增加了如下功能,
    逆向代码生成

    pom变化

    相比v1.0.0最基本得空框架而言,这需在pom增加如下依赖:

    <!--这是逆向工程所所需依赖,一共5个包 start-->
    <dependency><!-- 链接数据库驱动: 在idea初始化项目中,选了sql>mysql drive就会有此项,mybatis和逆向都需要 -->
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency> <!-- mybatis-plus(springBoot版)-->
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.0</version>
    </dependency>
    <dependency><!--mybatis-plus代码生成器,3.5之后独立出来了(这个生成代码后就可以删除了,毕竟只用一次)-->
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>3.5.1</version>
    </dependency>
    <dependency> <!--模板引擎:使用代码生成器时必须要的模板引擎依赖。-->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-freemarker</artifactId>
    </dependency>
    <dependency><!--SpringFox 3.0.0(swagger2支持):这个可选。逆向工具是否开启,自己是否需要2个条件决定  https://blog.csdn.net/fygkchina/article/details/109316824 start-->
        <groupId>io.springfox</groupId>
        <artifactId>springfox-boot-starter</artifactId>
        <version>3.0.0</version>
    </dependency>
    

    解释一下:
    mysql-connector-java 是mybatis和mybatis generator都要用到的连接数据库驱动包。
    mybatis-plus 就是mybatis的升级版本,是一款优秀的基于java的持久层框架。业务涉及到操作数据库or逆向生成都需要此包。
    mybatis-plus-generator 逆向代码生成工具包,生成完代码后,就可以删掉它了。
    spring-boot-starter-freemarker 后端得模板语言包,这个如果你用了逆向生成,则必须要使用这个包。 至于逆向为啥要用模板,我也不知道,没有百度到。
    springfox-boot-starter swagger2包,用来生成接口api工具的 逆向生成配置如果开启此功能,则需要下载此依赖,可选。

    swagger2处理

    swagger2因为升级到了3.0.0,所以和现有的spring2.6.x不兼容,Failed to start bean 'documentationPluginsBootstrapper'
    百度到一些 资料 , 需要做额外适配, application.yml文件增加如下代码:

    spring:
      mvc:
        pathmatch:
          matching-strategy: ant_path_matcher
    

    然后再启动类上增加@EnableOpenApi注解

    @EnableOpenApi
    @SpringBootApplication
    public class DemoApplication {
        public static void main(String[] args) {
            SpringApplication.run(SbDemoApplication.class, args);
        }
    }
    

    mybatis generator处理

    逆向工程时候,需要增加一个逆向配置类 utils\CodeGenerator.java

    import com.baomidou.mybatisplus.generator.FastAutoGenerator;
    import com.baomidou.mybatisplus.generator.config.OutputFile;
    import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
    import java.util.Collections;
    
    public class CodeGenerator {
        public static String projectPath = System.getProperty("user.dir");
        public static String dateBaseUrl = "jdbc:mysql://xxx:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false";
        public static void main(String[] args) {
            FastAutoGenerator.create(dateBaseUrl, "root", "*****")
                    .globalConfig(builder -> {
                        builder.author("丁少华") // 设置作者
                                .enableSwagger() // 开启 swagger 模式(非必须,如果开启,需要在依赖添加swagger以及启动类加注解)
                                .fileOverride() // 覆盖已生成文件
                                .outputDir(projectPath+"/src/main/java/"); // 指定输出目录
                    })
                    .packageConfig(builder -> {
                        builder.parent("com.dshvv.demo") // 设置父包名 我这里没有
                                .moduleName("") // 设置父包模块名 我这里没有
                                .pathInfo(Collections.singletonMap(OutputFile.mapperXml, projectPath+"/src/main/resources/mapper/")); // 设置mapperXml生成路径
                    })
                    .strategyConfig(builder -> {
                        builder.addInclude("blog") // 设置需要生成的表名
                                .addTablePrefix(); // 设置过滤表前缀. 我的表没有前缀
                    })
                    .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                    .execute();
        }
    }
    

    然后运行这个类的main方法,代码就生成了

    mybatis配置

    如果此时直接启动项目,则会报错,提示缺少数据库配置。原来mybatis generator的配置文件和mybatis不能公用
    此时在application.yml文件配置一下数据库就行:

    spring:
      datasource:  # 这个配置是给mybatis用的,不是给mybatis-generator用的
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://xxx:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false
        username: root
        password: 'xxx'
    

    此时在启动项目即可。
    不过,可能还会发现如下报错Unsatisfied dependency expressed through field 'baseMapper'
    意思是扫描不到mapper文件,我们在启动类上指定扫描路径的注解@MapperScan("com.dshvv.sbdemo.mapper")即可

    @MapperScan("com.dshvv.sbdemo.mapper")
    @SpringBootApplication
    public class SbDemoApplication {
        public static void main(String[] args) {
            SpringApplication.run(SbDemoApplication.class, args);
        }
    }
    

    freemarker的配置

    1、在application.yml文件增加如下配置:

    spring:
      freemarker:
        enabled: true
        charset: UTF-8 #编码
        suffix: .html #后缀名
        content-type: text/html
        prefer-file-system-access: true
        template-loader-path: classpath:/templates/ #模板位置
    

    2、resources\templates\index.html新增一个页面,内容随意
    3、新增一个控制器类,写入路由

    package com.dshvv.demo.controller;
    
    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;
    import org.springframework.web.servlet.ModelAndView;
    
    @RequestMapping
    @RestController
    public class OtherController {
      @ApiOperation(value = "后端服务起始页", notes = "用于用查看后端服务是否启动", produces = "text/html")
      @GetMapping("/")
      public ModelAndView Home() {
        return new ModelAndView("index");
      }
    }
    

    重启,即可访问

    controller优化

    后端返回格式是统一的,如有status、data、msg等等,所以我们需要做一个规范。
    1、pom里增加一个依赖

    <!--Json序列化工具,编写JsonResult类用到了-->
    <dependency>
      <groupId>org.junit.platform</groupId>
      <artifactId>junit-platform-commons</artifactId>
    </dependency>
    

    2、新建一个格式化返回值的类
    \utils\JsonResult.java内容如下:

    package com.dshvv.demo.utils;
    
    import org.junit.platform.commons.util.ToStringBuilder;
    import java.io.Serializable;
    import java.util.Objects;
    
    public class JsonResult implements Serializable {
    
        private static final long serialVersionUID = 5598308977637490090L;
    
        private int status;
    
        private String message;
    
        private Object data;
    
        public int getStatus() {
            return status;
        }
    
        public void setStatus(int status) {
            this.status = status;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public void setData(Object data) {
            this.data = data;
        }
    
        public Object getData() {
            return data;
        }
    
        public static JsonResult success() {
            return success(null);
        }
    
        public static JsonResult success(Object data) {
            JsonResult jsonResult = new JsonResult();
            jsonResult.setStatus(200);
            jsonResult.setMessage("SUCCESS");
            if (data != null) {
                jsonResult.setData(data);
            }
            return jsonResult;
        }
    
        public static JsonResult failed() {
            return failed("FAILED");
        }
    
        public static JsonResult failed(String message) {
            JsonResult jsonResult = new JsonResult();
            jsonResult.setStatus(500);
            jsonResult.setMessage(message);
            return jsonResult;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (!(o instanceof JsonResult)) {
                return false;
            }
            JsonResult result = (JsonResult) o;
            return status == result.status &&
                    Objects.equals(message, result.message) &&
                    Objects.equals(data, result.data);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(status, message, data);
        }
    
        @Override
        public String toString() {
            return new ToStringBuilder(this)
                    .append("status", status)
                    .append("message", message)
                    .append("data", data)
                    .toString();
        }
    
    }
    

    3、如何使用?
    建一个路由,尝试使用

    package com.dshvv.demo.controller;
    
    import com.dshvv.demo.utils.JsonResult;
    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;
    import org.springframework.web.servlet.ModelAndView;
    
    @RequestMapping
    @RestController
    public class OtherController {
      @ApiOperation(value = "测试接口", notes = "用于测试后台是否可被访问", produces = "application/json")
      @GetMapping("/test")
      public JsonResult Login() {
        return JsonResult.success();
      }
    }
    

    重启访问即可

    v1.0.2

    增加登陆授权

    添加依赖

    采取的是Sa-Token 权限认证.

    <dependency>
        <groupId>cn.dev33</groupId>
        <artifactId>sa-token-spring-boot-starter</artifactId>
        <version>1.28.0</version>
    </dependency>
    

    如果用默认推荐的给每个控制器方法添加鉴权功能,显然不合适,所以我们通过全局拦截器来处理整个项目的
    增加一个拦截器文件interceptor/SaTokenConfigure.java

    package com.dshvv.blogserver.interceptor;
    
    import cn.dev33.satoken.interceptor.SaRouteInterceptor;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    /**
     * <p>
     *  SaToken全局拦截器,校验登录
     *  参考 https://www.cnblogs.com/yunchu/p/14304900.html、
     *  参考 https://www.cnblogs.com/yunchu/p/14362461.html (重点)
     * </p>
     *
     * @author 丁少华
     * @since 2022-01-07
     */
    
    @Configuration
    public class SaTokenConfigure implements WebMvcConfigurer {
        // 注册拦截器
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 注册Sa-Token的路由拦截器
            registry.addInterceptor(new SaRouteInterceptor())
                    .addPathPatterns("/**")
                    .excludePathPatterns("/login","/reg")
                    .excludePathPatterns("/swagger**/**", "/v3/**", "/doc.html","/webjars/**"); //排除swagger设置
        }
    }
    

    对SaToken插件进行配置

    其实这个是非必需,因为不配置都有默认值,但是为了为了学习,和实验,还是配置一下吧,
    application.yml增加如下配置

    sa-token:
      token-name: satoken # token名称 (同时也是cookie名称)
      timeout: 5 # token有效期,单位s 默认30天, -1代表永不过期
    

    验证配置结果

    如何看SaToken是否生效呢?
    当然是写一个控制器,启动项目,用postMan测试接口啦。

    package com.dshvv.blogserver.controller;
    
    import cn.dev33.satoken.stp.StpUtil;
    import cn.dev33.satoken.util.SaResult;
    import com.dshvv.blogserver.service.IUserService;
    import com.dshvv.blogserver.utils.JsonResult;
    import io.swagger.annotations.ApiOperation;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.servlet.ModelAndView;
    import java.util.Map;
    
    @RequestMapping
    @RestController
    public class OtherController {
        @ApiOperation(value = "测试接口", notes = "用于测试后台是否可被访问", produces = "application/json")
        @GetMapping("/test")
        public JsonResult doTest() {
            return JsonResult.success();
        }
    
        // 登录
        @ApiOperation(value = "登录接口", notes = "用于用户登录", produces = "application/json")
        @PostMapping("/login")
        public SaResult doLogin(@RequestBody Map<String, Object> user) {
            String name = (String) user.get("name");
            String pwd = (String) user.get("pwd");
            // 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
            if("yan".equals(name) && "yh@0020".equals(pwd)) {
                StpUtil.login(10001);
                return SaResult.ok("登录成功");
            }
            return SaResult.error("登录失败");
        }
    }
    

    除此之外在启动项目的时候,启动类可以打印输出当前SaToken正在使用的配置项,用来确认application.yml配置是否生效

    @SpringBootApplication
    public class DemoServerApplication {
        public static void main(String[] args) {
            SpringApplication.run(DemoServerApplication.class, args);
            System.out.println("启动成功:Sa-Token配置如下:" + SaManager.getConfig());
        }
    }
    

    v1.0.3

    增加全局跨域处理
    同样,偷懒也不想用@CrossOrigin一个个的去注解类来解决跨域,所以同样的用拦截器
    增加处理跨域的全局拦截器类interceptor/CorsConfigurer.java

    package com.dshvv.blogserver.interceptor;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    /**
     * <p>
     *  跨域处理 
     *  参考: http://www.telami.cn/2019/springboot-resolve-cors/
     * </p>
     *
     * @author 丁少华
     * @since 2022-01-07
     */
    @Configuration
    public class CorsConfigurer implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOriginPatterns("*")
                    .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
                    .allowCredentials(true)
                    .maxAge(3600)
                    .allowedHeaders("*");
        }
    }
    

    v1.0.4

    全局异常处理
    这个很实用,比如登陆超时啊啥的
    新增处理异常类exception/GlobalExceptionHandler.java

    package com.dshvv.blogserver.exception;
    
    import cn.dev33.satoken.exception.NotLoginException;
    import com.dshvv.blogserver.utils.JsonResult;
    import org.springframework.dao.DuplicateKeyException;
    import org.springframework.http.HttpStatus;
    import org.springframework.web.bind.annotation.*;
    import javax.servlet.http.HttpServletRequest;
    import java.sql.SQLIntegrityConstraintViolationException;
    
    //ExceptionHandler的处理顺序是由异常匹配度来决定的,且我们也无法通过其他途径指定顺序(其实也没有必要)
    
    /**
     * 全局异常处理器
     */
    @ControllerAdvice // @ControllerAdvice将当前类标识为异常处理的组件
    @RestController
    public class GlobalExceptionHandler {
    
        @ExceptionHandler(NotLoginException.class)
        @ResponseStatus(HttpStatus.OK)
        protected JsonResult handleException(HttpServletRequest request, NotLoginException ex) {
            JsonResult result = new JsonResult();
            result.setCode(401);
            result.setMsg("用户未登录或已过期,请重新登录");
            return result;
        }
    
        @ExceptionHandler(DuplicateKeyException.class)
        @ResponseStatus(HttpStatus.OK)
        public JsonResult handleException(HttpServletRequest req, DuplicateKeyException ex) {
            JsonResult result = new JsonResult();
            result.setCode(1);
            result.setMsg("邮箱已经被注册");
            return result;
        }
    
        @ExceptionHandler(Exception.class)  // @ExceptionHandler用于设置所标识方法处理的异常 参数代表异常类型
        @ResponseStatus(HttpStatus.OK)
        public JsonResult handleException(HttpServletRequest req, Exception ex) {
            ex.printStackTrace();
            JsonResult result = new JsonResult();
            result.setCode(1);
            result.setMsg("系统错误");
            return result;
        }
    }
    
  • 相关阅读:
    找出水王
    第九周进度表
    [设计模式]组合模式
    [设计模式]外观模式
    [设计模式]策略模式
    [设计模式] 6个设计遵循基本原则
    [OSGI]Eclipse4.2 OSGI依赖Bundle
    [xfire]使用xfire开发webservice的简单示例
    [HTML5 Canvas学习]使用颜色和透明度
    [HTML5 Canvas学习]绘制矩形
  • 原文地址:https://www.cnblogs.com/dshvv/p/15770380.html
Copyright © 2020-2023  润新知