web-dev-qa-db-ja.com

JSONクエリパラメータをJAX-RSを使用してオブジェクトに変換する

次のようなJSON文字列としてパラメーターを取得するJAX-RSリソースがあります。

http://some.test/aresource?query={"paramA":"value1", "paramB":"value2"}

ここでJSONを使用する理由は、実際の使用例ではクエリオブジェクトが非常に複雑になる可能性があるためです。

JSON文字列をJavaオブジェクト、例ではdtoに変換します:

@GET 
@Produces("text/plain")
public String getIt(@QueryParam("query") DataTransferObject dto ) {
    ...
}

JAX-RSは、クエリパラメータとしてJavaオブジェクトに渡されるJSONからのこのような変換をサポートしていますか?

27
deamon

はい、できますが、変換コードを自分で作成する必要があります。幸い、これは簡単です。変換を行うには、パブリックStringコンストラクターを持つクラスを作成するだけです。例えば:

public class JSONParam {
    private DataTransferObject dto;

    public JSONParam(String json) throws WebApplicationException {
        try {
            // convert json string DataTransferObject and set dto
        }
        catch (JSONException e) {
            throw new WebApplicationException(Response.status(Status.BAD_REQUEST)
                    .entity("Couldn't parse JSON string: " + e.getMessage())
                    .build());
        }
    }

    public DataTransferObject getDTO() {
        return dto;
    }
}

それからあなたは使うことができます:

@GET 
@Produces("text/plain")
public String getIt(@QueryParam("query") JSONParam json) {
    DataTransferObject dto = json.getDTO();
    ...
}
15
Jason Day

前述のように、StringパラメーターからJSONに明示的に変換する必要があります。しかし、org.jsonのパーサーのようにプリミティブなものを使用する必要はありません。 Jackson または Gson は、1行または2行でデータバインディング(文字列からJSON、JSONからPOJO)を実行できます。ジャクソンと:

MyValue value = new ObjectMapper().readValue(json, MyValue.class);

(本番用コードの場合、静的メンバーとしてObjectMapperを1回作成するだけで、再利用できます)

Jacksonは、ほとんどのJAX-RS実装がPOSTデータのデータバインディングを実装するために使用するものであるため、これはよく似ています。

11
StaxMan

http://www.json.org/Java/ を使用してJasonのソリューションに追加します(Crockford提供):

import org.json.JSONObject;

public class JSONParam {
    private DataTransferObject dto;

    public JSONParam(String json) throws WebApplicationException {
        try {
            // convert json string DataTransferObject and set dto
            JSONObject jo = new JSONObject(json);
            dto.setParamA(jo.getString("paramA"));
            dto.setParamB(jo.getString("paramB"));
            // There are other get methods for Integer, Double, etc. 
            // You can also build JSON from Java objects.
        }
        catch (JSONException e) {
            throw new WebApplicationException(Response.status(Status.BAD_REQUEST)
                    .entity("Couldn't parse JSON string: " + e.getMessage())
                    .build());
        }
    }

     public DataTransferObject getDTO() {
        return dto;
    }                  
}

車輪を再発明しないでください:-)

8
Mike K

JAX-RSは、JAXB(XMLバインディング用Java API)を使用して、JavaBeanをXMLまたはJSONにバインドしたり、その逆をサポートしたりします。詳細はここにあります。例: http://www.ibm.com/developerworks/web/library/wa-aj-Tomcat/index.html

必要がある

  • DataTransferObjectに@XmlRootElementアノテーションを追加します
  • DataTransferObjectで空のデフォルトコンストラクターを作成します。
  • @Consumes(MediaType.APPLICATION_JSON)アノテーションをWebServiceに追加します
4
lili
0
Yaroslav

DTOの生成に関心がある場合は、 jsonschema2pojo を提案できますか? JSON Schema を使用してオブジェクトを定義し、DTOを自動的に生成できます。

スキーマを作成したら、それをコンシューマーに渡して、コンシューマーがリクエストのフォーマット方法を正確に理解できるようにすることもできます。

0
joelittlejohn