mybatis-plus自动生成代码(整理版)

Springboot集成请参考上篇博文:Springboot集成mybatis-plus自动生成代码

一、CodeGenerator.java

    整理版,添加了注释模版,常用基础方法

package com.hng.business;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * @Author 郝南过
 * @Date 2023/11/6 16:30
 * @Version 1.0
 * mybatis-plus代码生成器官网地址 https://baomidou.com/pages/d357af/
 */
public class CodeGenerator {

    private static final String Author = "郝南过";
    /**数据库连接字段配置**/
    private static final String JDBC_URL = "jdbc:mysql://139.198.179.225:3306/hng?useUnicode=true&useSSL=false&characterEncoding=utf8";
    private static final String JDBC_USER_NAME = "root";
    private static final String JDBC_PASSWORD = "@1Verizon";
    /**包名和模块名配置**/
    private static final String PACKAGE_NAME = "com.hng"; //包名
    private static final String MODULE_NAME = "business"; //模块名
    /**相关路径配置**/
    private static final String projectPath = System.getProperty("user.dir");//项目地址
    private static final String OUT_FILE_PATH =projectPath +"/"+MODULE_NAME+"/src/main/java";//生成文件存放路径(可根据需要指定生成到某个模块下)
    /**相关模式开关**/
    private static final boolean IF_RECOVER_ENABLE = true; //再次调用时是否覆盖原文件
    private static final boolean IF_OPEN_DIRECTORY = false; //是否打开输出目录 默认值:true
    private static final boolean IF_SWAGGER2 = true; //是否开启swagger2模式 实体属性 Swagger2 注解
    private static final boolean IF_BASE_COLUMN_LIST = false; //开启 baseColumnList (通用查询结果列),默认false,开启后mapper.xml文件中将生成对应代码
    private static final boolean IF_BASE_COLUMN_MAP = false; //开启 BaseResultMap (通用查询映射结果),默认false,开启后mapper.xml文件中将生成对应代码
    private static final boolean IF_ACTIVE_RECORD = true; //开启ActiveRecord模式,默认false,参考:https://blog.youkuaiyun.com/qq_31762741/article/details/120392656
    private static final boolean IF_ENABLE_CACHE = false; // 是否在xml中添加二级缓存配置,默认false
    /**表设置**/
    private static final String TABLE_PREFIX = "_";  //表名的前缀,从表生成代码时会去掉前缀,没有前缀就只写_
    /**模版设置**/
    private static final  String templatePath = "/templates/mapper.xml.ftl";// 如果模板引擎是 freemarker
    //private static final String templatePath = "/templates/mapper.xml.vm";// 如果模板引擎是 velocity
    private static final  String Controller_template = "templates/vm/controller.java";
    private static final  String Service_template = "templates/vm/service.java";
    private static final  String ServiceImpl_template = "templates/vm/serviceImpl.java";

    /**
     * <p>
     * 读取控制台内容 控制台输入模块表名回车自动生成对应项目目录中
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }

    /**
     * 主方法,包括(1.全局配置、2.数据源配置、3.包配置、4.自定义配置、5.模版配置、6.策略配置)
     * @param args
     */
    public static void main(String[] args) {
        //代码生成器
        AutoGenerator mpg = new AutoGenerator();
        //全局配置
        GlobalConfig gc = new GlobalConfig();
        GlobalConfig(gc,mpg);
        //数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        DataSourceConfig(dsc,mpg);
        //包配置
        PackageConfig pc = new PackageConfig();
        PackageConfig(pc,mpg);
        //自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };
        InjectionConfig(cfg,mpg);
        //模版配置
        TemplateConfig templateConfig = new TemplateConfig();
        TemplateConfig(templateConfig,mpg);
        //策略配置
        StrategyConfig strategy = new StrategyConfig();
        StrategyConfig(strategy,pc,mpg);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }

    // 全局配置
    private static AutoGenerator GlobalConfig(GlobalConfig gc,AutoGenerator mpg){
        gc.setFileOverride(IF_RECOVER_ENABLE);//再次调用时是否覆盖原文件
        gc.setOutputDir(OUT_FILE_PATH);
        gc.setAuthor(Author);
        gc.setOpen(IF_OPEN_DIRECTORY); //是否打开输出目录 默认值:true
        gc.setSwagger2(IF_SWAGGER2); //是否开启swagger2模式 实体属性 Swagger2 注解
        gc.setBaseColumnList(IF_BASE_COLUMN_LIST); //开启 baseColumnList (通用查询结果列),默认false
        gc.setBaseResultMap(IF_BASE_COLUMN_MAP); //开启 BaseResultMap (通用查询映射结果),默认false
        gc.setActiveRecord(IF_ACTIVE_RECORD); //开启ActiveRecord模式,默认false
        gc.setEnableCache(IF_ENABLE_CACHE); // 是否在xml中添加二级缓存配置,默认false
        gc.setIdType(IdType.AUTO);// AUTO(0)使用数据库id,NONE(1)不设置id生成策略,INPUT(2)用户手工输入id,ASSIGN_ID(3)雪花算法生成id(可兼容数值型与字符串型),ASSIGN_UUID(4)以UUID生成算法作为id生成策略
        // 自定义文件命名,注意 %s 会自动填充表实体属性(各层文件名称方式,例如:%sAction生成UserAction, %s为占位符)
        gc.setControllerName("%sController");
        gc.setServiceName("%sService");
        gc.setServiceImplName("%sServiceImpl");
        gc.setMapperName("%sMapper");
        gc.setXmlName("%sMapper");
        //gc.setEntityName("%sEntity");
        mpg.setGlobalConfig(gc);
        return mpg;
    }
    //数据源配置
    private static AutoGenerator DataSourceConfig(DataSourceConfig dsc,AutoGenerator mpg){
        dsc.setUrl(JDBC_URL);
        //dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername(JDBC_USER_NAME);
        dsc.setPassword(JDBC_PASSWORD);
        mpg.setDataSource(dsc);
        return mpg;
    }
    //包配置
    private static AutoGenerator PackageConfig(PackageConfig pc,AutoGenerator mpg){
        //pc.setModuleName(scanner("模块名"));
        pc.setModuleName(MODULE_NAME);
        //你的项目包结构名
        pc.setParent(PACKAGE_NAME);
        mpg.setPackageInfo(pc);
        return mpg;
    }
    //自定义配置
    private static AutoGenerator InjectionConfig(InjectionConfig cfg ,AutoGenerator mpg){
        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化
                // 注意此处要想生效,需要在模版设置中将XML设置为null,使默认的xml目录不再生成
                return projectPath +"/"+ MODULE_NAME + "/src/main/resources/mapper/"
                         + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        /*
        cfg.setFileCreate(new IFileCreate() {
            @Override
            public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
                // 判断自定义文件夹是否需要创建
                checkDir("调用默认方法创建的目录,自定义目录用");
                if (fileType == FileType.MAPPER) {
                    // 已经生成 mapper 文件判断存在,不想重新生成返回 false
                    return !new File(filePath).exists();
                }
                // 允许生成模板文件
                return true;
            }
        });
        */
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);
        return mpg;
    }
    //模版配置
    private static AutoGenerator TemplateConfig(TemplateConfig templateConfig,AutoGenerator mpg){
        // 配置自定义输出模板
        //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        templateConfig.setController(Controller_template);
        templateConfig.setService(Service_template);
        templateConfig.setServiceImpl(ServiceImpl_template);
//        templateConfig.setMapper("templates/vm/mapper.java");
//        templateConfig.setEntity("templates/vm/entity.java");
//        templateConfig.setXml("templates/vm/mapper.xml");
        //使默认的xml目录不再生成,使用自定义的resource/mapper输出目录
        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);
        return mpg;
    }
    //策略配置
    private static AutoGenerator StrategyConfig(StrategyConfig strategy,PackageConfig pc,AutoGenerator mpg){
        //数据库表映射到实体的命名策略
        strategy.setNaming(NamingStrategy.underline_to_camel);
        //数据库表字段映射到实体的命名策略
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);//restful api风格控制器
        // 公共父类
        //strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!");
        // 自动填充
        TableFill createTime = new TableFill("create_Time", FieldFill.INSERT);
        TableFill updateTime = new TableFill("update_Time",FieldFill.INSERT_UPDATE);
        ArrayList<TableFill> tableFills = new ArrayList<TableFill>();
        tableFills.add(createTime);
        tableFills.add(updateTime);
        strategy.setTableFillList(tableFills);

        // 写于父类中的公共字段
        // strategy.setSuperEntityColumns("id");
        strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
        strategy.setControllerMappingHyphenStyle(true);
        //生成实体类等时去掉表前缀
        strategy.setTablePrefix(TABLE_PREFIX);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        return mpg;
    }

}

 补充:FieldFill.INSERT需要实现如下代码(作废)

package com.hng.config.generator;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 自定义元数据对象处理器
 */
@Component
@Slf4j
public class MyMetaObjecthandler implements MetaObjectHandler {
    /**
     * 插入操作自动填充
     *
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        metaObject.setValue("createTime", LocalDateTime.now());
        metaObject.setValue("updateTime", LocalDateTime.now());
//        metaObject.setValue("createBy", BaseContext.getCurentId());
//        metaObject.setValue("updateBy", BaseContext.getCurentId());

    }

    /**
     * 更新操作
     *
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("公共字段");
        metaObject.setValue("updateTime", LocalDateTime.now());
//    metaObject.setValue("updateUser",BaseContext.getCurentId());
    }
}

二、controller.java.ftl

仅提供基础方法,可根据具体需求自行改造

package ${package.Controller};
import com.hng.config.exception.error.ErrorEnum;
import org.springframework.beans.factory.annotation.Autowired;
import com.hng.config.response.Result;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;


import ${package.Entity}.${entity};
import ${package.Service}.${table.serviceName};


/**
* <p>
   * ${table.comment!} 前端控制器
   * </p>
*/
@Slf4j
@Api(value = "${entity}", tags = "${entity}")
@RestController
@RequestMapping("<#if package.ModuleName?? && package.ModuleName != "">/${package.ModuleName}</#if>/<#if controllerMappingHyphenStyle>${controllerMappingHyphen}<#else>${table.entityPath}</#if>")
public class ${table.controllerName} {

   @Autowired
   private ${table.serviceName} ${table.serviceName?uncap_first};

   /**
   * 新增数据
   *
   * @param ${entity?uncap_first} 实体对象
   * @return Result
   */
   @PostMapping("add")
   @ResponseBody
   public Result<?> add(@Validated @RequestBody ${entity} ${entity?uncap_first}) {
      return ${table.serviceName?uncap_first}.add${entity}(${entity?uncap_first});
   }

   /**
   * 根据ID查询数据
   *
   * @param id ID
   * @return Result
   */
   @GetMapping("getById/{id}")
   @ResponseBody
   public Result<?> getById(@PathVariable Long id) {
      if(id!=null){
         return ${table.serviceName?uncap_first}.get${entity}ById(id);
      }
      return Result.Result(ErrorEnum.REQUEST_FAIL, "id为空");
   }

   /**
   * 更新数据
   *
   * @param ${entity?uncap_first} 实体对象
   * @return Result
   */
   @PostMapping("update")
   @ResponseBody
   public Result<?> update(@Validated @RequestBody ${entity} ${entity?uncap_first}) {
      if(${entity?uncap_first}.getId()!=null){
         return ${table.serviceName?uncap_first}.update${entity}(${entity?uncap_first});
      }
      return Result.Result(ErrorEnum.REQUEST_FAIL, "id为空");
   }

   /**
   * 删除数据
   *
   * @param id ID
   * @return Result
   */
   @PostMapping("delete/{id}")
   @ResponseBody
   public Result<?> delete(@PathVariable Long id) {
      if(id!=null){
         return ${table.serviceName?uncap_first}.delete${entity}(id);
      }
      return Result.Result(ErrorEnum.REQUEST_FAIL, "id为空");
   }

}

三、service.java.ftl

仅提供基础方法,可根据具体需求自行改造

package ${package.Service};
import com.hng.config.response.Result;
import ${package.Entity}.${entity};
import ${superServiceClassPackage};

/**
* <p>
    * ${table.comment!} 服务类
    * </p>
*/
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {

    /**
    * 新增数据
    *
    * @param ${"${entity}"} 实体对象
    * @return Result
    */
    Result<?> ${"add${entity}"}(${"${entity}"} ${"${entity?uncap_first}"});

    /**
    * 根据ID查询数据
    *
    * @param id ID
    * @return Result
    */
    Result<?> ${"get${entity}ById(Long id)"};

    /**
    * 更新数据
    *
    * @param ${entity?uncap_first} 实体对象
    * @return Result
    */
    Result<?> ${"update${entity}"}(${entity} ${entity?uncap_first});

    /**
    * 删除数据
    *
    * @param id ID
    * @return Result
    */
    Result<?> ${"delete${entity}"}(Long id);

}

四、serviceImpl.java.ftl

仅提供基础方法,可根据具体需求自行改造

package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import com.hng.config.exception.error.ErrorEnum;
import com.hng.config.response.Result;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;

/**
* <p>
    * ${table.comment!} 服务实现类
    * </p>
*/
@Service
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {

    @Autowired
    private ${table.mapperName} ${table.mapperName?uncap_first};

    /**
    * 新增数据
    *
    * @param ${entity?uncap_first} 实体对象
    * @return Result
    */
    @Override
    public Result<?> add${entity}(${entity} ${entity?uncap_first}) {
<#--        //忽略不需要手动填入的属性插入,预防误填出错-->
<#--        CopyOptions options = CopyOptions.create()-->
<#--        .setIgnoreProperties("createTime").setIgnoreProperties("updateTime")-->
<#--        .setIgnoreProperties("createBy").setIgnoreProperties("updateBy");-->
<#--        BeanUtil.copyProperties(${entity?uncap_first}, ${entity?uncap_first},options);-->
        BeanUtil.copyProperties(${entity?uncap_first}, ${entity?uncap_first});
        return Result.Result(${table.mapperName?uncap_first}.insert(${entity?uncap_first}) > 0 ?
        ErrorEnum.SUCCESS:ErrorEnum.REQUEST_FAIL , null);
    }

    /**
    * 根据ID查询数据
    *
    * @param id ID
    * @return responseResult
    */
    @Override
    public Result<?> get${entity}ById(Long id) {
        ${entity} ${entity?uncap_first} = ${table.mapperName?uncap_first}.selectById(id);
        if(${entity?uncap_first} != null){
            return Result.Result(ErrorEnum.SUCCESS, ${entity?uncap_first});
        }else{
            return Result.Result(ErrorEnum.DATA_NOT_FOUND, null);
        }
    }

    /**
    * 更新数据
    *
    * @param ${entity?uncap_first} 实体对象
    * @return Result
    */
    @Override
    public Result<?> update${entity}(${entity} ${entity?uncap_first}) {
        if(${table.mapperName?uncap_first}.updateById(${entity?uncap_first}) > 0){
            return Result.Result(ErrorEnum.SUCCESS, "更新成功");
        }else{
            return Result.Result(ErrorEnum.DATA_NOT_FOUND, null);
        }
    }

    /**
    * 删除数据
    *
    * @param id ID
    * @return Result
    */
    @Override
    public Result<?> delete${entity}(Long id) {
        if(${table.mapperName?uncap_first}.deleteById(id) > 0 ){
            return Result.Result(ErrorEnum.SUCCESS, "删除成功");
        }else{
            return Result.Result(ErrorEnum.DATA_NOT_FOUND,null);
        }
    }
}

五、其他注意事项

       代码中涉及的ErrorEnum.java 和 Result.java 为之前博文【Springboot项目返回数据统一封装】所写,如需要可参考: Springboot项目返回数据统一封装。也可直接替换成公共的或自己代码中自定义的。

首先需要引入相关的依赖,包括JWT和Spring Security的依赖: ``` <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 然后创建一个JwtTokenUtil类来实现JWT的签发和验证功能: ```java import io.jsonwebtoken.Claims; import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.stereotype.Component; import java.util.Date; import java.util.HashMap; import java.util.Map; @Component public class JwtTokenUtil { private static final String CLAIM_KEY_USERNAME = "sub"; private static final String CLAIM_KEY_CREATED = "created"; @Value("${jwt.secret}") private String secret; @Value("${jwt.expiration}") private Long expiration; public String generateToken(UserDetails userDetails) { Map<String, Object> claims = new HashMap<>(); claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername()); claims.put(CLAIM_KEY_CREATED, new Date()); return generateToken(claims); } public String getUsernameFromToken(String token) { String username; try { Claims claims = getClaimsFromToken(token); username = claims.getSubject(); } catch (Exception e) { username = null; } return username; } public Date getCreatedDateFromToken(String token) { Date created; try { Claims claims = getClaimsFromToken(token); created = new Date((Long) claims.get(CLAIM_KEY_CREATED)); } catch (Exception e) { created = null; } return created; } public Date getExpirationDateFromToken(String token) { Date expiration; try { Claims claims = getClaimsFromToken(token); expiration = claims.getExpiration(); } catch (Exception e) { expiration = null; } return expiration; } public boolean isTokenExpired(String token) { Date expiration = getExpirationDateFromToken(token); return expiration.before(new Date()); } public String refreshToken(String token) { String refreshedToken; try { Claims claims = getClaimsFromToken(token); claims.put(CLAIM_KEY_CREATED, new Date()); refreshedToken = generateToken(claims); } catch (Exception e) { refreshedToken = null; } return refreshedToken; } public boolean validateToken(String token, UserDetails userDetails) { String username = getUsernameFromToken(token); return username.equals(userDetails.getUsername()) && !isTokenExpired(token); } private Claims getClaimsFromToken(String token) { Claims claims; try { claims = Jwts.parser() .setSigningKey(secret) .parseClaimsJws(token) .getBody(); } catch (Exception e) { claims = null; } return claims; } private String generateToken(Map<String, Object> claims) { Date expirationDate = new Date(System.currentTimeMillis() + expiration * 1000); JwtBuilder builder = Jwts.builder() .setClaims(claims) .setExpiration(expirationDate) .signWith(SignatureAlgorithm.HS512, secret); return builder.compact(); } } ``` 其中,JwtTokenUtil类中的generateToken方法用于生成JWT Token,getUsernameFromToken和getExpirationDateFromToken方法用于解析JWT Token中的用户名和过期时间,isTokenExpired方法用于判断JWT Token是否已经过期,refreshToken方法用于刷新JWT Token,validateToken方法用于验证JWT Token是否有效,getClaimsFromToken方法用于从JWT Token中获取Claims。 然后在Spring Security的配置类中添加JwtTokenFilter来实现JWT的过滤和验证: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Autowired private JwtTokenFilter jwtTokenFilter; @Autowired private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder()); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/login").permitAll() .anyRequest().authenticated() .and() .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint) .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); http.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class); } @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } } ``` 其中,SecurityConfig类中的configure方法用于配置Spring Security的策略,addFilterBefore方法用于添加JwtTokenFilter,authenticationManagerBean方法用于获取AuthenticationManager。 最后,在登录接口中,使用JwtTokenUtil生成JWT Token并返回给前端: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class AuthController { @Autowired private AuthenticationManager authenticationManager; @Autowired private JwtTokenUtil jwtTokenUtil; @Autowired private UserDetailsService userDetailsService; @PostMapping("/login") public ResponseEntity<?> login(@RequestBody AuthRequest authRequest) throws Exception { try { Authentication authentication = authenticationManager.authenticate( new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword()) ); UserDetails userDetails = userDetailsService.loadUserByUsername(authRequest.getUsername()); String token = jwtTokenUtil.generateToken(userDetails); return ResponseEntity.ok(new AuthResponse(token)); } catch (Exception e) { throw new Exception("Incorrect username or password", e); } } } ``` 其中,AuthController类中的login方法用于处理登录请求,通过authenticationManager.authenticate方法验证用户名和密码,然后使用JwtTokenUtil生成JWT Token并返回给前端。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郝南过

感谢大佬打赏,送你一个么么哒

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值