「小程序JAVA實戰」小程序的springboot後臺攔截器(61)

之前咱們把用戶登錄,註冊成功的信息都放到redis裏面了,如果產品經理有一種場景,就是同一個用戶在同一個時間以最後一個登錄爲準,那麼前一個就需要重新登錄,並且清空前一個用戶緩存。這就用到了springboot的緩存機制。源碼:https://github.com/limingios/wxProgram.git 中No.15和springboot

攔截器的創建

通過前端傳遞過來的userToken,和從redis裏面獲取到的userToken對比,如果不一致,前端傳遞過來的這個session獎盃提示用戶被擠出,直接緩存失效。需要重新登錄。

package com.idig8.controller.interceptor;import java.io.IOException;import java.io.OutputStream;import java.io.UnsupportedEncodingException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import com.idig8.utils.JSONResult;import com.idig8.utils.JsonUtils;import com.idig8.utils.RedisOperator;public class MiniInterceptor implements HandlerInterceptor {    @Autowired
    public RedisOperator redis;    public static final String USER_REDIS_SESSION = "user-redis-session";    
    /**
     * 攔截請求,在controller調用之前
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
            Object arg2) throws Exception {
        String userId = request.getHeader("headerUserId");
        String userToken = request.getHeader("headerUserToken");        
        if (StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(userToken)) {
            String uniqueToken = redis.get(USER_REDIS_SESSION + ":" + userId);            if (StringUtils.isEmpty(uniqueToken) && StringUtils.isBlank(uniqueToken)) {
                System.out.println("請登錄...");
                returnErrorResponse(response, new JSONResult().errorTokenMsg("請登錄..."));                return false;
            } else {                if (!uniqueToken.equals(userToken)) {
                    System.out.println("賬號被擠出...");
                    returnErrorResponse(response, new JSONResult().errorTokenMsg("賬號被擠出..."));                    return false;
                }
            }
        } else {
            System.out.println("請登錄...");
            returnErrorResponse(response, new JSONResult().errorTokenMsg("請登錄..."));            return false;
        }        
        
        /**
         * 返回 false:請求被攔截,返回
         * 返回 true :請求OK,可以繼續執行,放行
         */
        return true;
    }    
    public void returnErrorResponse(HttpServletResponse response, JSONResult result) 
            throws IOException, UnsupportedEncodingException {
        OutputStream out=null;        try{
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/json");
            out = response.getOutputStream();
            out.write(JsonUtils.objectToJson(result).getBytes("utf-8"));
            out.flush();
        } finally{            if(out!=null){
                out.close();
            }
        }
    }    
    /**
     * 請求controller之後,渲染視圖之前
     */
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
            throws Exception {
    }    
    /**
     * 請求controller之後,視圖渲染之後
     */
    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
    }

}

每一個攔截器有需要實現HandlerInterceptor接口,這個接口有三個方法,每個方法會在請求調用的不同時期完成,因爲我們需要在接口調用之前攔截請求判斷是否登陸,所以這裏需要使用preHandle方法,在裏面是驗證邏輯,最後返回true或者false,確定請求是否合法。

1240

攔截器加入配置中

原來咱們在spring mvc的時候都是通過xml配置文件的方法,springboot爲了簡化,都是通過java來進行配置,剛創建的攔截器需要配置在webconfig裏面

package com.idig8;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import com.idig8.controller.interceptor.MiniInterceptor;@Configurationpublic class WebMvcConfig extends WebMvcConfigurerAdapter {    
    @Value("${server.file.path}")    private String fileSpace;    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {        //資源的路徑.swagger2的資源.所在的目錄,
        registry.addResourceHandler("/**")
        .addResourceLocations("classpath:/META-INF/resources/")
        .addResourceLocations("file:"+fileSpace);
        
    }    
    @Bean
    public MiniInterceptor miniInterceptor() {        return new MiniInterceptor();
    }    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        
        registry.addInterceptor(miniInterceptor()).addPathPatterns("/user/**")
                       .addPathPatterns("/video/upload", "/video/uploadCover")
                                                  .addPathPatterns("/bgm/**");        
        super.addInterceptors(registry);
    }

}

1240

小程序針對返回的502問題添加判斷

在通過userId獲取用戶的信息時,在header中添加用戶的userId,userToken,針對登錄後返回502進行提示並清空用戶信息緩存。

// pages/mine/mine.jsconst app = getApp()var videoUtils = require('../../utils/videoUtils.js')
Page({  /**
   * 頁面的初始數據
   */
  data: {    faceImage: "../../resource/images/noneface.png",    nickname: "暱稱",    fansCounts: 0,    followCounts: 0,    receiveLikeCounts: 0,
  },  /**
   * 用戶註銷
   */
  logout: function(e) {    var user = app.getGlobalUserInfo();
    wx.showLoading({      title: '正在註銷中。。。'
    });
    wx.request({      url: app.serverUrl + "/logout?userId=" + user.id,      method: "POST",      header: {        'content-type': 'application/json' // 默認值
      },      success: function(res) {        console.log(res.data);        var status = res.data.status;
        wx.hideLoading();        if (status == 200) {
          wx.showToast({            title: "用戶註銷成功~!",            icon: 'none',            duration: 3000
          })          // app.userInfo = null;
          wx.removeStorageSync("userInfo");
          wx.redirectTo({            url: '../userRegister/userRegister',
          })

        } else if (status == 500) {
          wx.showToast({            title: res.data.msg,            icon: 'none',            duration: 3000
          })
        }
      }
    })
  },  /**
   * 頭像上傳
   */
  uploadFace: function(e) {    // var user = app.userInfo;
    var user = app.getGlobalUserInfo();    var me = this;
    wx.chooseImage({      count: 1, // 默認9
      sizeType: ['compressed'], // 可以指定是原圖還是壓縮圖,默認二者都有
      sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機,默認二者都有
      success: function(res) {        // 返回選定照片的本地文件路徑列表,tempFilePath可以作爲img標籤的src屬性顯示圖片
        var tempFilePaths = res.tempFilePaths        if (tempFilePaths.length > 0) {          console.log(tempFilePaths[0]);
          wx.uploadFile({            url: app.serverUrl + "/user/uploadFace?userId=" + user.id, //僅爲示例,非真實的接口地址
            filePath: tempFilePaths[0],            name: 'file',            success: function(res) {              var data = JSON.parse(res.data);              console.log(data);
              wx.hideLoading();              if (data.status == 200) {
                wx.showToast({                  title: "用戶上傳成功~!",                  icon: 'none',                  duration: 3000
                })
                me.setData({                  faceUrl: app.serverUrl + data.data
                })


              } else if (data.status == 500) {
                wx.showToast({                  title: data.msg,                  icon: 'none',                  duration: 3000
                })
              }
            }
          })
        }

      }
    })
  },  /**
   * 生命週期函數--監聽頁面加載
   */
  onLoad: function(options) {    var me = this;    var userInfo = app.getGlobalUserInfo();
    wx.showLoading({      title: '正在獲取用戶信息。。。'
    });
    wx.request({      url: app.serverUrl + "/user/queryByUserId?userId=" + userInfo.id,      method: "POST",      header: {        'content-type': 'application/json', // 默認值
        'headerUserId': userInfo.id,        'headerUserToken': userInfo.userToken
      },      success: function(res) {        console.log(res.data);        var status = res.data.status;        if (status == 200) {          var userInfo = res.data.data;
          wx.hideLoading();          var faceImage = me.data.faceUrl;          if (userInfo.faceImage != null && userInfo.faceImage != '' && userInfo.faceImage != undefined) {
            faceImage = app.serverUrl + userInfo.faceImage;
          }
          me.setData({            faceImage: faceImage,            fansCounts: userInfo.fansCounts,            followCounts: userInfo.followCounts,            receiveLikeCounts: userInfo.receiveLikeCounts,            nickname: userInfo.nickname
          })
        } else if (status == 502){
          wx.showToast({            title: res.data.msg,            duration:3000,            icon:'none',            complete:function(){
              wx.removeStorageSync("userInfo");

              wx.navigateTo({                url: '../userLogin/userLogin',
              })
            }
          })
          
        }
      }
    })
  },  uploadVideo: function(e) {
    videoUtils.uploadVideo();
  },  /**
   * 生命週期函數--監聽頁面初次渲染完成
   */
  onReady: function() {

  },  /**
   * 生命週期函數--監聽頁面顯示
   */
  onShow: function() {

  },  /**
   * 生命週期函數--監聽頁面隱藏
   */
  onHide: function() {

  },  /**
   * 生命週期函數--監聽頁面卸載
   */
  onUnload: function() {

  },  /**
   * 頁面相關事件處理函數--監聽用戶下拉動作
   */
  onPullDownRefresh: function() {

  },  /**
   * 頁面上拉觸底事件的處理函數
   */
  onReachBottom: function() {

  },  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function() {

  }
})

1240

PS:通過攔截器的方式很好的保護後臺的程序正常的運行。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章