多人在线协同小程序开发

在这里,我想记录一些我之前学习的小程序开发和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切面类开始说起

这个博主把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;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值