9

次のような汎用 ServiceResponse クラスがあります。

@XMLRootElement
public class ServiceResponse<T>
{
    private T data;
    private String error;
    //setters n getters

}

私の RESTEasy サービスから、xml 応答を次のように生成したいと考えています。

List<Customer> customers = someDAO.getCustomers();
ServiceResponse<List<Customer>> resp = new ServiceResponse<List<Customer>>();
resp.setData(customers);
resp.setError("No Error");
return resp;
or return Response.ok().entity(resp).build();

しかし、java.util.List の JaxbMarshallWriter がないため、これはエラーをスローしています。

GenericEntity クラスを使用して List をマーシャリングできます。

GenericEntity<List<Customer>> entity = new GenericEntity<List<Customer>>(customers){};
Response.ok(entity).build();

しかしGenericEntity<ServiceResponse<List<Customer>>>、java.util.List の JaxbMarshallWriter がないと言って動作しません。

ジェネリック テンプレート (、) を使用してクラスをマーシャリング/アンマーシャリングするための回避策はありますか?

4

4 に答える 4

1

クラスが一般的なテンプレートを使用することで違いが生じるかどうかはわかりませんが、RESTEasy を使用して XML 応答を生成する方法は次のとおりです。

これは、サービス応答を保持するクラスです

public class ServiceResponse<T>
{
    private T data;
    private String error;
    //setters n getters
}

これは、実際に応答を XML に変換するクラスです。このクラスは、XML/JSON または使用しているものを取り込んで生成する以外には、ほとんど何もしません。次に、実際の作業を行うクラスにリクエストを渡します。ただし、これはあなたの特定の質問に答えるクラスです(私は信じています)。

@Path("/myrestservice")
public class SomeRestService
{
    private SomeCoreService coreService;
    //getters and setters here

    @POST
    @Path("/examples/")
    @Consumes({MediaType.APPLICATION_XML}) //this consumes XML
    @Produces({MediaType.APPLICATION_XML}) //this produces XML
    public ServiceResponse<T> exampleFunction(Request request)
    {
        try
        {
            //Unwrap the request and take only what you need out
            //of the request object here
            return this.coreService.examples(request.getStringFromRequest());
        }
        catch(Exception ex)
        {
            return new ServiceResponse<T>(Put response error message here);
        }
    }
}

これは、実際のすべての作業を行うクラスです。

public class SomeCoreService
{
    public ServiceResponse<T> examples(String stringFromRequest)
    {
        //do whatever work you need to do here.
        return new ServiceResponse<T>(put whatever you need in the service response here)
    }
}

また、私はこれをテストしていません。うまくいけば、パターンを取得するだけで十分です。

于 2013-03-08T17:34:34.133 に答える
0

問題は一般的なものではありません。問題は、リストをオブジェクト内にラップする必要があることです。

ServiceResponse<ResponseData<Customer>> resp = new ServiceResponse<ResponseData<Customer>>();

次に、ResponseDataクラスに注釈を付けて、オブジェクトのセットを表すことができます。

于 2012-12-02T11:03:23.140 に答える
0

返信がかなり遅れていることはわかっていますが、賛成票の回答がないため、回答が役立つことを願っています。

問題は、T に @XMLRootElement または @XMLType のアノテーションが付けられている場合を除いて、MyClass jaxB というジェネリック クラスがある場合です。

あなたのコード シナリオでは、タイプ T は List です。List には @XMLRootElement または @XMLType がないため、エラーがスローされます。上記のケースの解決策は、 Collection のようなラッパークラスを作成することだと思います

@XMLRootElement
Class JaxBCollection<T>{
    java.util.Collection<T> collection;
    /* Have getters and setters*/
}

今あなたのコードにこのようなものがあります。

List<Customer> customers = someDAO.getCustomers();
JaxBCollection<Customer> jaxBCustomers= new JaxBCollection<Customer>();
jaxBCustomers.setCollection(customers);
ServiceResponse<JaxBCollection<Customer>> resp = new ServiceResponse<JaxBCollection<Customer>>();
resp.setData(jaxBCustomers);
resp.setError("No Error");
return resp;
于 2013-04-20T13:19:44.407 に答える
0

同じ問題に対して私が行った解決策は、ジェネリック型リストをシミュレートする新しい型を作成することでした。リストタイプの代わりに使用するエンティティ(人)のリストで、非常にうまく機能します...

ここに私の例があります。

package com.dosideals.server.beans;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.xml.bind.annotation.XmlRootElement;

/**
 *
 * @author LOTFI
 */
@Entity
@XmlRootElement
public class Admin implements Serializable {

    @Id
    private String login;
    private String password;
    private String firstName;
    private String lastName;

    public Admin() {
    }

    public Admin(String login, String password, String firstName, String lastName) {
        this.login = login;
        this.password = password;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Admin other = (Admin) obj;
        if ((this.login == null) ? (other.login != null) : !this.login.equals(other.login)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 83 * hash + (this.login != null ? this.login.hashCode() : 0);
        return hash;
    }

    @Override
    public String toString() {
        return "Admin{" + "login=" + login + ", password=" + password + ", firstName=" + firstName + ", lastName=" + lastName + '}';
    }
}

そして、これはコンテナ AdminContainer です:

package com.dosideals.server.beans.containers;

import com.dosideals.server.beans.Admin;
import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;

/**
 *
 * @author LOTFI
 */
@XmlRootElement
public class AdminContainer {

    private List<Admin> admin;

    public AdminContainer() {
    }

    public AdminContainer(List<Admin> admin) {
        this.admin = admin;
    }

    public List<Admin> getAdmin() {
        return admin;
    }

    public void setAdmin(List<Admin> admin) {
        this.admin = admin;
    }
}
于 2013-02-12T15:28:19.737 に答える