在这里,我想记录一些我之前学习的小程序开发和springboot开发方面的知识
这是我的目录结构
我的配置类,在这里我习惯了yml格式的配置样式
server:
tomcat:
uri-encoding: utf-8
threads:
max: 200
min-spare: 30
connection-timeout: 5000ms
port: 8080
servlet:
context-path: /emos-wx-api
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/emos?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: 123456
initial-size: 8
max-active: 16
min-idle: 8
max-wait: 60000
test-while-idle: true
test-on-borrow: false
test-on-return: false
redis:
database: 0
host: 47.106.153.108
port: 6379
password:
jedis:
pool:
max-active: 1000
max-wait: -1ms
max-idle: 16
min-idle: 8
data:
mongodb:
host: localhost
port: 27017
database: emos
authentication-database: admin
mybatis:
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: com.example.emos.wx.db.pojo
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
logging:
level:
root: info
com.example.emos.wx.db.dao: warn
pattern:
console: "%d{HH:mm:ss} %-5level %msg%n"
emos:
jwt:
secret: abc123456
expire: 5
cache-expire: 10
wx:
app-id: 自己在小程序公众平台申请
app-secret: 自己在小程序公众平台申请
我引用的pom文件坐标
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>emos-wx-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>emos-wx-api</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.13</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.4.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.11</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.13</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.12.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
我习惯从头开始说起
首先我先从我的aop切面类开始说起
注解说明
@Aspect:作用是把当前类标识为一个切面供容器读取
@Pointcut:Pointcut是植入Advice的触发条件。每个Pointcut的定义包括2部分,一是表达式,二是方法签名。方法签名必须是 public及void型。可以将Pointcut中的方法看作是一个被Advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为 此表达式命名。因此Pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码。
@Around:环绕增强,相当于MethodInterceptor
@AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行
@Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有
@AfterThrowing:异常抛出增强,相当于ThrowsAdvice
@After: final增强,不管是抛出异常或者正常退出都会执行
@Aspect
@Component
public class TokenAspect {
@Resource
private ThreadLocalToken threadLocalToken;
@Pointcut("execution(public * com.example.emos.wx.controller.*.*(..))")
public void aspect()
{
}
@Around("aspect()")
public Object around(ProceedingJoinPoint point) throws Throwable{
//返回方法执行结果 point.proceed();
R r=(R)point.proceed();
String token = threadLocalToken.getToken();
if (token!=null)
{
r.put("token",token);
threadLocalToken.clear();
}
return r;
}
}
统一的返回方法类
在这里我觉得没什么,不过,他的链式调用实在是高,本来就是继承了hashmap,然而自己写多一个方法put,返回值为本类,也就是说,我通过自己写的put方法,将我自己put进去的值追加到后面去了,可以重叠也可以追加
public class R extends HashMap<String,Object> {
public R(){
put("code", HttpStatus.SC_OK);
put("msg","success");
}
//链式调用
public R put(String key,Object value)
{
super.put(key,value);
return this;
}
//静态工厂方法
public static R ok(){
return new R();
}
public static R ok(String msg)
{
R r=new R();
r.put("msg",msg);//这里就是把前面的消息进行覆盖
return r;
}
public static R ok(Map<String,Object> map)
{
R r=new R();
r.putAll(map);
return r;
}
public static R error(int code,String msg)
{
R r=new R();
r.put("code",code);
r.put("msg",msg);
return r;
}
//当我没有传递状态码时,我们默认状态码为HttpStatus.SC_INTERNAL_SERVER_ERROR 500
public static R error(String msg)
{
R r=error(HttpStatus.SC_INTERNAL_SERVER_ERROR,msg);
return r;
}
public static R error()
{
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR,"未知异常,请联系管理员");
}
}
接下来是shiro包下的配置类
在jwt类中,我主要是想实现创建token,获取token中用户的id还有验证token是否有效
@Component
@Slf4j
public class JwtUtil {
@Value("${emos.jwt.secret}")
private String secret;
@Value("${emos.jwt.expire}")
private int expire;
//创建token
public String createToken(int userId){
//根据过期时间,密钥和userid生成token
//找到当前日期的五天后的时间
Date date = DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, 5);
//把密钥封装成加密算法
Algorithm algorithm=Algorithm.HMAC256(secret);
//创建jwt内部类
JWTCreator.Builder builder= JWT.create();
//生成密钥
String token= builder.withClaim("userId",userId).withExpiresAt(date).sign(algorithm);
return token;
}
//从token中获取userid
public int getUserId(String token)
{
//创建一个解码对象
DecodedJWT jwt=JWT.decode(token);
int userId=jwt.getClaim("userId").asInt();
return userId;
}
//验证令牌字符串的有效性
public void verifierToken(String token)
{
Algorithm algorithm=Algorithm.HMAC256(secret);
//创建一个验证对象
JWTVerifier verifier=JWT.require(algorithm).build();
verifier.verify(token);
}
}
Oauthfilter过滤类
@Component
//说明这是一个多例对象,如果不添加,说明全局使用一个对象
@Scope("prototype")
public class OAuth2Filter extends AuthenticatingFilter {
@Resource
private ThreadLocalToken localToken;
@Value("${emos.jwt.cache-expire}")
private int cacheExpire;
@Resource
private JwtUtil jwtUtil;
@Resource
private RedisTemplate redisTemplate;
@Override
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest req= (HttpServletRequest) request;
String token=getRequestToken(req);
//判断返回的token是否为空
if(StrUtil.isBlank(token))
{
return null;
}
return new OAuth2Token(token);
}
//判断哪一种请求需要shiro框架处理
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
HttpServletRequest req= (HttpServletRequest) request;
//判断请求是不是option请求,option是假请求,直接放行
if(req.getMethod().equals(RequestMethod.OPTIONS.name()))
{
return true;
}
//不是的话就需要shiro去处理
return false;
}
//执行
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest req= (HttpServletRequest) request;
HttpServletResponse resp= (HttpServletResponse) response;
//在响应中设置信息
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
//这两个响应是后端项目允许跨域请求
resp.setHeader("Access-Control-Allow-Credentials","true");
resp.setHeader("Access-Control-Allow-Origin",req.getHeader("Origin"));
//当我发现令牌需要刷新时,我就清空令牌
localToken.clear();
String token=getRequestToken(req);
if(StrUtil.isBlank(token))
{
resp.setStatus(HttpStatus.SC_UNAUTHORIZED);
//往响应体中获取消息,getWriter()这是一个流
resp.getWriter().print("无效的令牌");
return false;
}
try {
jwtUtil.verifierToken(token);
}catch (TokenExpiredException e){
//redisTemplate.hasKey(token)==true说明服务器令牌过期,redis里面没有过期
if(redisTemplate.hasKey(token))
{
//进行令牌刷新
redisTemplate.delete(token);
int userId=jwtUtil.getUserId(token);
token=jwtUtil.createToken(userId);
redisTemplate.opsForValue().set(token,userId+"",cacheExpire, TimeUnit.DAYS);
localToken.setToken(token);
}
//服务端令牌过期,客户端没有
else {
resp.setStatus(HttpStatus.SC_UNAUTHORIZED);
//往响应体中获取消息,getWriter()这是一个流
resp.getWriter().print("令牌已过期");
return false;
}
}catch (Exception e){
resp.setStatus(HttpStatus.SC_UNAUTHORIZED);
//往响应体中获取消息,getWriter()这是一个流
resp.getWriter().print("无效的令牌");
return false;
}
//间接让shiro执行realm类
boolean bool=executeLogin(request,response);
return bool;
}
@Override
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
HttpServletRequest req= (HttpServletRequest) request;
HttpServletResponse resp= (HttpServletResponse) response;
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
//这两个响应是后端项目允许跨域请求
resp.setHeader("Access-Control-Allow-Credentials","true");
resp.setHeader("Access-Control-Allow-Origin",req.getHeader("Origin"));
resp.setStatus(HttpStatus.SC_UNAUTHORIZED);
//往响应体中获取消息,getWriter()这是一个流
try {
resp.getWriter().print(e.getMessage());
}catch (Exception exception){
//exception.printStackTrace();
}
return false;
}
@Override
public void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
super.doFilterInternal(request, response, chain);
}
//从请求头获得token,或者请求体中获得令牌
private String getRequestToken(HttpServletRequest request)
{
String token=request.getHeader("token");
if(StrUtil.isBlank(token))
{
token=request.getParameter("token");
}
return token;
}
}
shiro领域类OAuth2Realm
@Component
//认证和授权框架
public class OAuth2Realm extends AuthorizingRealm {
@Resource
private JwtUtil jwtUtil;
@Resource
private UserService userService;
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof OAuth2Token;
}
/**
* 授权
* @param collection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection collection) {
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
/**
* TODO 查询用户列表的权限列表
*
* TODO 把权限列表添加到info对象中
*/
TbUser user= (TbUser) collection.getPrimaryPrincipal();
int userId=user.getId();
Set<String> permissions=userService.searchUserPermissions(userId);
info.setStringPermissions(permissions);
return info;
}
/**
* 认证
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//从令牌中回去userid,然后检测该账户是否被冻结
String accessToken = (String) token.getPrincipal();
int userId=jwtUtil.getUserId(accessToken);
TbUser user=userService.searchById(userId);
if(user==null)
{
throw new LockedAccountException("账号已被锁定,请联系管理员");
}
SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(user,accessToken,this.getName());
//往info对象中添加用户信息,token字符串
return info;
}
}
OAuth2Token
//把令牌封装成认证对象
public class OAuth2Token implements AuthenticationToken {
private String token;
public OAuth2Token(String token) {
this.token = token;
}
@Override
public Object getPrincipal() {
return token;
}
@Override
public Object getCredentials() {
return token;
}
}
shiro配置类ShiroConfig
//创建四个对象返回给springboot
@Configuration
public class ShiroConfig {
@Bean("securityManager")
//用于封装realm对象
public SecurityManager securityManager(OAuth2Realm realm){
DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
securityManager.setRealm(realm);
securityManager.setRememberMeManager(null);
return securityManager;
}
@Bean("shiroFilterFactoryBean")
//用于封装filter对象
//设置filter拦截路径
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager,OAuth2Filter filter)
{
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String, Filter> map=new HashMap<>();
map.put("oauth2",filter);
shiroFilterFactoryBean.setFilters(map);
//写入什么路劲下需要拦截
Map<String,String> filterMap=new LinkedHashMap<>();
filterMap.put("/webjars/**","anon");
filterMap.put("/druid/**","anon");
filterMap.put("/app/**","anon");
filterMap.put("/sys/login","anon");
filterMap.put("/swagger/**","anon");
filterMap.put("/v2/api-docs","anon");
filterMap.put("/swagger-ui.html","anon");
filterMap.put("/swagger-resources/**","anon");
filterMap.put("/captcha/**","anon");
filterMap.put("/user/register","anon");
filterMap.put("/user/login","anon");
//filterMap.put("/test/**","anon");
filterMap.put("/**","oauth2");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
//管理shiro对象的生命周期
@Bean("lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
return new LifecycleBeanPostProcessor();
}
//aop切面类
//web方法执行前,验证权限
@Bean("authorizationAttributeSourceAdvisor")
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager)
{
AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
}
ThreadLocalToken
@Component
//创建存储令牌的媒介类
public class ThreadLocalToken {
private ThreadLocal<String> local=new ThreadLocal();
public void setToken(String token)
{
local.set(token);
}
public String getToken()
{
return local.get();
}
public void clear()
{
local.remove();
}
}
跨域包xss下的类
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String value= super.getParameter(name);
if(!StrUtil.hasEmpty(value))
{
value=HtmlUtil.filter(value);
}
return value;
}
@Override
public String[] getParameterValues(String name) {
String[]values= super.getParameterValues(name);
if(values!=null)
{
for(int i=0;i<values.length;i++){
String value=values[i];
if(!StrUtil.hasEmpty(value))
{
value=HtmlUtil.filter(value);
}
values[i]=value;
}
}
return values;
}
@Override
public Map<String, String[]> getParameterMap() {
Map<String,String[]> map= super.getParameterMap();
LinkedHashMap<String,String[]> linkedHashMap=new LinkedHashMap<>();
if(map!=null)
{
for(String key:map.keySet())
{
String []values=map.get(key);
for(int i=0;i<values.length;i++){
String value=values[i];
if(!StrUtil.hasEmpty(value))
{
value=HtmlUtil.filter(value);
}
values[i]=value;
}
linkedHashMap.put(key,values);
}
}
return linkedHashMap;
}
@Override
public String getHeader(String name) {
String value= super.getHeader(name);
if(!StrUtil.hasEmpty(value))
{
value=HtmlUtil.filter(value);
}
return value;
}
@Override
public ServletInputStream getInputStream() throws IOException {
//从请求读取数据的io流
InputStream in= super.getInputStream();
//创建字符流
InputStreamReader reader=new InputStreamReader(in, Charset.forName("UTF-8"));
//为了高效性,配置缓冲流
BufferedReader buffer=new BufferedReader(reader);
StringBuffer body=new StringBuffer();
String line=buffer.readLine();
while(line!=null)
{
body.append(line);
line=buffer.readLine();
}
buffer.close();
reader.close();
in.close();
//把读取出来的内容请求进行格式转换
//因为Java中不支持原生json的读取,所以要转换为我要返回的字符格式
//这里把原生json转化了一下
Map<String,Object> map=JSONUtil.parseObj(body.toString());
Map<String,Object> result=new LinkedHashMap<>();
for(String key:map.keySet())
{
Object val=map.get(key);
if(val instanceof String)
{
//判断是不是字符串格式,如果是,将你强制转化
if(!StrUtil.hasEmpty(val.toString()))
{
result.put(key,HtmlUtil.filter(val.toString()));
}
}
else {
result.put(key,val);
}
}
//把我转化的json在转化为流
//json格式的字符串
String json=JSONUtil.toJsonStr(result);
ByteArrayInputStream bain=new ByteArrayInputStream(json.getBytes());
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return bain.read();
}
};
}
}
把之前写的跨域转义和过滤的内容配置在filter中XssFilter
@WebFilter(urlPatterns = "/*")
public class XssFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//这个的意思就是把所有的请求的都转义过滤一遍
HttpServletRequest request= (HttpServletRequest) servletRequest;
XssHttpServletRequestWrapper wrapper=new XssHttpServletRequestWrapper(request);
filterChain.doFilter(wrapper,servletResponse);
}
@Override
public void destroy() {
}
}
config包
全局异常处理ExceptionAdvice
@Slf4j
//拦截异常并统一处理
@RestControllerAdvice
public class ExceptionAdvice {
@ResponseBody
//返回错误状态码
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
//捕获异常
@ExceptionHandler(Exception.class)
public String validExceptionHandle(Exception e)
{
log.error("执行异常",e);
//后端异常校验
if(e instanceof MethodArgumentNotValidException)
{
MethodArgumentNotValidException exception= (MethodArgumentNotValidException) e;
//获取具体错误消息
return exception.getBindingResult().getFieldError().getDefaultMessage();
}
else if(e instanceof EmosException)
{
EmosException exception= (EmosException) e;
return exception.getMsg();
}
else if(e instanceof UnauthenticatedException)
{
return "你不具备相关权限";
}
else {
return "后端执行异常";
}
}
}
mq配置类
@Configuration
public class RabbitMQConfig {
@Bean
public ConnectionFactory getFactory(){
ConnectionFactory factory=new ConnectionFactory();
factory.setHost("192.168.11.1");
factory.setPort(5672);
factory.setPassword("admin");
factory.setUsername("admin");
return factory;
}
}
swagger2配置类
@Configuration
@EnableSwagger2
//登录时会需要在请求头中添加请求条件
public class SwaggerConfig {
//swagger的各种东西都是要封装到docket里面,所以我们创建一个docket,用来返回给springboot
@Bean
public Docket creatRestApi(){
//docket类型
Docket docket=new Docket(DocumentationType.SWAGGER_2);
//这是设置信息
/**
*ApiInfoBuilder定义swagger页面的基本信息
*/
ApiInfoBuilder builder=new ApiInfoBuilder();
builder.title("Emos 在线办公系统");
//这是把设置好的信息存到swagger页面中
ApiInfo apiInfo=builder.build();
//设置好标题
docket.apiInfo(apiInfo);
//把是需要的页面或者包下的东西传给swagger
/**
* ApiSelectorBuilder 那些类会出现在swagger页面中
*/
ApiSelectorBuilder selectorBuilder=docket.select();
//让所以路径都扫描进来
selectorBuilder.paths(PathSelectors.any());
//在已有的路劲下过滤条件,只要添加了ApiOperation这个注解,都会添加到swagger页面上
selectorBuilder.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class));
//把docket实现更新
docket = selectorBuilder.build();
/**
* 开启对jwt的支持,都是要添加更新到docket里面
* List<ApiKey> :用户需要输入什么参数
* AuthorizationScope【】:jwt认证在swagger中的作用域
* List<SecurityReference> :令牌的作用域
* List<SecurityContext>:令牌上下文
*/
//使swagger支持jwt
//使swagger知道你是在请求头中提交了令牌参数
ApiKey apiKey=new ApiKey("token","token","header");
List<ApiKey> apiKeyList=new ArrayList<>();
apiKeyList.add(apiKey);
docket.securitySchemes(apiKeyList);
//设置令牌作用域,配置jwt
AuthorizationScope scope=new AuthorizationScope("global","accessEverything");
AuthorizationScope []scopes={scope};
SecurityReference reference=new SecurityReference("token",scopes);
List reflist=new ArrayList();
reflist.add(reference);
SecurityContext context=SecurityContext.builder().securityReferences(reflist).build();
List ctxlist=new ArrayList();
ctxlist.add(context);
docket.securityContexts(ctxlist);
return docket;
}
}
现在到了微信小程序中获取openid的方法(固定写法)
public String getOpenId(String code){
String url="https://api.weixin.qq.com/sns/jscode2session";
HashMap map=new HashMap();
map.put("appid",appId);
map.put("secret",appSecret);
map.put("js_code",code);
map.put("grant_type","authorization_code");
String response = HttpUtil.post(url, map);
JSONObject jsonObject=JSONUtil.parseObj(response);
String openId=jsonObject.getStr("openid");
if(openId==null||openId.length()==0)
{
throw new RuntimeException("临时登录凭证错误");
}
return openId;
}