3

Company と Employee という 2 つの Java オブジェクトがあります。RESTful サービスを呼び出して HTTP GET できるように、どちらにも Jersey/JAXB アノテーションが付けられています。基本的に、Company は Employee の「親」オブジェクトであり、Company に対して GET を実行する場合、JSON 応答で Employees の子リストの属性のサブセットのみを提供したいと考えています。ただし、従業員自体に対して GET を実行するときに、従業員のすべての属性を返したいと考えています。

私はこれに頭を悩ませようとしてきましたが、それを行う方法がよくわかりません。かなり基本的なようですが、オンラインで例を見つけることができませんでした(間違ったものをグーグルで検索しているのかもしれません)。

会社.java

@XmlRootElement
public class Company {
  private String companyName;
  private String companyType;
  private List<Employee> employees = new ArrayList<Employee>();

  // getters and setters with @XmlElement on each attribute 
  //...etc...
  @XmlElement
  public List<Employee> getEmployees() {
    return employees;
  }
  //...etc...
}

従業員.java

@XmlRootElement
public class Employee{
  private String employeeId;
  private String employeeName;
  private String employeeType;

  // getters and setters with @XmlElement on each attribute
  //...etc...
  @XmlElement
  public String getEmployeeId() {
    return employeeId;
  }
  //...etc...
}

これで、Company オブジェクトと Employee オブジェクトに対して HTTP GET を実行する RESTful サービスができました。

public class infoService{
  @GET
  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
  public Response getCompany(String Id) {
  //....
  }

  @GET
  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
  public Response getEmployee(String Id) {
  //....
  }
}

Employee オブジェクトを取得する場合、期待どおり、すべての属性が返されます。したがって、次のようになります。

{
  "employeeId": "1A2-B35",
  "employeeName": "John Doe",
  "employeeType": "Engineer"
}

Company オブジェクトに対して GET を実行するとき、Company オブジェクトの下の Employees のリストが、Employee に対して指定された 2 つの属性 (つまり、従業員名と従業員 ID のみ) のみを返すようにします。したがって、私の望ましい JSON 応答は次のようになります。

{
  "companyName": "Acme",
  "companyType": "Services",
  "employees": [
    {
      "employeeId": "123_ABC",
      "employeeName": "John Doe"
    },
    {
      "employeeId": "456_XYZ",
      "employeeName": "Jane Doe"
    }
  ]
}

ただし、もちろん、次のように、従業員リスト内のすべての従業員属性を返します。

{
  "companyName": "Acme",
  "companyType": "Services",
  "employees": [
    {
      "employeeId": "123_ABC",
      "employeeName": "John Doe",
      "employeeType": "Engineer"
    },
    {
      "employeeId": "456_XYZ",
      "employeeName": "Jane Doe",
      "employeeType": "Executive"
    }
  ]
}

注釈だけでこれを行うことは可能ですか? または、独自の JSON オブジェクトを作成する以外に、これを行う他の方法はありますか?

4

2 に答える 2

4

を使用して、XmlAdapterこのユースケースを解決できます。

EmployeeAdapter

XmlAdapter、完全に入力Employeeされたものを、マーシャリングするフィールドのみを使用してXMLに入力された別のインスタンスに変換します。これはコピーであるため、元のオブジェクトモデルには影響しません。

package forum11059499;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class EmployeeAdapter extends XmlAdapter<Employee, Employee>{

    @Override
    public Employee marshal(Employee employee) throws Exception {
        Employee partialEmployee = new Employee();
        partialEmployee.setEmployeeId(employee.getEmployeeId());
        partialEmployee.setEmployeeName(employee.getEmployeeName());
        return partialEmployee;
    }

    @Override
    public Employee unmarshal(Employee employee) throws Exception {
        return employee;
    }

}

会社

@XmlJavaTypeAdapter注釈は、目的のプロパティを指定するために使用されますXmlAdapter

package forum11059499;

import java.util.*;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
public class Company {
    private String companyName;
    private String companyType;
    private List<Employee> employees = new ArrayList<Employee>();

    // getters and setters with @XmlElement on each attribute
    // ...etc...
    @XmlElement
    @XmlJavaTypeAdapter(EmployeeAdapter.class)
    public List<Employee> getEmployees() {
        return employees;
    }
    // ...etc...
}

詳細については


コードに次のコメントがあることに気づきました。

//各属性に@XmlElementを使用したゲッターとセッター

JAXB(JSR-222)の実装は例外による構成であるため、デフォルトのXML表現が必要な場所にのみ注釈を追加する必要があります。これは、モデルにある注釈の一部を削除できる可能性があることを意味します。

于 2012-06-16T10:12:36.853 に答える
1

私はインターフェイスでこれを行いました。IEmployee および IEmployeeLight インターフェイスを作成します。

IEmployeeLight には基本があり、IEmployee はそれを拡張して完全なファット データを追加します。コレクションが IEmployeeLight の型を返すようにすることができます。両方のインターフェースに適切に注釈を付けます。実装のヒントがない限り、JAXB はインターフェイスにバインドできないため、おそらくサービス定義で XmlSeeAlso を使用する必要があります。

詳細が不十分な場合は申し訳ありませんが、これは複雑なトピックであり、ホワイトボードなしで正しく説明するのは困難です.

このソリューションが最適であると言っているわけではありません。

私たちのユースケースは、DTO、JPA エンティティ、バージョニングなどでより複雑でした。

于 2012-06-15T23:52:57.513 に答える