草庐IT

android - 无法从 Android 上的 Jersey clientresponse 读取 cookie

coder 2023-12-23 原文

我有一个 Web 应用程序,它执行身份验证,然后检查请求中的 cookie 以允许来自同一客户端的后续调用。我写了一段代码,当我从 eclipse 运行它时它工作得很好,但是当从 android 模拟器运行时它失败了。这是我做的

为 URI 创建 Web 资源并将过滤器绑定(bind)到它以将 cookie 附加到请求的类

public class TolvenRestClient {
        private static Client client;
        private static final ThreadLocal<String> instance = new ThreadLocal<String>();

    static {
        ClientConfig config = new DefaultClientConfig();
        client = Client.create(config);
        client.setFollowRedirects(true);
    }

    private Client getClient() {
        return client;
    }

    public WebResource getResource(String path){
        WebResource webResource = getClient().resource(path);
        webResource.addFilter(new ClientFilter() {
            @Override
            public ClientResponse handle(ClientRequest clientRequest) throws ClientHandlerException {
                if (instance.get() != null) {
                    clientRequest.getHeaders().putSingle("Cookie", "SSOCookie=" + instance.get());
                }
                ClientResponse clientResponse = getNext().handle(clientRequest);
                String cookieName = "SSOCookie";
                System.out.println("cookies "+clientResponse.getCookies());
                for (NewCookie newCookie : clientResponse.getCookies()) {
                    if (cookieName.equals(newCookie.getName())) {
                        String extendedSessionId = newCookie.getValue();                            
                        instance.set(extendedSessionId);
                        break;
                    }
                }
                return clientResponse;
            }
        }); 
        return webResource;
    }

然后是触发网络服务调用的示例代码

RestClient client = new RestClient();

    MultivaluedMap<String, String> formData = new MultivaluedMapImpl();
    formData.add("username", "demo");
    formData.add("password", "1234qwer");
    formData.add("realm", "tolven");
    WebResource webResource = client.getResource("https://dev.example.com:8443/gatekeeper/rs/authenticate/login");
    ClientResponse response = webResource.type(MediaType.APPLICATION_FORM_URLENCODED).post(ClientResponse.class,formData);
    //ClientResponse response = webResource.accept("text/html").get(ClientResponse.class);
    System.out.println("Here ....." + response.toString());     
    webResource = client.getResource("https://dev.example.com:8443/api/vestibule/accountList");
    response = webResource.get(ClientResponse.class);
    Accounts accounts = response.getEntity(Accounts.class);

这段代码在从 eclipse 运行时工作得很好。但是当在 android 模拟器中运行时,它无法从客户端响应中读取 cookie

我得到以下异常

09-20 19:55:31.067: W/System.err(1172): java.lang.NullPointerException
09-20 19:55:31.077: W/System.err(1172):     at javax.ws.rs.core.NewCookie.valueOf(NewCookie.java:126)
09-20 19:55:31.077: W/System.err(1172):     at com.sun.jersey.api.client.ClientResponse.getCookies(ClientResponse.java:714)
09-20 19:55:31.077: W/System.err(1172):     at com.userexample.LoginActivityTolven$1$1.handle(LoginActivityTolven.java:71)
09-20 19:55:31.088: W/System.err(1172):     at com.sun.jersey.api.client.WebResource.handle(WebResource.java:680)
09-20 19:55:31.088: W/System.err(1172):     at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
09-20 19:55:31.097: W/System.err(1172):     at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:568)
09-20 19:55:31.097: W/System.err(1172):     at com.userexample.LoginActivityTolven$1.onClick(LoginActivityTolven.java:86)
09-20 19:55:31.097: W/System.err(1172):     at android.view.View.performClick(View.java:4240)
09-20 19:55:31.097: W/System.err(1172):     at android.view.View$PerformClick.run(View.java:17721)
09-20 19:55:31.107: W/System.err(1172):     at android.os.Handler.handleCallback(Handler.java:730)
09-20 19:55:31.107: W/System.err(1172):     at android.os.Handler.dispatchMessage(Handler.java:92)
09-20 19:55:31.107: W/System.err(1172):     at android.os.Looper.loop(Looper.java:137)
09-20 19:55:31.107: W/System.err(1172):     at android.app.ActivityThread.main(ActivityThread.java:5103)
09-20 19:55:31.107: W/System.err(1172):     at java.lang.reflect.Method.invokeNative(Native Method)
09-20 19:55:31.117: W/System.err(1172):     at java.lang.reflect.Method.invoke(Method.java:525)
09-20 19:55:31.117: W/System.err(1172):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
09-20 19:55:31.117: W/System.err(1172):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
09-20 19:55:31.117: W/System.err(1172):     at dalvik.system.NativeStart.main(Native Method)

有没有人以前尝试过在 android 上使用 Jersey 客户端并遇到过这个问题?

最佳答案

看起来您正在使用 Jersey 1.x,并且 JAX-RS 运行时委托(delegate)在 NewCookie 中为 null。

如果找不到 Jersey META-INF/services 文件,就会发生这种情况。 如果 Android 重新打包过程没有重新打包 META-INF/services 文件,则可能是问题的根源,请务必检查一下。

一种方法是通过提供您自己的 ServiceIteratorProvider 来覆盖服务定位算法。 .

参见:

作为引用这里是示例代码:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import com.sun.jersey.spi.service.ServiceFinder.ServiceIteratorProvider;

public class YourOwnServiceIteratorProvider<T> extends ServiceIteratorProvider<T>
{
    private static final HashMap<String, String[]> SERVICES = new HashMap<String, String[]>();

    private static final String[] com_sun_jersey_spi_HeaderDelegateProvider = new String[] {
            "com.sun.jersey.core.impl.provider.header.LocaleProvider",
            "com.sun.jersey.core.impl.provider.header.EntityTagProvider",
            "com.sun.jersey.core.impl.provider.header.MediaTypeProvider",
            "com.sun.jersey.core.impl.provider.header.CacheControlProvider",
            "com.sun.jersey.core.impl.provider.header.NewCookieProvider",
            "com.sun.jersey.core.impl.provider.header.CookieProvider",
            "com.sun.jersey.core.impl.provider.header.URIProvider",
            "com.sun.jersey.core.impl.provider.header.DateProvider",
            "com.sun.jersey.core.impl.provider.header.StringProvider"

    };
    private static final String[] com_sun_jersey_spi_inject_InjectableProvider = new String[] {
            "com.sun.jersey.core.impl.provider.xml.SAXParserContextProvider",
            "com.sun.jersey.core.impl.provider.xml.XMLStreamReaderContextProvider",
            "com.sun.jersey.core.impl.provider.xml.DocumentBuilderFactoryProvider",
            "com.sun.jersey.core.impl.provider.xml.TransformerFactoryProvider"
    };
    private static final String[] javax_ws_rs_ext_MessageBodyReader = new String[] {
            "com.sun.jersey.core.impl.provider.entity.StringProvider",
            "com.sun.jersey.core.impl.provider.entity.ByteArrayProvider",
            "com.sun.jersey.core.impl.provider.entity.FileProvider",
            "com.sun.jersey.core.impl.provider.entity.InputStreamProvider",
            "com.sun.jersey.core.impl.provider.entity.DataSourceProvider",
            "com.sun.jersey.core.impl.provider.entity.RenderedImageProvider",
            "com.sun.jersey.core.impl.provider.entity.MimeMultipartProvider",
            "com.sun.jersey.core.impl.provider.entity.FormProvider",
            "com.sun.jersey.core.impl.provider.entity.FormMultivaluedMapProvider",
            "com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$App",
            "com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$Text",
            "com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General",
            "com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$App",
            "com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$Text",
            "com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General",
            "com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$App",
            "com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$Text",
            "com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General",
            "com.sun.jersey.core.impl.provider.entity.ReaderProvider",
            "com.sun.jersey.core.impl.provider.entity.DocumentProvider",
            "com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader",
            "com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader",
            "com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader",
            "com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$App",
            "com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$Text",
            "com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General",
            "com.sun.jersey.core.impl.provider.entity.EntityHolderReader"
    };
    private static final String[] javax_ws_rs_ext_MessageBodyWriter = new String[] {
            "com.sun.jersey.core.impl.provider.entity.StringProvider",
            "com.sun.jersey.core.impl.provider.entity.ByteArrayProvider",
            "com.sun.jersey.core.impl.provider.entity.FileProvider",
            "com.sun.jersey.core.impl.provider.entity.InputStreamProvider",
            "com.sun.jersey.core.impl.provider.entity.DataSourceProvider",
            "com.sun.jersey.core.impl.provider.entity.RenderedImageProvider",
            "com.sun.jersey.core.impl.provider.entity.MimeMultipartProvider",
            "com.sun.jersey.core.impl.provider.entity.FormProvider",
            "com.sun.jersey.core.impl.provider.entity.FormMultivaluedMapProvider",
            "com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$App",
            "com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$Text",
            "com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General",
            "com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$App",
            "com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$Text",
            "com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General",
            "com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$App",
            "com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$Text",
            "com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General",
            "com.sun.jersey.core.impl.provider.entity.ReaderProvider",
            "com.sun.jersey.core.impl.provider.entity.DocumentProvider",
            "com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider",
            "com.sun.jersey.core.impl.provider.entity.SourceProvider$SourceWriter"
    };

    static
    {
        SERVICES.put("com.sun.jersey.spi.HeaderDelegateProvider",
            com_sun_jersey_spi_HeaderDelegateProvider);
        SERVICES.put("com.sun.jersey.spi.inject.InjectableProvider",
            com_sun_jersey_spi_inject_InjectableProvider);
        SERVICES.put("javax.ws.rs.ext.MessageBodyReader", javax_ws_rs_ext_MessageBodyReader);
        SERVICES.put("javax.ws.rs.ext.MessageBodyWriter", javax_ws_rs_ext_MessageBodyWriter);
    }

    @SuppressWarnings("unchecked")
    @Override
    public Iterator<Class<T>> createClassIterator(Class<T> service, String serviceName,
        ClassLoader loader, boolean ignoreOnClassNotFound)
    {
        String[] classesNames = SERVICES.get(serviceName);
        int length = classesNames.length;
        ArrayList<Class<T>> classes = new ArrayList<Class<T>>(length);
        for (int i = 0; i < length; i++)
        {
            try
            {
                classes.add((Class<T>) Class.forName(classesNames[i]));
            } catch (ClassNotFoundException e)
            {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public Iterator<T> createIterator(Class<T> service, String serviceName, ClassLoader loader,
        boolean ignoreOnClassNotFound)
    {
        String[] classesNames = SERVICES.get(serviceName);
        int length = classesNames.length;
        ArrayList<T> classes = new ArrayList<T>(length);
        for (int i = 0; i < length; i++)
        {
            try
            {
                classes.add(service.cast(Class.forName(classesNames[i]).newInstance()));
            } catch (IllegalAccessException e)
            {
                e.printStackTrace();
            } catch (InstantiationException e)
            {
                e.printStackTrace();
            } catch (ClassNotFoundException e)
            {
                e.printStackTrace();
            }
        }
        return classes.iterator();
    }
}

可以这样使用:

// ...
Client client = Client.create();
// ...
ServiceFinder.setIteratorProvider(new YourOwnServiceIteratorProvider());
// ...

HTH

关于android - 无法从 Android 上的 Jersey clientresponse 读取 cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18927510/

有关android - 无法从 Android 上的 Jersey clientresponse 读取 cookie的更多相关文章

  1. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

  4. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  5. ruby-on-rails - 无法在centos上安装therubyracer(V8和GCC出错) - 2

    我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e

  6. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  7. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  8. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  9. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  10. ruby - 无法覆盖 irb 中的 to_s - 2

    我在pry中定义了一个函数:to_s,但我无法调用它。这个方法去哪里了,怎么调用?pry(main)>defto_spry(main)*'hello'pry(main)*endpry(main)>to_s=>"main"我的ruby版本是2.1.2看了一些答案和搜索后,我认为我得到了正确的答案:这个方法用在什么地方?在irb或pry中定义方法时,会转到Object.instance_methods[1]pry(main)>defto_s[1]pry(main)*'hello'[1]pry(main)*end=>:to_s[2]pry(main)>defhello[2]pry(main)

随机推荐