微信公众号网页授权代码优化过程(四)

上篇博客已经完成了功能并且很好地运行。但是我们感觉代码还有改进的空间,就再着手改进。之前已经说过,改进的代码使用SpringMVC的拦截器Interceptor或是Servlet的过滤器Filter,此处我们使用前者,原因有二:

  • 过滤器需要在web.xml中配置,多一段配置或多一段代码都增大了出现问题的可能,有句话说的好——“不写代码就不会有bug。”
  • 项目框架中我们已经使用了SpringMVC,为了完成功能我们只是多使用了它本身提供的功能而已,反正功能就在那儿,不使用白不使用。

了解并使用拦截器

如果你看过SpringMVC的源码入口类org.springframework.web.servlet.DispatcherServlet,会发现程序在执行到Controller类之前会被拦截器处理,拦截器可以决定是进行下一步处理或是返回false从而中断此次请求。要写一个拦截器,可以实现HandlerInterceptor接口,或者继承HandlerInterceptorAdapter抽象类,差别是实现接口必须重写它的所有方法,而继承抽象类则只用重写需要的方法,功能上是一样的,依个人喜好使用,我倾向于使用HandlerInterceptorAdapter。HandlerInterceptor接口有三个方法:

  • boolean preHandle() 在请求Controller之前执行
  • void postHandle() 在请求Controller之后执行,但是在DispatcherServlet渲染页面视图之前执行
  • void afterCompletion() DispatcherServlet渲染页面视图之的执行

我们需要的只有一个方法:preHandle()。假定我的们拦截器名叫WxOAuth2Interceptor,它继承了HandlerInterceptorAdapter抽象类,并重写了preHandle()方法,该方法主要处理的问题是判断session中是否有openid,有就放行,没有的话就先判断request中有无code参数,有的话,就去获取openid并保存到session再放行,没有的话就去做微信授权认证。之后在页面代码中如GoodsController.list()中只需从session中取出openid使用即可,无须判断openid是否为空。

有一点需要着重说明的是,微信授权认证时的redirect_uri已经替换为当前请求路径了。之前的版本是跳转到WxRedirectController#callback()中。

配置

当编写好了代码之后需要在SpringMVC的配置文件中做配置的,该文件是SpringMVC的配置文件,并不是Spring的配置文件,也就是在web.xml中配置org.springframework.web.servlet.DispatcherServlet的contextConfigLocation参数,本例中的是springMVC-servlet.xml。配置是很简单的,如下:

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <mvc:exclude-mapping path="/wxmpBind/**"/>
            <bean class="com.billy.weixinoauthcodeoptimization.WxOAuth2Interceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

mvc:mapping表示的是该拦截器要拦截哪些路径,不想拦截的路径就用mvc:exclude-mapping来排除掉就好了,我们不能拦截微信绑定服务器的这个请求,所以就排除了。

版本三的代码地址如下:版本三的代码

猜你喜欢

转载自my.oschina.net/valuetodays/blog/1629919