1、集成swagger+shiro放行
(1)导包
(2)SwaggerConfig(公共)
package com.smart.community.common.swagger.config;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import javax.annotation.Resource;
/**
* @author liuhuitang
*/
@Configuration
@EnableOpenApi
public class SwaggerConfig {
@Resource
private SwaggerProperties swaggerProperties;
@Bean
public Docket docket(ApiInfo apiInfo){
return new Docket(DocumentationType.OAS_30).apiInfo(apiInfo)
.enable(swaggerProperties.getEnable())
.groupName(swaggerProperties.getGroupName())
.select()
.apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()))
.paths(PathSelectors.any())
.build();
}
@Bean
public ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title(swaggerProperties.getTitle())
.description(swaggerProperties.getDescription())
.version(swaggerProperties.getVersion())
.contact(new Contact(swaggerProperties.getName(), swaggerProperties.getUrl(), swaggerProperties.getEmail()))
.build();
}
}
(3)SwaggerProperties(公共)
package com.smart.community.common.swagger.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author liuhuitang
*/
@Component
@ConfigurationProperties("swagger")
@Data
public class SwaggerProperties {
private String title;
private String basePackage;
private String groupName = "default-group";
private String description;
private String name;
private String url;
private String email;
private Boolean enable = true;
private String version;
}
(4)yml文件(公共)
spring:
# swagger使用
mvc:
# 配置Spring MVC如何匹配URL路径
path-match:
# 基于Ant风格的路径模式匹配
matching-strategy: ant_path_matcher
(5)yml文件(具体)
swagger:
base-package: "com.smart.community.services.controller"
title: "智慧社区在线Api文档"
group-name: "物业服务模块"
description: "出现bug,请熟读该文档"
name: "智慧社区"
url: "https://www.baidu.com"
email: "11111@163.com"
version: "V1.0.0"
(6)设置放行(具体yml里面)
shiro:
loginUrl: "/test/no/login"
white:
list: "/auth/**,/doc.html,/swagger**/**,/webjars/**,/v3/**,/druid/**"
(7)ShiroConfig 重新配置
package com.smart.community.services.config;
import com.smart.community.services.realm.UserRealm;
import com.smart.community.services.session.CustomSessionManager;
import com.smart.community.services.utils.ShiroUtils;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
/**
* @author liuhuitang
*/
@Configuration
public class ShiroConfig {
public static final String SHIRO_ANON="anon";
public static final String SHIRO_AUTHC = "authc";
@Value("${shiro.white.list}")
private List<String> whiteList;
/**
* 注册realm
* @return
*/
@Bean
public UserRealm realm(HashedCredentialsMatcher hashedCredentialsMatcher){
UserRealm userRealm = new UserRealm();
userRealm.setCredentialsMatcher(hashedCredentialsMatcher);
return userRealm;
}
/**
* 注册realmmanager
* @param realm
* @return
*/
@Bean
public DefaultWebSecurityManager securityManager(UserRealm realm,CustomSessionManager customSessionManager){
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
//注册自定义Realm
defaultWebSecurityManager.setRealm(realm);
//注册session
defaultWebSecurityManager.setSessionManager(customSessionManager);
return defaultWebSecurityManager;
}
/**
* 注册过滤器
* @return
*/
@Bean
public ShiroFilterChainDefinition shiroFilterChainDefinition(){
DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
//白名单(支持通配符)
//放行
whiteList.forEach(path->definition.addPathDefinition(path,SHIRO_ANON));
//表示其他所有接口需要认证
definition.addPathDefinition("/**",SHIRO_AUTHC);
return definition;
}
/**
* 注册密码加密器
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName(Md5Hash.ALGORITHM_NAME);
hashedCredentialsMatcher.setHashIterations(ShiroUtils.HASH_ITERATIONS);
// hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
return hashedCredentialsMatcher;
}
/**
* cookie+session
* jwt
*/
@Bean
public CustomSessionManager sessionManager(){
CustomSessionManager customSessionManager = new CustomSessionManager();
// session的过期时间 -1永不过期 0用一次 >0根据时间(单位毫秒)
//todo 作用?
customSessionManager.setGlobalSessionTimeout(7*24*60*60*1000);
customSessionManager.setSessionIdCookieEnabled(true);
customSessionManager.setSessionIdUrlRewritingEnabled(false);
return customSessionManager;
}
}
2、mybatisPlus的配置分页转换
package com.smart.community.common.db.utils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.BeanUtils;
import org.springframework.util.ObjectUtils;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
* @author liuhuitang
*/
public class CommonBeanUtils extends BeanUtils {
/**
* 将A对象的属性赋值给B对象
* @param source
* @param targetSupplier
* @return
* @param <S>
* @param <T>
*/
public static <S,T> T convertTo(S source, Supplier<T> targetSupplier){
// 这里的ObjectUtils.isEmpty(targetSupplier)是为了方式下面的get出现空指针异常
if (ObjectUtils.isEmpty(source) || ObjectUtils.isEmpty(targetSupplier)){
return null;
}
T t = targetSupplier.get();
copyProperties(source,t);
return t;
}
/**
* 调用convertTo(s, targetSupplier)方法来生成一个新的T类型对象。
* 然后使用collect(Collectors.toList())将所有这些新生成的T类型对象收集到一个新的列表中
* @param sources
* @param targetSupplier
* @return
* @param <S>
* @param <T>
*/
public static <S,T> List<T> convertListTo(List<S> sources, Supplier<T> targetSupplier){
if (ObjectUtils.isEmpty(sources) || ObjectUtils.isEmpty(targetSupplier)){
return null;
}
//把每个对象赋值属性然后用collect转为集合
return sources.stream().map(s -> convertTo(s,targetSupplier)).collect(Collectors.toList());
}
/**
* mybatisplus 配置分页转换
* @param source
* @param target
* @param targetSupplier
* @return
* @param <S>
* @param <T>
*/
public static <S,T> IPage<T> convertPageInfo(IPage<S> source, IPage<T> target, Supplier<T> targetSupplier){
//属性复制
copyProperties(source,target);
target.setRecords(convertListTo(source.getRecords(),targetSupplier));
return target;
}
}