私はRESTful Webサービスの初心者であり、スタンドアロンクライアントアプリケーションから@OneToMany
関係を更新しようとしましたが、それはできません。 Glassfish 3.1.1に同梱されているJAX-RSのJersey実装を使用しています。
クラスA
との@OneToMany
関係を持つクラスB
があります。
MyRestClient
は、Glassfish 3.1.1にデプロイされたRESTful Webサービスを呼び出しているスタンドアロンクライアントです。
MyRestClient.Java
public class MyRestClient {
public static void main(String[] args) {
Client client = Client.create();
WebResource resource = client.resource("http://localhost:8080/myapp/rest/a/update/123");
B b1 = new B("debris");
ClientResponse response = resource.put(ClientResponse.class, b1);
System.out.println(response.getEntity(A.class).getTitle() + " has " + response.getEntity(A.class).getBList().size() + " Bs.");
}
}
AResource
は、RESTful Webサービスとして使用しているEJBセッションBeanです。
AResource.Java
@Stateless
@Path("/a")
public class AResource {
@EJB
private AManager aManager;
@PUT
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
@Path("/update/{id}")
public Response updateA(B b, @PathParam("id") int id) {
A a = aManager.findAById(id);
a.addB(b);
return Response.status(Status.OK).entity(a).build();
}
}
クライアントを実行すると、次のエラーメッセージが表示されます。com.Sun.jersey.api.client.ClientHandlerException:Javaタイプのメッセージボディライター、クラスmyPackage。 B、およびMIMEメディアタイプapplication/octet-streamが見つかりませんでした。
以下は、RESTful Webサービスとして使用しているAResource
EJBセッションBeanを呼び出しているスタンドアロンクライアントアプリケーションのドメインオブジェクトです。
A.Java
@XmlRootElement
public class A implements Serializable{
private List<B> bList = new ArrayList<B>();
public List<B> getBList() {
return bList;
}
//remaining code
}
B.Java
public class B implements Serializable {
private String text;
private A a;
@XmlTransient
public A getA() {
return a;
}
public void afterUnmarshal(Unmarshaller u, Object parent) {
this.a = (A) parent;
}
//remaining code
}
誰かがこれがなぜ起こっているのか、この問題をどのように解決すべきかを理解するのを手伝ってくれますか?
クライアントコードでは、送信するデータのコンテンツタイプを指定していません。そのため、Jerseyはb1オブジェクトをシリアル化するための適切なMessageBodyWritterを見つけることができません。
Mainメソッドの最後の行を次のように変更します。
ClientResponse response = resource.type(MediaType.APPLICATION_XML).put(ClientResponse.class, b1);
そして、サーバー側とクライアント側の両方のクラスBに@XmlRootElementアノテーションを追加します。
この依存関係をPOM.xmlに含めて、Maven-> Updateを実行します
<dependency>
<groupId>com.Sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.owlike</groupId>
<artifactId>genson</artifactId>
<version>0.99</version>
</dependency>
B.classの_@Provider
_ that @Produces(MediaType.APPLICATION_XML)
を指定する必要があります
An _MessageBodyWriter<B.class>
_のパッケージを_/WEB_INF/web.xml
_に追加します:
_<init-param>
<param-name>com.Sun.jersey.config.property.packages</param-name>
<param-value>
your.providers.package
</param-value>
</init-param>
_
参照の追加:
<dependency>
<groupId>com.Sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>${jersey1.version}</version>
</dependency>
クライアントの作成時にclientConfig.getFeatures()。put(JSONConfiguration.FEATURE_POJO_MAPPING、true);を追加する限り、問題は解決しました。
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, true);
Client client = Client.create(clientConfig);
このエラーを削除するには、2つのことを行う必要があります。
@xmlElement
_マッピングクライアント側:
response = resource.type(MediaType.APPLICATION_XML).put(ClientResponse.class, b1); //consume
または
response = resource.accept(MediaType.APPLICATION_XML).put(ClientResponse.class, b1); //produce
getメソッドで同じ問題に直面していました@getメソッドの「int」を返していましたそれ
これらすべてのライブラリがクラスパスにあることを確認してください。
compile(group: 'com.Sun.jersey', name: 'jersey-core', version: '1.19.4')
compile(group: 'com.Sun.jersey', name: 'jersey-server', version: '1.19.4')
compile(group: 'com.Sun.jersey', name: 'jersey-servlet', version: '1.19.4')
compile(group: 'com.Sun.jersey', name: 'jersey-json', version: '1.19.4')
compile(group: 'com.Sun.jersey', name: 'jersey-client', version: '1.19.4')
compile(group: 'javax.ws.rs', name: 'jsr311-api', version: '1.1.1')
compile(group: 'org.codehaus.jackson', name: 'jackson-core-asl', version: '1.9.2')
compile(group: 'org.codehaus.jackson', name: 'jackson-mapper-asl', version: '1.9.2')
compile(group: 'org.codehaus.jackson', name: 'jackson-core-asl', version: '1.9.2')
compile(group: 'org.codehaus.jackson', name: 'jackson-jaxrs', version: '1.9.2')
compile(group: 'org.codehaus.jackson', name: 'jackson-xc', version: '1.9.2')
「Pojo Mapping」と「Jackson Provider」をジャージクライアント設定に追加します。
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
clientConfig.getClasses().add(JacksonJsonProvider.class);
これは私に解決します!
ClientResponse response = null;
response = webResource
.type(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.get(ClientResponse.class);
if (response.getStatus() == Response.Status.OK.getStatusCode()) {
MyClass myclass = response.getEntity(MyClass.class);
System.out.println(myclass);
}
これは、エンティティの空のパブリックコンストラクターがない場合にも発生します(JSON、XMLなどの場合があります)。
これは、最近Antをアップグレードした場合にも発生する可能性があります。私はプロジェクトでAnt 1.8.4を使用していましたが、Antを1.9.4にアップグレードし、Antを使用してファットjarをビルドするとこのエラーが発生し始めました。
私にとっての解決策は、コマンドラインとEclipseのためにAnt 1.8.4にダウングレードすることでした ここで詳述するプロセスを使用して
これで問題が解決しました。
POM.xmlに以下の依存関係を含めてMaven-> Updateを実行すると、この問題も修正されました。
<dependency>
<groupId>com.Sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.19.1</version>
</dependency>
<dependency>
<groupId>com.owlike</groupId>
<artifactId>genson</artifactId>
<version>0.99</version>
</dependency>