GVKun编程网logo

android – 如何在Interceptor中访问上下文?(android如何访问system)

6

如果您对android–如何在Interceptor中访问上下文?和android如何访问system感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解android–如何在Interceptor

如果您对android – 如何在Interceptor中访问上下文?android如何访问system感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解android – 如何在Interceptor中访问上下文?的各种细节,并对android如何访问system进行深入的分析,此外还有关于(转)spring中的拦截器(HandlerInterceptor+MethodInterceptor)、android – PopupWindow TouchInterceptor无法正常工作、android – 在运行时使用Dagger添加Retrofit Requestinterceptor、android – 如何从视图中获取上下文?的实用技巧。

本文目录一览:

android – 如何在Interceptor中访问上下文?(android如何访问system)

android – 如何在Interceptor中访问上下文?(android如何访问system)

我想在拦截器上保存SharedPreferences上的一些东西.
我找不到办法,因为我找不到一种方法来访问Interceptor上的上下文(所以不可能使用PreferencesManager等).
public class CookieInterceptor implements Interceptor {

@Override public Response intercept(Chain chain) throws IOException {

    PreferenceManager.getDefaultSharedPreferences(Context ??)

}}

有任何想法吗 ?

我正在使用AndroidStudio&最新版本的OkHttp.

谢谢

总结

以上是小编为你收集整理的android – 如何在Interceptor中访问上下文?全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

(转)spring中的拦截器(HandlerInterceptor+MethodInterceptor)

(转)spring中的拦截器(HandlerInterceptor+MethodInterceptor)

1.  过滤器跟拦截器的区别

在说拦截器之前,不得不说一下过滤器,有时候往往被这两个词搞的头大。

其实我们最先接触的就是过滤器,还记得web.xml中配置的<filter>吗~

你应该知道spring mvc的拦截器是只拦截controller而不拦截jsp,html 页面文件的,如果想要拦截那怎么办?

这就用到过滤器filter了,filter是在servlet前执行的,你也可以理解成过滤器中包含拦截器,一个请求过来 ,先进行过滤器处理,看程序是否受理该请求 。 过滤器放过后 , 程序中的拦截器进行处理 。

(1)过滤器(Filter):当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。(理解:就是一堆字母中取一个B)

(2)拦截器(Interceptor):在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情。(理解:就是一堆字母中,干预他,通过验证的少点,顺便干点别的东西)。

2.  spring中的拦截器

在web开发中,拦截器是经常用到的功能。它可以帮我们验证是否登陆、预先设置数据以及统计方法的执行效率等等。

今天就来详细的谈一下spring中的拦截器。spring中拦截器主要分两种,一个是HandlerInterceptor,一个是MethodInterceptor。

2.1  HandlerInterceptor拦截器

HandlerInterceptor是springMVC项目中的拦截器,它拦截的目标是请求的地址,比MethodInterceptor先执行。

实现一个HandlerInterceptor拦截器可以直接实现HandlerInterceptor接口,也可以继承HandlerInterceptorAdapter类。

这两种方法殊途同归,其实HandlerInterceptorAdapter也就是声明了HandlerInterceptor接口中所有方法的默认实现,而我们在继承他之后只需要重写必要的方法。

下面就是HandlerInterceptorAdapter的代码,可以看到一个方法只是默认返回true,另外两个是空方法:

public abstract class HandlerInterceptorAdapter implements HandlerInterceptor {  
  
    /** 
     * This implementation always returns <code>true</code>. 
     */  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)  
        throws Exception {  
        return true;  
    }  
  
    /** 
     * This implementation is empty. 
     */  
    public void postHandle(  
            HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)  
            throws Exception {  
    }  
  
    /** 
     * This implementation is empty. 
     */  
    public void afterCompletion(  
            HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)  
            throws Exception {  
    }  
  
}  

这三个方法都是干什么的,有什么作用,什么时候调用,不同的拦截器之间是怎样的调用顺序呢?

先补一张图:

这还得参考一下DispatcherServlet的doDispatch方法:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {  
        HttpServletRequest processedRequest = request;  
        HandlerExecutionChain mappedHandler = null;  
        int interceptorIndex = -1;  
  
        try {  
            ModelAndView mv;  
            boolean errorView = false;  
  
            try {  
                processedRequest = checkMultipart(request);  
  
                // Determine handler for the current request.  
                mappedHandler = getHandler(processedRequest, false);  
                if (mappedHandler == null || mappedHandler.getHandler() == null) {  
                    noHandlerFound(processedRequest, response);  
                    return;  
                }  
  
                // Determine handler adapter for the current request.  
                HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());  
  
                // Process last-modified header, if supported by the handler.  
                String method = request.getMethod();  
                boolean isGet = "GET".equals(method);  
                if (isGet || "HEAD".equals(method)) {  
                    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());  
                    if (logger.isDebugEnabled()) {  
                        String requestUri = urlPathHelper.getRequestUri(request);  
                        logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);  
                    }  
                    if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {  
                        return;  
                    }  
                }  
  
                // Apply preHandle methods of registered interceptors.  
                HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();  
                if (interceptors != null) {  
                    for (int i = 0; i < interceptors.length; i++) {  
                        HandlerInterceptor interceptor = interceptors[i];  
                        if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {  
                            triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);  
                            return;  
                        }  
                        interceptorIndex = i;  
                    }  
                }  
  
                // Actually invoke the handler.  
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  
  
                // Do we need view name translation?  
                if (mv != null && !mv.hasView()) {  
                    mv.setViewName(getDefaultViewName(request));  
                }  
  
                // Apply postHandle methods of registered interceptors.  
                if (interceptors != null) {  
                    for (int i = interceptors.length - 1; i >= 0; i--) {  
                        HandlerInterceptor interceptor = interceptors[i];  
                        interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);  
                    }  
                }  
            }  
            catch (ModelAndViewDefiningException ex) {  
                logger.debug("ModelAndViewDefiningException encountered", ex);  
                mv = ex.getModelAndView();  
            }  
            catch (Exception ex) {  
                Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);  
                mv = processHandlerException(processedRequest, response, handler, ex);  
                errorView = (mv != null);  
            }  
  
            // Did the handler return a view to render?  
            if (mv != null && !mv.wasCleared()) {  
                render(mv, processedRequest, response);  
                if (errorView) {  
                    WebUtils.clearErrorRequestAttributes(request);  
                }  
            }  
            else {  
                if (logger.isDebugEnabled()) {  
                    logger.debug("Null ModelAndView returned to DispatcherServlet with name ''" + getServletName() +  
                            "'': assuming HandlerAdapter completed request handling");  
                }  
            }  
  
            // Trigger after-completion for successful outcome.  
            triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);  
        }  
  
        catch (Exception ex) {  
            // Trigger after-completion for thrown exception.  
            triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);  
            throw ex;  
        }  
        catch (Error err) {  
            ServletException ex = new NestedServletException("Handler processing failed", err);  
            // Trigger after-completion for thrown exception.  
            triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);  
            throw ex;  
        }  
  
        finally {  
            // Clean up any resources used by a multipart request.  
            if (processedRequest != request) {  
                cleanupMultipart(processedRequest);  
            }  
        }  
    }  
View Code

代码有点长,但是它封装了springMVC处理请求的整个过程。首先根据请求找到对应的HandlerExecutionChain,它包含了处理请求的handler和所有的HandlerInterceptor拦截器;然后在调用hander之前分别调用每个HandlerInterceptor拦截器的preHandle方法,若有一个拦截器返回false,则会调用triggerAfterCompletion方法,并且立即返回不再往下执行;若所有的拦截器全部返回true并且没有出现异常,则调用handler返回ModelAndView对象;再然后分别调用每个拦截器的postHandle方法;最后,即使是之前的步骤抛出了异常,也会执行triggerAfterCompletion方法。关于拦截器的处理到此为止,接下来看看triggerAfterCompletion做了什么:

private void triggerAfterCompletion(HandlerExecutionChain mappedHandler,  
            int interceptorIndex,  
            HttpServletRequest request,  
            HttpServletResponse response,  
            Exception ex) throws Exception {  
  
        // Apply afterCompletion methods of registered interceptors.  
        if (mappedHandler != null) {  
            HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();  
            if (interceptors != null) {  
                for (int i = interceptorIndex; i >= 0; i--) {  
                    HandlerInterceptor interceptor = interceptors[i];  
                    try {  
                        interceptor.afterCompletion(request, response, mappedHandler.getHandler(), ex);  
                    }  
                    catch (Throwable ex2) {  
                        logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);  
                    }  
                }  
            }  
        }  
    }  
View Code

 triggerAfterCompletion做的事情就是从当前的拦截器开始逆向调用每个拦截器的afterCompletion方法,并且捕获它的异常,也就是说每个拦截器的afterCompletion方法都会调用。

根据以上的代码,分析一下不同拦截器及其方法的执行顺序。假设有5个拦截器编号分别为12345,若一切正常则方法的执行顺序是12345的preHandle,54321的postHandle,54321的afterCompletion。若编号3的拦截器的preHandle方法返回false或者抛出了异常,接下来会执行的是21的afterCompletion方法。这里要注意的地方是,我们在写一个拦截器的时候要谨慎的处理preHandle中的异常,因为这里一旦有异常抛出就不会再受到这个拦截器的控制。12345的preHandle的方法执行过之后,若handler出现了异常或者某个拦截器的postHandle方法出现了异常,则接下来都会执行54321的afterCompletion方法,因为只要12345的preHandle方法执行完,当前拦截器的拦截器就会记录成编号5的拦截器,而afterCompletion总是从当前的拦截器逆向的向前执行。

2.2  MethodInterceptor拦截器

MethodInterceptor是AOP项目中的拦截器,它拦截的目标是方法,即使不是controller中的方法。实现MethodInterceptor拦截器大致也分为两种,一种是实现MethodInterceptor接口,另一种利用AspectJ的注解或配置。
下面是第一种方法的示例
public class MethodInvokeInterceptor implements MethodInterceptor {  
    @Override  
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {  
        System.out.println("before method invoke");  
        Object object = methodInvocation.proceed();  
        System.out.println("after method invoke");  
        return object;  
    }  
}  

下面是基于注解的AspectJ方式

@Component  
@Aspect  
public class AutoAspectJInterceptor {  
  
    @Around("execution (* com.test.controller..*.*(..))")  
    public Object around(ProceedingJoinPoint point) throws Throwable{  
        System.out.println("AutoAspectJInterceptor begin around");  
        Object object = point.proceed();  
        System.out.println("AutoAspectJInterceptor end around");  
        return object;  
    }  
     
}  

下面是一个用于支持AspectJ方式拦截的普通的bean,当然你也可以在配置文件中声明这个bean

@Component  
 public class AspectJInterceptor {  
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {  
        System.out.println("AspectJInterceptor around before");  
        Object object = proceedingJoinPoint.proceed();  
        System.out.println("AspectJInterceptor around after");  
        return object;  
    }  
}  

当然,这一切都离不开配置,具体看配置中的注释

<!-- 自定义拦截器 ,先过mvc:interceptors-->  
    <bean id="methodInvokeInterceptor" class="com.test.interceptor.MethodInvokeInterceptor"/>  
    <bean id="aspectInterceptor" class="com.test.interceptor.AspectJInterceptor"/>  
  
    <aop:config>  
        <!--切入点,controlller -->  
        <aop:pointcut id="pointcut_test"   expression="execution(* com.test.controller..*.*(..))" />  
        <!--在该切入点使用自定义拦截器 ,按照先后顺序执行 -->  
        <aop:advisor pointcut-ref="pointcut_test" advice-ref="methodInvokeInterceptor" />  
  
  
        <aop:aspect ref="aspectInterceptor">  
            <aop:around method="around" pointcut="execution(* com.test.controller..*.*(..))"/>  
        </aop:aspect>  
    </aop:config>  
    <!-- 自动扫描使用了aspectj注解的类 -->  
    <aop:aspectj-autoproxy/>

通过上面的配置三个MethodInterceptor就能正常工作了。其实,这两种实现方最终...没错,还是殊途同归。

aspectj的拦截器会被解析成AOP中的advice,最终被适配成MethodInterceptor,详细的过程请参考springAOP的实现。

3.  实例选择拦截器

项目中采用Interceptor来过滤URL来决定哪些可以在不登录的情况下访问,哪些必须要登录才可以访问;

3.1  HandlerInterceptor方式

public class SessionTimeoutInterceptor implements HandlerInterceptor {
     .........
}

此时需要在servlet.xml中配置<mvc:interceptor>

 

3.2  MethodInterceptor注解Aspect方式

@Component
@Aspect
public void class BindingResultAop{
    ........
}

同时在servlet.xml中配置
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

经测试发现,interceptor先于AOP执行。

4.  谈一谈区别

上面的两种拦截器都能起到拦截的效果,但是他们拦截的目标不一样,实现的机制不同,所以有的时候适用不同的场景。

HandlerInterceptoer拦截的是请求地址,所以针对请求地址做一些验证、预处理等操作比较合适。当你需要统计请求的响应时间时MethodInterceptor将不太容易做到,因为它可能跨越很多方法或者只涉及到已经定义好的方法中一部分代码。MethodInterceptor利用的是AOP的实现机制,在本文中只说明了使用方式,关于原理和机制方面介绍的比较少,因为要说清楚这些需要讲出AOP的相当一部分内容。在对一些普通的方法上的拦截HandlerInterceptoer就无能为力了,这时候只能利用AOP的MethodInterceptor。


另外,还有一个跟拦截器类似的东西----Filter。Filter是Servlet规范规定的,不属于spring框架,也是用于请求的拦截。但是它适合更粗粒度的拦截,在请求前后做一些编解码处理、日志记录等。而拦截器则可以提供更细粒度的,更加灵活的,针对某些请求、某些方法的组合的解决方案。


另外的另外,用过人人网的ROSE框架的人都会非常喜欢它的拦截器功能。因为它实现了全注解的方式,只要在类的名字上加上拦截器的注解即表示这是一个拦截器。而使用这个拦截器的方法或者controller也只需在方法或controller的上面加上这个拦截器的注解。其实这是一个关注点的转变,spring的切面控制在配置文件中,配置文件关注哪些地方需要拦截。而在ROSE中,则是在需要拦截的地方关注我要被谁拦截。

android – PopupWindow TouchInterceptor无法正常工作

我正在尝试测试PopupWindow类.我创建了这个方法来显示弹出窗口:

public void showPopup(){
            LayoutInflater layoutInflater   = (LayoutInflater)getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);  
            View popupView = layoutInflater.inflate(R.layout.popup,null);
            final PopupWindow popup = new PopupWindow(popupView,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);  
            popup.setoutsidetouchable(true);
            popup.setTouchable(true);
            popup.setTouchInterceptor(new OnTouchListener() {
                @Override
                public boolean onTouch(View v,MotionEvent event) {
                    Log.d("POPUP",event.toString());
                    if(event.getAction() == MotionEvent.ACTION_OUTSIDE){
                        popup.dismiss();
                        return true;
                    }
                    return true;
                }
            });
            popup.showAtLocation(findViewById(R.id.main),Gravity.BottOM|Gravity.CENTER_HORIZONTAL,200);
}

弹出窗口正确显示,看起来Touch Interceptor似乎根本不起作用:我没有得到任何日志信息,当然如果按下它以外弹出窗口也不会消失.

我是否需要在弹出窗口或托管它的Activity中设置一些其他属性?

解决方法

pw.setBackgroundDrawable (new BitmapDrawable());
 pw.setFocusable(false);
 pw.setoutsidetouchable(true);

使用此代码希望这是有帮助的

android – 在运行时使用Dagger添加Retrofit Requestinterceptor

android – 在运行时使用Dagger添加Retrofit Requestinterceptor

我正在使用匕首和改装.我用Dagger注入了我的Retrofit服务.

现在我想做一个授权请求来获取accesstoken.

之后我想使用Request拦截器来增强我的api模块,以便将来使用此访问令牌.

我的想法是在收到访问令牌后使用ObjectGraph.plus()方法,但我不确定这是否是最好的方法.

有人能指出我正确的方向,或者github上有一个示例项目吗?

解决方法

关键是始终添加RequestInterceptor,然后更改它是否添加标头.

class ApiHeaders implements RequestInterceptor {
  private String authValue;

  public void clearauthValue() {
    authValue = null;
  }

  public void setAuthValue(String authValue) {
    this.authValue = authValue;
  }

  @Override public void intercept(RequestFacade request) {
    String authValue = this.authValue;
    if (authValue != null) {
      request.addHeader("Authorization",authValue);
    }
  }
}

这样,您可以在需要设置或清除令牌时注入ApiHeaders单例.

android – 如何从视图中获取上下文?

android – 如何从视图中获取上下文?

我已经实现了一个WebViewClient来覆盖onReceivedError()事件.这是我的代码:

@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
    InternetConnectivityChecker internetConnectivityChecker = new InternetConnectivityChecker(view.getContext().getApplicationContext());

    onReceivedErrorListener.onReceivedError();
    if (internetConnectivityChecker.isConnected() == false) {

    }
}

而且,这是我的InternetConnectivityChecker类:

package com.sama7.sama;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

public class InternetConnectivityChecker {
    private Context context;

    public InternetConnectivityChecker(Context context) {
        context = context;
    }

    public boolean isConnected() {
        NetworkInfo info = ((ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();

        if (info == null || !info.isConnected()) {
            return false;
        }

        return true;
    }

}

运行此代码时,我遇到异常,说:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
                                                                at com.sama7.sama.InternetConnectivityChecker.isConnected(InternetConnectivityChecker.java:15)

为什么我的上下文是一个空对象?而且,我该如何解决这个问题呢?

解决方法:

更换:

context = context;

有:

this.context = context;

这样您就可以设置字段的值.就目前而言,您正在为自己设置方法参数.

我们今天的关于android – 如何在Interceptor中访问上下文?android如何访问system的分享已经告一段落,感谢您的关注,如果您想了解更多关于(转)spring中的拦截器(HandlerInterceptor+MethodInterceptor)、android – PopupWindow TouchInterceptor无法正常工作、android – 在运行时使用Dagger添加Retrofit Requestinterceptor、android – 如何从视图中获取上下文?的相关信息,请在本站查询。

本文标签: