【问题标题】:JAX-RS @CookieParam Ionic client not sending cookies (Capacitor)JAX-RS @CookieParam 离子客户端不发送 cookie(电容器)
【发布时间】:2020-12-08 01:59:17
【问题描述】:

我在标头中发送一个带有注释@CookieParam 的 cookie 作为参数。

第一步:register/start

    @GET
    @Path("/start")
    @Produces(MediaType.APPLICATION_JSON)
    @NoCache
    public Response start() {
        try {
            String myIdentifier = "abcdefghijkl123456789";

            LOGGER.info(String.format("My identifier: %s ", myIdentifier)); 

            // the identifier is send through the cookies in headers
            NewCookie cookie = new NewCookie("myIdentifierCookie", myIdentifier, null, null, null,
                    1200, false, false);
            return Response.ok().cookie(cookie).build();
        }catch (Exception e) {
            return Response.status(500).build();
        }
    }

从现在开始就好了。当我执行 GET 时,我可以在响应标头上读取我的 cookie。 现在我正在做一个 POST 方法来检查收到的电子邮件,它有 @CookieParam 注释。

    @POST
    @Path("/email")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @NoCache
    public Response emailCheck(@CookieParam("myIdentifierCookie") Cookie identifierCookie,
                                  CheckEmailRequest request) {

        String identifier = "";
        try {
            identifier = identifierCookie.getValue();
        } catch (Exception e) {
            LOGGER.error("exception e ", e);
            LOGGER.error(String.format("Invalid  request identifier: %s ", identifier));
            return Response.status(500).build();
        }
    }

我的 cookie 值为空,我正在接收:

(executor-thread-62) exception e : java.lang.NullPointerException
 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:151)
        at org.jboss.resteasy.core.MethodInjectorImpl.lambda$invoke$3(MethodInjectorImpl.java:122)
        at java.base/java.util.concurrent.CompletableFuture.uniApplyNow(CompletableFuture.java:680)
        at java.base/java.util.concurrent.CompletableFuture.uniApplyStage(CompletableFuture.java:658)
        at java.base/java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:2158)
        at java.base/java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:143)
        at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:122)
        at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:594)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:468)
        at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:421)
        at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:363)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:423)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:391)
        at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invoke$1(ResourceMethodInvoker.java:365)
        at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1183)
        at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2299)
        at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:143)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:365)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:477)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:252)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:153)
        at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:363)
        at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:156)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:238)
        at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:120)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access$000(VertxRequestHandler.java:36)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:85)
        at io.quarkus.runtime.CleanableExecutor$CleaningRunnable.run(CleanableExecutor.java:224)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
        at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2011)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1535)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1426)
        at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
        at java.base/java.lang.Thread.run(Thread.java:832)
        at org.jboss.threads.JBossThread.run(JBossThread.java:479)


我的实现有错吗?
非常感谢。

编辑:@Paul Samsotha

我使用的是哪个客户端?

我正在使用Ionic with Angular,我的插件是来自@angular/common/http 的 Angular Http 模块。 我有一个这样定义的backend service

  get(url, options?): Observable<any> {
    options = { ...options, withCredentials: true };
    return this.http.get(myURL, options);
  }

  post(url, body, options?): Observable<any> {
    options = { ...options, withCredentials: true };
    return this.http.post(myURL, body, options);
  }

所以在我的组件上我是这样使用它的:

  public getRegistrationStart() {
    return this.backendService.get('/register/start', {
      observe: 'response',
    });
  }

  public emailStep(email) {
    const headers = new HttpHeaders().set('Content-Type', 'application/json');
    return this.backendService.postPublic('/register/email', email, {
      observe: 'response',
      headers,
    });
  }

我的电子邮件以 JSON 格式发送,例如 {"email":"test@test.test"}

编辑 2:@Paul

这是我的启动请求屏幕,服务器以包含我的 cookie 的 Set-Cookie 响应(我设置了一个随机数生成器),但我的 cookie 在这里。

【问题讨论】:

  • 你用的是什么客户端?您能否展示一下您是如何提出请求的。
  • 我正在使用 Angular Ionic,尤其是来自 @angular/common/http 的 Angular HTTP 客户端。我正在编辑我的帖子,向您展示我的请求。
  • 我认为你看错了。所以服务器发送cookie,客户端应该将它与请求一起发送回来。但它不会把它送回去。所以这是你必须回答的问题。尝试用谷歌搜索“ionic not sent cookie back to server”,看看是否有帮助。我已经有一段时间没有使用离子了,所以我不确定。
  • 让我重新表述一下。当客户端发送第一个请求时,服务器会随响应一起发送一个 cookie。该 cookie 用于识别客户端。客户端应该在每个请求中将该 cookie 发送回服务器,以便服务器知道谁在发出请求。 @CookieParam 是客户端发送回服务器的 cookie。它应该与服务器在第一次请求时发送给客户端的相同。但在您的情况下,客户端不会将 cookie 发回。这就是你需要解决的问题。
  • 服务器最初向客户端发送cookie时,是以Set-Cookie响应头的形式发送的。客户端回传时,以Cookie请求头的形式发送

标签: java ionic-framework cookies jax-rs angular-httpclient


【解决方案1】:

问题不是 JAX RS,而是 Ionic Capacitor 阻止了 cookie。通过在capacitor.config.json 中添加此行解决了问题:

"server":{"hostname":"mydomain"}

Cookie 没有在 Android 中被截获,它在 iOS 中被截获,所以只在 iOS 构建文件中的 capacitor.config.json 中添加这一行解决了我的问题。

非常感谢 Paul Samsotha,他向我展示了解决方案。

【讨论】:

  • 很高兴你知道了。您是否使用了我建议的搜索词?您就是这样找到解决方案的吗?
  • 是的,我在谷歌上搜索了你的确切字词,我找到了这个主题:github.com/ionic-team/capacitor/issues/1143这解决了我的问题!现在,cookies 发送到 Android 和 iOS。太棒了!
  • 太棒了。请记住,这只是一种解决方法。如果您需要调用一些第三方 API,if 将无法正常工作。您必须通过您的服务器作为第三方 API 的网关进行调用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 2014-07-11
  • 2016-02-21
相关资源
最近更新 更多