最初の春ブーツ0からプロジェクトの構築

プロジェクト開発プロジェクトの準備作業:(参考ログ:D:\シェン\ javaの\ webdevelop \春\ログ)

start.spring.io

輸入関連の依存性

 

データベーススキーマ、テーブル構造の定義

フライウェイマップ

 <properties>
        <mybatis-plus-boot-starter.version>3.3.1</mybatis-plus-boot-starter.version>
        <java.version>1.8</java.version>
        <!-- flyway mvn cmd配置-->
        <flyway.url>jdbc:mysql://10.1.252.23:3306/springisp?serverTimezone=GMT%2B8&amp;useSSL=false&amp;characterEncoding=utf8</flyway.url>
        <flyway.user>root</flyway.user>
        <flyway.password>%tBqnWF1y3ku</flyway.password>
        <flyway.locations>filesystem:src/main/resources/db/migration</flyway.locations>
        <!--		<flyway.schemas>schemaName</flyway.schemas>-->
    </properties>
d:\shen\java\webdevelop\spring\ispManager
λ mvn flyway:migrate
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< ik.starriver:ispManager >-----------------------
[INFO] Building ispManager 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- flyway-maven-plugin:6.2.3:migrate (default-cli) @ ispManager ---
[INFO] Flyway Community Edition 6.2.3 by Redgate
[INFO] Database: jdbc:mysql://10.1.252.23:3306/springisp (MySQL 5.7)
[INFO] Successfully validated 1 migration (execution time 00:00.053s)
[INFO] Current version of schema `springisp`: << Empty Schema >>
[INFO] Migrating schema `springisp` to version 1 - init tables
[WARNING] DB: Unknown table 'springisp.tbl_change_history_manager' (SQL State: 42S02 - Error Code: 1051)
[WARNING] DB: Unknown table 'springisp.tbl_contract_file_manager' (SQL State: 42S02 - Error Code: 1051)
[WARNING] DB: Unknown table 'springisp.tbl_contract_manager' (SQL State: 42S02 - Error Code: 1051)
[WARNING] DB: Unknown table 'springisp.tbl_line_manager' (SQL State: 42S02 - Error Code: 1051)
[INFO] Successfully applied 1 migration to schema `springisp` (execution time 00:00.436s)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.679 s
[INFO] Finished at: 2020-03-02T16:49:33+08:00
[INFO] ------------------------------------------------------------------------

d:\shen\java\webdevelop\spring\ispManager
λ

 

コードジェネレータは、MyBatisのを生成し、

<dependencies>
        <!-- MBP code Generator start -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.1</version>
        </dependency>
        <!-- MBP code Generator end -->

D:\シェン\ javaの\ webdevelop \春\ ispManager \ SRC \テスト\ javaの\ MPGenerator.java

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 代码生成器演示
 * </p>
 */
public class MPGenerator {

    final static String  dirPath = "D:\\shen\\java\\webdevelop\\spring\\ispmanager\\src\\main\\java\\";
    final static String  mapperXmlPath = "D:\\shen\\java\\webdevelop\\spring\\ispmanager\\src\\main\\resources\\mappers\\";

    /**
     * <p>
     * MySQL 生成演示
     * </p>
     */
    public static void main(String[] args) {
        AutoGenerator mpg = new AutoGenerator();
        // 选择 freemarker 引擎,默认 Velocity
//        mpg.setTemplateEngine(new FreemarkerTemplateEngine());

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir(dirPath);
        gc.setAuthor("shenxianjie");
        gc.setFileOverride(true); //是否覆盖
//        gc.setActiveRecord(true);// 不需要ActiveRecord特性的请改为false
        gc.setEnableCache(false);// XML 二级缓存
        gc.setBaseResultMap(true);// XML ResultMap
        gc.setBaseColumnList(true);// XML columList

        // 自定义文件命名,注意 %s 会自动填充表实体属性!
        // gc.setMapperName("%sDao");
        // gc.setXmlName("%sMapper");
        // gc.setServiceName("MP%sService");
        // gc.setServiceImplName("%sServiceDiy");
        // gc.setControllerName("%sAction");
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDbType(DbType.MYSQL);
        dsc.setTypeConvert(new MySqlTypeConvert(){
            // 自定义数据库表字段类型转换【可选】
            @Override
            public DbColumnType processTypeConvert(GlobalConfig globalConfig,String fieldType) {
                System.out.println("转换类型:" + fieldType);
                // 注意!!processTypeConvert 存在默认类型转换,如果不是你要的效果请自定义返回、非如下直接返回。
                return (DbColumnType) super.processTypeConvert(globalConfig, fieldType);
            }
        });
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("%tBqnWF1y3ku");
        dsc.setUrl("jdbc:mysql://10.1.252.23:3306/springisp?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf8");
        mpg.setDataSource(dsc);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        // strategy.setCapitalMode(true);// 全局大写命名 ORACLE 注意
//        strategy.setTablePrefix(new String[] { "tianshu_log" });// 此处可以修改为您的表前缀
        strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略
         strategy.setInclude(new String[] {
                 "tbl_change_history_manager"
                 , "tbl_contract_file_manager"
                 , "tbl_contract_manager"
                 , "tbl_line_manager"
         }); // 需要生成的表
        // strategy.setExclude(new String[]{"test"}); // 排除生成的表
        // 自定义实体父类
//         strategy.setSuperEntityClass("ik.starriver.log.SuperEntity");
        // 自定义实体,公共字段
//         strategy.setSuperEntityColumns(new String[] { "id"});
        // 自定义 mapper 父类
//         strategy.setSuperMapperClass("com.baomidou.demo.TestMapper");
        // 自定义 service 父类
        // strategy.setSuperServiceClass("com.baomidou.demo.TestService");
        // 自定义 service 实现类父类
        // strategy.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl");
        // 自定义 controller 父类
        // strategy.setSuperControllerClass("com.baomidou.demo.TestController");
        // 【实体】是否生成字段常量(默认 false)
        // public static final String ID = "test_id";
        // strategy.setEntityColumnConstant(true);
        // 【实体】是否为构建者模型(默认 false)
        // public User setName(String name) {this.name = name; return this;}
        strategy.setEntityBuilderModel(true);
        mpg.setStrategy(strategy);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("ik");
        pc.setModuleName("starriver.ispmanager");
        pc.setController("controller");
        pc.setEntity("entity");
        pc.setMapper("mapper");
        pc.setService("service");
        pc.setServiceImpl("serviceImpl");
        //pc.setXml("mapperXml");

        mpg.setPackageInfo(pc);

        // 注入自定义配置,可以在 VM 中使用 cfg.abc 【可无】
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = new HashMap();
                map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
                this.setMap(map);
            }
        };

        // 自定义 xxList.jsp 生成
        List<FileOutConfig> focList = new ArrayList();
/*        focList.add(new FileOutConfig("/template/list.jsp.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return "D://my_" + tableInfo.getEntityName() + ".jsp";
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);*/

        // 调整 xml 生成目录演示
        focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return mapperXmlPath + tableInfo.getEntityName() + "Mapper.xml";
            }
        });
        cfg.setFileOutConfigList(focList);

        mpg.setCfg(cfg);

        // 关闭默认 xml 生成,调整生成 至 根目录
/*        TemplateConfig tc = new TemplateConfig();
        tc.setXml(null);
        mpg.setTemplate(tc);*/

        // 自定义模板配置,可以 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改,
        // 放置自己项目的 src/main/resources/templates 目录下, 默认名称一下可以不配置,也可以自定义模板名称
        // TemplateConfig tc = new TemplateConfig();
        // tc.setController("...");
        // tc.setEntity("...");
        // tc.setMapper("...");
        // tc.setXml("...");
        // tc.setService("...");
        // tc.setServiceImpl("...");
        // 如上任何一个模块如果设置 空 OR Null 将不生成该模块。
        // mpg.setTemplate(tc);

        // 执行生成
        mpg.execute();

//        System.err.println("mpg finished!");
        // 打印注入设置【可无】
//        System.err.println(mpg.getCfg().getMap().get("abc"));
    }

}

MPGeneratorメインの実行

 

 スキャンパスマッパーインタフェースの設定

package ik.starriver.ispmanager;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan({"ik.starriver.ispmanager.mapper*"})
public class IspManagerApplication {

	public static void main(String[] args) {
		SpringApplication.run(IspManagerApplication.class, args);
	}

}

サービス開始

ノーマル

輸入関連ツールパッケージ

 

コメントを追加します

@Component
public class TblContractFileManager extends BaseModel {

 

@Service
public class TblContractFileManagerServiceImpl extends ServiceImpl<TblContractFileManagerMapper, TblContractFileManager> implements ITblContractFileManagerService {

}

 豆はのRestControllerスプリングによって注釈付き

@RestController
@RequestMapping("/starriver.ispmanager/tblContractFileManager")
public class TblContractFileManagerController extends BaseController<TblContractFileManager, TblContractFileManagerServiceImpl>{

}

 または@BeanアノテーションでApplicationAutoConfiguration(2通りの選択肢)

@Configuration
@ConditionalOnWebApplication
public class ApplicationAutoConfiguration {


    @Bean
    public TblChangeHistoryManagerController tblChangeHistoryManagerController() {
        return new TblChangeHistoryManagerController();
    }

    @Bean
    public TblContractFileManagerController tblContractFileManagerController() {
        return new TblContractFileManagerController();
    }

    @Bean
    public TblLineManagerController tblLineManagerController() {
        return new TblLineManagerController();
    }

    @Bean
    public TblContractManagerController tblContractManagerController() {
        return new TblContractManagerController();
    }
}

データベースの設計は、フィールド名とキーワードの繰り返しに最善ではありません。

    @TableField(value = "description") //映射数据库的字段名
    private String description; //不要使用desc,这是关键字段,会和数据库冲突

データ検証:

一つの方法:ConstraintValidatorカスタム実装クラスは、BaseControllerによって検証ジェネリックに渡され、

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE, TYPE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {ContractManagerValidator.class})
public @interface ContractManagerCA {
    String message() default "ContractManagerCA message";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
@Component
public class ContractManagerValidator implements ConstraintValidator<ContractManagerCA, ContractManager>{

    @Override
    public void initialize(ContractManagerCA constraintAnnotation) {

    }

    @SneakyThrows
    @Override
    public boolean isValid(ContractManager value, ConstraintValidatorContext context) {
        ValidateTimeDelta(value);
        return true;
    }

    public void ValidateTimeDelta(ContractManager data) throws Exception {
        if(!data.getEndDate().isAfter(data.getStartDate())){
            throw new DefaultException("合同结束日期应该大于开始日期");
        }

    }

}
public class BaseController<E extends BaseModel, S extends ServiceImpl, V extends ConstraintValidator> implements
        DeleteOneController
        , DeleteManyController
        , GetOneController
        , GetPageController
        , InsertOneController<ResponseEntity, E>
        , UpdateOneController<ResponseEntity, E> {

    @Autowired
    private S service;

    @Autowired
    private E entity;

    @Autowired
    private V validator;
    
    ...
    @Override
    @RequestMapping(path = "/", method = {RequestMethod.PUT})
    public ResponseEntity update2(@RequestBody E object) {
        try {
            validator.isValid(object, null);
        } catch (Exception e) {
            return this.responseEntity.error(e.getMessage().toString());
        }

第二の方法:ノートをチェックする@Valid方法

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE, TYPE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {ContractManagerValidator.class})
public @interface ContractManagerCA {
    String message() default "ContractManagerCA message";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

 

@Component
public class ContractManagerValidator implements ConstraintValidator<ContractManagerCA, ContractManager>{

    @Override
    public void initialize(ContractManagerCA constraintAnnotation) {

    }

    @SneakyThrows
    @Override
    public boolean isValid(ContractManager value, ConstraintValidatorContext context) {
        ValidateTimeDelta(value);
        return true;
    }

    public void ValidateTimeDelta(ContractManager data) throws Exception {
        if(!data.getEndDate().isAfter(data.getStartDate())){
            throw new DefaultException("合同结束日期应该大于开始日期");
        }

    }

}

エンティティに注釈チェックを追加します。

@ContractManagerCA
public class ContractManager extends BaseModel {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
//    @Max(value = 0, message = "id validate failed")
    private Integer id;

パリティチェック注釈要求エンティティオブジェクトインタフェースRequestBody

    @Override
    @RequestMapping(path = "/", method = {RequestMethod.PUT})
    public ResponseEntity update(@Valid @RequestBody E object, Errors error) {
        if (error.hasErrors()) {
            return this.responseEntity.error(error.getFieldError().getDefaultMessage().toString());
        }
        int updateById = service.getBaseMapper().updateById(object);
        return this.responseEntity.success(service.getById(object.getId()));
    }

 

JWTトークン検証

オプション1:AOP

package ik.starriver.log.aspect;

import ik.starriver.log.utils.DefaultResponseEntity;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * //匹配任何以find开头而且只有一个Long参数的方法
 *
 * @Pointcut("execution(* *..find*(Long))")
 *         //匹配任何以find开头的而且第一个参数为Long型的方法
 * @Pointcut("execution(* *..find*(Long,..))")
 *         //匹配任何只有一个Long参数的方法
 * @Pointcut("within(com.imooc..*) && args(Long)")
 *         //匹配第一个参数为Long型的方法
 * @Pointcut("within(com.imooc..*) && args(Long,..)")
 *         Created by cat on 2016-12-04.
 */

@Aspect
@Component
public class ControllerAspect {


    @Autowired
    private DefaultResponseEntity responseEntity;

//    @Pointcut("args(Long,String) && within(com.imooc.service.*)")
//    public void matchArgs() {
//    }
//
//    @Before("matchArgs()")
//    public void before() {
//        System.out.println("");
//        System.out.println("###before");
//    }


//    @Around("execution(* ik.starriver.log.controller..*.*(..))")
    public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
        if (joinPoint.toString().endsWith(".value())")){
            return joinPoint.proceed(); //判断通过,返回执行原函数
        }
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            if (arg instanceof HttpHeaders) {
                List<String> tokens = ((HttpHeaders) arg).getValuesAsList(HttpHeaders.AUTHORIZATION);

                System.err.println(tokens.toString());

                // TODO validate token
                //validate success
//                return joinPoint.proceed();
                //validate fail
                return this.responseEntity.error("validate fail");
            }
        }
        return false;
    }

}

JWTロジック

 

 

 

残りのテンプレート

コード例:

D:\シェン\ javaの\ webdevelop \春\ログ\ SRC \テスト\ javaの\私が主演\川\ログ\ウェブ\残り\ CallingRESTServiceswithRestTemplate.java

use exchange for CRUD

参考春ブート参照

RESTサービスを呼び出す  RestTemplate
RESTサービスを呼び出す  のHttpClient
 
 
公開された105元の記事 ウォン称賛33 ビュー30000 +

おすすめ

転載: blog.csdn.net/github_38596081/article/details/104621819
おすすめ