実際、Thomas(質問に追加されたコメントを参照)は質問に答えました。 @トーマス:ありがとう、それは私の前の研究で逃したものでした。
いくつかの詳細を追加できます。
非同期サービス・インターフェース上で設定する必要がRpcRequestBuilderカスタムクライアント側では、トーマスが提案したよう:
IMyServiceAsync service = GWT.create(IMyService.class);
((ServiceDefTarget)service).setRpcRequestBuilder(new MyCustomRpcRequestBuilder());
送信されようとしている要求を操作するためdoSetRequestData
をオーバーライドする必要がRpcRequestBuilderカスタムそしてdoSetCallback
、それが処理される前に、応答にその手を得るために:サーバー側で
private final class MyCustomRpcRequestBuilder extends RpcRequestBuilder {
@Override
protected void doSetRequestData(RequestBuilder rb, String payload) {
// do whatever you need to do on the payload, request header, ...
String checksum = calculateChecksum(payload);
rb.setHeader(MY_CUSTOM_HEADER_NAME, checksum);
super.doSetRequestData(rb, payload);
}
@Override
protected void doSetCallback(RequestBuilder rb, final RequestCallback callback) {
super.doSetCallback(rb, new RequestCallback() {
@Override
public void onResponseReceived(Request request, Response response) {
// do whatever you need to do on the response header, ...
String receivedChecksum = response.getHeader(MY_CUSTOM_HEADER_NAME);
if (receivedChecksum.equals(calculateChecksum(response.getText())) {
callback.onResponseReceived(request, response);
}
else {
callback.onError(request, new InvalidChecksumException(...));
}
}
@Override
public void onError(Request request, Throwable exception) {
callback.onError(request, exception);
}
});
}
}
をサーブレットフィルタを使用することができます。
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest)req;
HttpServletResponse httpResp = (HttpServletResponse)resp;
String receivedChecksum = httpReq.getHeader(MY_CUSTOM_HEADER_NAME);
String reqPayload = RPCServletUtils.readContentAsGwtRpc(httpReq);
if (receivedChecksum.equals(calculateChecksum(reqPayload)) {
final ServletInputStream inputStream = new ByteArrayServletInputStream(reqPayload.getBytes(RPCServletUtils.CHARSET_UTF8));
HttpServletRequestWrapper reqWrapper = new HttpServletRequestWrapper(httpReq) {
@Override
public ServletInputStream getInputStream() throws IOException {
return inputStream;
}
};
final CachingServletOutputStream outputStream = new CachingServletOutputStream();
HttpServletResponseWrapper respWrapper = new HttpServletResponseWrapper(httpResp) {
@Override
public ServletOutputStream getOutputStream() throws IOException {
return outputStream;
}
};
filterChain.doFilter(reqWrapper, respWrapper);
// possibly you also need to handle gzipped payload
String respPayload = new String(outputStream.getCachedDataAsBytes(), RPCServletUtils.CHARSET_UTF8);
String checksum = calculateChecksum(respPayload);
httpResp.setHeader(MY_CUSTOM_HEADER_NAME, checksum);
httpResp.getOutputStream().write(outputStream.getCachedDataAsBytes());
} else {
httpResp.setContentType("text/plain");
httpResp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
httpResp.getOutputStream().write("Invalid checksum".getBytes(RPCServletUtils.CHARSET_UTF8));
}
}
static class ByteArrayServletInputStream extends ServletInputStream {
private final InputStream delegate;
ByteArrayServletInputStream(byte[] data) throws IOException, ServletException {
delegate = new ByteArrayInputStream(data);
}
@Override
public int read() throws IOException {
return delegate.read();
}
}
static class CachingServletOutputStream extends ServletOutputStream {
private final ByteArrayOutputStream cache;
CachingServletOutputStream() {
this.cache = new ByteArrayOutputStream(4096);
}
@Override
public void write(int b) throws IOException {
cache.write(b);
}
@Override
public void flush() throws IOException {
cache.flush();
}
byte[] getCachedDataAsBytes() {
return cache.toByteArray();
}
}
}
出典
2017-05-16 09:32:44
Pat
どのようにサーバー側でサーブレットフィルタを使用して、カスタム[ 'RpcRequestBuilder'](約http://www.gwtproject.org/javadoc/latest/com:GWTのRPCServletUtilsは、いくつかの有用な方法のhereforeを持っています/google/gwt/user/client/rpc/RpcRequestBuilder.html)をクライアントサイドに追加しますか? –