【问题标题】:Jersey - Modify Query Parameter inside a ResourceJersey - 修改资源内的查询参数
【发布时间】:2016-05-11 02:00:55
【问题描述】:

我在 ResourceA 中调用 ResourceB。

两者都使用相同的查询参数“param1”。

如何在调用 ResourceB 之前更改 ResourceA 中“param1”的值。

代码如下:

package com.example;

import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import com.sun.jersey.api.core.ResourceContext;

public abstract class MyResource {
    ResponseBuilder response;
    Request request;
    protected String param1;

    public MyResource(@QueryParam("param1") String param1, @Context Request request) {
        this.param1 = param1;
        this.request = request;
        this.response = Response.ok();
    }
}

public class ResourceA extends MyResource {
    public ResourceA(String param1, Request request) {
        super(param1, request);
    }
    @Context private ResourceContext rc;
    public Response postJSON(String postData) {
        JSONObject data = JSONObject.fromObject(postData);
        if (data.has("resourceB")) {
            ResourceB resourceB = rc.getResource(ResourceB.class);
            // resourceB.setQueryParams("param1", "my new param 1");
            resourceB.postJSON(data.getJSONArray("resourceB"));
        }
    }
}

public class ResourceB extends MyResource {
    public ResourceB(String param1, Request request) {
        super(param1, request);
    }

    public Response postJSON(JSONArray data) {
        // this.params1 should not be "my new param 1"
    }
}

【问题讨论】:

  • 我不确定你想在这里做什么。什么不适用于您的代码? ResourceB 中 param1 的预期值是多少?你可以简单地设置resourceB.param1 = ...,我错过了什么吗?
  • 是的,这就是我现在正在做的事情。问题是如果 ResourceB 调用 ResourceC,我需要再次传递 param1。如果我能够更改请求的查询参数的值,我只需要在 ResourceA 中执行一次。
  • 你可以改变 ResourceA 的构造函数,所以当它被实例化时,值会在一个地方被修改
  • 不应为 ResourceA 的每个路径修改它,并且在构造函数中新值是未知的。

标签: java json web-services rest jersey


【解决方案1】:

如何使用ResourceContext.initResource(T resource),使用修改后的值初始化资源,并通过声明 JAX-RS 注释字段来控制 DI 提供程序注入的内容?
如果我正确理解您的问题,您想在找到匹配的资源方法后修改请求上下文或挂钩注入并更改一些值。我不确定这是否可能。

但是,正如我所建议的,如果可以进行一些设计修改,您可以以编程方式初始化资源并利用仅注入字段:

public Response postJSON(String postData) {
    JSONObject data = JSONObject.fromObject(postData);
    if (data.has("resourceB")) {
        ResourceB resourceB = new ResourceB(/* pass here the modified query param */ "my new param 1");
        // let the DI provider inject the JAX-RS annotated fields only
        resourceB = rc.initResource(resourceB);
        // resourceB.setQueryParams("param1", "my new param 1");
        resourceB.postJSON(data.getJSONArray("resourceB"));
    }
}

ResourceB 类本身(及其超类)将声明您希望注入的注释字段,而@QueryParam("param1")(可能还有其他 JAX-RS 感知字段)将是在构造函数中声明,这样它就不会被覆盖。

public abstract class MyResource {
    ResponseBuilder response;

    // this gets injected in the ResourceContext.initResource() method
    @Context
    Request request;

    // additional JAX-RS annotated fields you would like to have injected such as
    @PathParam("id")
    private String pathParamId;

    protected String param1;

    // constructor JAX-RS annotated parameters would not get re-initialized  
    public MyResource(@QueryParam("param1") String param1) {
        this.param1 = param1;
        this.request = request;
        this.response = Response.ok();
    }
}

【讨论】:

  • 感谢您的回答。它似乎不是由 Jersey 开箱即用提供的......
猜你喜欢
  • 1970-01-01
  • 2012-05-30
  • 2014-04-01
  • 2016-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-05
  • 2017-10-27
相关资源
最近更新 更多