これはデザイン/パターンの問題です。私は、RESTfulWebサービスとしても公開する必要があるサービスを持っています。
既存のコード内で、私はRequestの概念、可能なServiceOperations(戦略)のスイートを持っており、ServiceOperationの戻り値はResponseオブジェクトです。このアプローチは、サービスの内部動作をプレゼンテーションメディア(カスタムTCPサーバー、HTTP REST、HTTP SOAPなど)から切り離します。
これで、次のようなMyServiceRESTfulServletの実装を開始しました。
public void doGet(HttpRequest httpRequest, HttpResponse httpResponse) throws ServletException, IOException {
try {
/* Wrap an http servlet request with an adapter which hides all
* the messy details of an HttpRequest and exposes a nice interface
* for working with MyService
*/
IRequest serviceRequest = new MyServiceRESTfulRequest(httpRequest);
/* There's nothing HTTP related in this part, it's the exact same
* code you'd find in other presentation formats. A Response has
* no idea about HTTP, TCP Servers or the like.
*/
Response serviceResponse = dispatchRequest(serviceRequest);
/* A static helper which knows the interface of a Response
* and can translate that into REST-speak for feeding back via
* an HttpServletResponse.
*/
renderRESTfulResponse(serviceResponse, httpResponse);
} catch (Exception e) {
throw new ServletExcetion(e); // Caught by a seperate
// RESTfulErrorServlet
// configured in web.xml
// Rendering an appropriate
// response.
}
}
私の問題は、応答が現在2種類のいずれかになり得ることです。
public enum ResponseKind() {
BINARY, METADATA;
}
バイナリの場合、RESTful Response Helperは一方向にレンダリングします。メタデータの場合、メタデータを適切に提示する必要があります(HTMLテーブル、JSONブロブなど)。
どのタイプが簡単かを理解する-ResponseオブジェクトはgetOriginalRequest()を公開し、適切なチェックの後、.getAcceptablePresentation()を公開するMyServiceRESTfulRequestにキャストできます-列挙型:
public enum RESTPresentationKind() {
HTML, JSON, XML, PROTOBUF_MYSERV_0.1;
}
このレンダリングコードをResponseオブジェクトから切り離しておくにはどうすればよいでしょうか。将来的には、他の種類の対応も可能になることは間違いありません。現状では、renderRESTfulResponse()はRequestオブジェクトをレイドし、データを適切に書き込みます。それは両方のResponseインターフェース(私は大丈夫です)と非常に緊密に結合されていますが、Requestオブジェクトを突っ込むことも知っています。
私は、このサービスの残りの部分と同じように、このビットをクリーンで保守可能な方法で実行したとは感じていません。私は、可能な応答タイプのそれぞれ、および可能な応答形式のそれぞれの「特別なケーシング」です。ユーバーハッキーな感じ。
プレゼンテーションにとらわれないRequestオブジェクトを指定して、RESTful応答のレンダリングをクリーンに処理する方法を提案できますか?