boot父依赖? 可以指定版本号(指定后boot其他依赖不加版本号不报错 否则报错)??
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/>
</parent>
boot的web依赖 开启boot的注解 配置啥的
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
?boot的测试依赖?
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
boot 数据效验依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
mysql 依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
阿里连接池依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
mybatisplus 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
Data 依赖?
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
jwt 依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.13.0</version>
</dependency>
热部署
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
shiro依赖
<!-- shiro依赖-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.8.0</version>
</dependency>
测试框架依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
maven打包工具
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
代码生成依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
代码生成配置文件
package com.project.util;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
/**
* @Author 955
* @Date 2022-04-13 18:36
* @Description
*/
public class CodeGenrator {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/pestcontrol?characterEncoding=utf-8&serverTimezone=Asia/Shanghai", "root", "Yang1997")
.globalConfig(builder -> {
// 设置作者
builder.author("jcy")
// 开启 swagger 模式
.enableSwagger()
// 覆盖已生成文件
.fileOverride()
.dateType(DateType.ONLY_DATE)
//格式化注释日期格式
.commentDate("yyyy年MM月dd日")
// 指定输出目录
.outputDir("E:\\pestControl\\src\\main\\java");
})
.packageConfig(builder -> {
// 设置父包名
builder.parent("com.project")
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, "E:\\pestControl\\src\\main\\resources\\mapper")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
//需要注意的是,在builder后面乱点是点不出来有些方法的,必须先开启相应配置再点,如先.controllerBuilder(),才能继续点属于controllerBuilder的方法
//官方api文档地址:https://baomidou.com/pages/981406/#%E6%95%B0%E6%8D%AE%E5%BA%93%E9%85%8D%E7%BD%AE-datasourceconfig
// 设置需要生成的表名(,user_industry,industry_specific,industry_info,family_member)
builder.addInclude("line_info")
//开启lombok注解(需要引入lombok依赖)
.entityBuilder().enableLombok()
//设置id类型
.idType(IdType.ASSIGN_ID)
// //设置逻辑删除字段
// .logicDeleteColumnName("zxbz")
//开启字段映射表字段名注解
.enableTableFieldAnnotation()
//定义service命名规范
.serviceBuilder().formatServiceFileName("%sService")
//开启controller配置
.controllerBuilder()
//使用rest风格
.enableRestStyle();
// 设置过滤表前缀
// .addTablePrefix("t_", "c_");
})
// 使用Freemarker引擎模板,默认的是Velocity引擎模板
// .templateEngine(new FreemarkerTemplateEngine())
.execute();
}
}
json 转换依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
token 解码 创建配置
package com.project.util;
/**
* xx类
*
* @author jcy
* @description:token配置
* @since 2022/10/12 18:18
*/
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;
public class token {
private static final long EXPIRE_TIME = 1000 * 60 * 24;
private static final String TOKEN_SECRET = "68a34f98-7fd7-4fb7-956a-def1e491b641";
public static String createToken(String json) {
//过期时间
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
//私钥及加密算法
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
//设置头信息
HashMap<String, Object> header = new HashMap<>(2);
header.put("typ", "JWT");
header.put("alg", "HS256");
//附带username和userID生成签名
String token = JWT.create().withHeader(header)
.withClaim("info", json)
.withExpiresAt(date).sign(algorithm);
return token;
}
public static String verifierJwt(String token) {
//私钥及加密算法
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
String info = "";
JWTVerifier verifier = JWT.require(algorithm).build();
try {
DecodedJWT jwt = verifier.verify(token); //认证token
info = jwt.getClaim("info").asString();//取token中的信息
} catch (Exception e) {
return "502";
}
return info;
}
public static void main(String[] args) throws InterruptedException {
System.out.println(UUID.randomUUID());
}
}
swagger文档依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
文档 配置及使用 注意 :{需要在启动类加上@EnableWebMvc? 或者在application.yml spring下:mvc: pathmatch: matching-strategy: ant_path_matcher?}
/**
* 实体类
*
* @author jcy
* @description:user实体
* @since 2022/10/12 14:13
*/
@Data
@ApiModel
public class UserEntity {
@ApiModelProperty(value ="用户名" )
private String userName;
@ApiModelProperty(value = "密码")
private String passWord;
@ApiModelProperty(value = "年龄",hidden = true)
private int age ;
}
/**
* 控制层
*
* @author jcy
* @description:拦截器控制器测试
* @since 2022/10/12 11:40
*/
@RestController
@RequestMapping("boot")
@Api(tags = "上传接口")
public class HandlerController {
@ApiOperation(value = "AOP测试")
@GetMapping("testInterceptor")
public String testInterceptor() {
return "hello AOP";
}
@ApiOperation(value = "用户信息查询")
@GetMapping("userInfo/{userName}/{passWord}/info")
public String userInfo(@PathVariable("userName") String userName,
@PathVariable("passWord") String passWord) {
String user = "";
if (userName.equals("zy")) {
user = "赵云";
} else if (userName.equals("lc")) {
user = "林冲";
} else {
user = "马超";
}
return user;
}
@ApiOperation(value = "保存用户")
@PostMapping("saveUser")
public boolean saveUser(UserEntity user) {
System.out.println(user.getUserName());
return true;
}
/**
* swwger 配置类
*
* @author jcy
* @description:配置文件
* @since 2022/10/12 14:21
*/
@Configuration
@EnableOpenApi
public class SwaggerConfiguration {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("BOOT接口文档")
.description("BOOT接口文档")
.version("1.0")
.build();
}
@Bean
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebMvcRequestHandlerProvider) {
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
}
return bean;
}
private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(
List<T> mappings) {
List<T> copy = mappings.stream().filter(mapping -> mapping.getPatternParser() == null)
.collect(Collectors.toList());
mappings.clear();
mappings.addAll(copy);
}
@SuppressWarnings("unchecked")
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
try {
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
field.setAccessible(true);
return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
};
}
}
?拦截器 配置 两个类?
/** 拦截类
* xx类
*
* @author jcy
* @description:配置拦截器
* @since 2022/10/12 11:44
*/
@Component
public class Config implements WebMvcConfigurer {
@Autowired
HandlerConfig handlerConfig;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(handlerConfig)
.addPathPatterns("/boot/**")
.excludePathPatterns("boot/test");
}
/**
* 拦截器业务类
*
* @author jcy
* @description:拦截器
* @since 2022/10/12 11:43
*/
@Component
public class HandlerConfig implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// response.setCharacterEncoding("utf-8");
// PrintWriter ps = response.getWriter();
// ps.write("非法操作");
// ps.flush();
// ps.close();
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
shiro 配置 及使用
/**
* 配置类 启动程序自动进入此类
*
* @author 简重阳
* @description:shiro配置
* @since 2022/10/13 16:17
*/
@Configuration
public class ShiroConfig {
/**
* 认证过滤器:
* anon:无需认证即可访问,游客身份。
* authc:必须认证(登录)才能访问。
* authcBasic:需要通过 httpBasic 认证。
* user:不一定已通过认证,只要是曾经被 Shiro 记住过登录状态的用户就可以正常发起请求,比如 rememberMe。
* <p>
* 授权过滤器:
* perms:必须拥有对某个资源的访问权限(授权)才能访问。
* role:必须拥有某个角色权限才能访问。
* port:请求的端口必须为指定值才可以访问。
* rest:请求必须是 RESTful,method 为 post、get、delete、put。
* ssl:必须是安全的 URL 请求,协议为 HTTPS。
*
* @param manager
* @return
*/
@Bean
public ShiroFilterFactoryBean filterFactoryBean(@Qualifier("manager") DefaultWebSecurityManager manager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(manager);
// Map<String,String> map = new HashMap<>();
// map.put("/main","authc");
// map.put("/test","authc");
// factoryBean.setFilterChainDefinitionMap(map);
//设置登录页面
factoryBean.setLoginUrl("/login/**");
//未授权页面
factoryBean.setUnauthorizedUrl("/unauth");
return factoryBean;
}
@Bean
public DefaultWebSecurityManager manager(@Qualifier("myRealm") MyRealm myRealm) {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(myRealm);
return manager;
}
}
/**
* 第二个方法查询是否有这个用户类 然后返回前段 前段再次请求 访问第一个方法 查询数据库权限保存
*
* @author 简重阳
* @description:shiro返回数据的配置
* @since 2022/10/13 16:19
*/
@Component
public class MyRealm extends AuthorizingRealm {
@Autowired
UserService userService;
@Autowired
PowerService powerService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
User u = (User) principalCollection.getPrimaryPrincipal();
//用用户查询权限
List<Power> list = powerService.allPower(u.getUserName());
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
list.stream().filter(power -> power != null && !power.getUserId().equals(""))
.forEach(
powerEntity ->
info.addStringPermission(powerEntity.getPowerResource())
);
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
char[] passArray = token.getPassword();
String username = token.getUsername();
String password = String.valueOf(passArray);
//从数据库查询用户是否存在
User user = userService.find(username, password);
if (null != user) {
return new SimpleAuthenticationInfo(user, password, username);
}
return null;
}
}
/**
* 控制层
*
* @author 简重阳
* @description:权限控制层
* @since 2022/10/13 16:35
*/
@RestController
@RequestMapping("good")
public class GoodController {
@GetMapping("findUserInfoNew1")
public String findUserInfo3(){
//此处判断是否有次权限
if(SecurityUtils.getSubject().isPermitted("权限一")){
return "权限一";
}
return "权限一";
}
shiro配合拦截器使用(只需要把控制层的判断 截取到拦截器业务类)
/**
* 拦截类
*
* @author jcy
* @description:拦截器
* @since 2022/10/12 17:44
*/
@Configuration
public class HandlerConfig implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//此处获取返回的权限 用路径替代
String path = request.getRequestURI();
String str = path.substring(path.lastIndexOf("/") + 1);
System.out.println(path);
if (SecurityUtils.getSubject().isPermitted(str)) {
return true;
}
response.setCharacterEncoding("utf-8");
PrintWriter ps = response.getWriter();
ps.write("没有权限");
ps.flush();
ps.close();
return false;
}
|