使ってます REST-Jersey
プロジェクト内。すべてのPOSTデータはJSON
形式で送信され、サーバーサイドでそれぞれのBeanに非整列化されます。次のようなもの:
サーバーにリクエストを送信:
$('a#sayHelloPost').click(function(event){
event.preventDefault();
var mangaData = {
title:'Bleach',
author:'Kubo Tite'
}
var formData=JSON.stringify(mangaData);
console.log(formData);
$.ajax({
url:'rest/cred/sayposthello',
type: 'POST',
data: formData,
dataType: 'json',
contentType:'application/json'
})
});
ペイロード:
{"title":"Bleach","author":"Kubo Tite"}
サーバーエンド:
@POST
@Path("/sayposthello")
@Produces(MediaType.APPLICATION_JSON)
public Response sayPostHello(MangaBean mb){
System.out.println(mb);
return Response.status(200).build();
}
MangaBean:
public class MangaBean {
private String title;
private String author;
@Override
public String toString() {
return "MangaBean [title=" + title + ", author=" + author + "]";
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
コンソールでの出力:
MangaBean [title=Bleach, author=Kubo Tite]
here からRESTインターセプター実装を取得しました。
public class JerseyFilter implements ContainerRequestFilter{
@Override
public ContainerRequest filter(ContainerRequest req) {
return req;
}
}
インターセプターのペイロード(リクエストボディ)にアクセスしたい。データはJSON形式であるため、リクエストパラメータとしてアクセスできません。 インターセプターメソッドでリクエストボディを取得する方法はありますか?アドバイスをお願いします。
これは、Jerseyがロギングフィルターを実装する方法と非常によく似た、実装可能な1つの方法です。エンティティを読み取ってリクエストに貼り付けることができるため、誤ってエンティティをフィルターで使用することはありません。
import com.Sun.jersey.api.container.ContainerException;
import com.Sun.jersey.core.util.ReaderWriter;
import com.Sun.jersey.spi.container.ContainerRequest;
import com.Sun.jersey.spi.container.ContainerRequestFilter;
import Java.io.ByteArrayInputStream;
import Java.io.ByteArrayOutputStream;
import Java.io.IOException;
import Java.io.InputStream;
public class JerseyFilter implements ContainerRequestFilter {
@Override
public ContainerRequest filter(ContainerRequest request) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
InputStream in = request.getEntityInputStream();
final StringBuilder b = new StringBuilder();
try {
if (in.available() > 0) {
ReaderWriter.writeTo(in, out);
byte[] requestEntity = out.toByteArray();
printEntity(b, requestEntity);
request.setEntityInputStream(new ByteArrayInputStream(requestEntity));
}
return request;
} catch (IOException ex) {
throw new ContainerException(ex);
}
}
private void printEntity(StringBuilder b, byte[] entity) throws IOException {
if (entity.length == 0)
return;
b.append(new String(entity)).append("\n");
System.out.println("#### Intercepted Entity ####");
System.out.println(b.toString());
}
}
リクエスト入力ストリームからPOST Bodyを取得できます。次のようなものを試してください:
@Override
public ContainerRequest filter(ContainerRequest req) {
try{
StringWriter writer = new StringWriter();
IOUtils.copy(req.getEntityInputStream(), writer, "UTF-8");
//This is your POST Body as String
String body = writer.toString();
}
catch (IOException e) {}
return req; }
コンテンツは入力ストリームであるため、一度しか読み取ることができません。インターセプターで取得した場合、メインの構文解析でそれを提供することはできません。
あなたがする必要があるのは、データを読み取り、それを必要とする他の誰もが利用できるようにするフィルターを作成することです。基本的な手順は次のとおりです。
in.available()
メソッドを使用して、Inputstreamの合計バイト数を確認しないでください。一部のクライアントはこの値を設定しません。この場合、メッセージ本文の入力ストリームが存在していても不正です。
InputStream in = request.getEntityInputStream();
final StringBuilder b = new StringBuilder();
try {
if (in.available() > 0)
以下のコードを使用
String json = IOUtils.toString(requestContext.getEntityStream(), Charsets.UTF_8);
messageBody = json;
InputStream in = IOUtils.toInputStream(json);
requestContext.setEntityStream(in);