2016-08-03 2 views
0

リクエストを他のサーブレットのサービスメソッドから別のサーブレットに手動で転送する必要があります。別のサーブレットを呼び出すこのサーブレットは、他のサーブレットの応答からデータを抽出し、それ自身の応答をクライアントに送信する必要があります。この種の機能を実現するには?別のサーブレットで他のサーブレットサービスを使用する方法は?

Client <-----> Servlet1 <-----> Servlet2

私はそれが悪いデザインだけど、事情により、我々はあなたがにHttpServletResponseWrapperを使用し、そのgetOutputStreamのメソッドをオーバーライドする必要にservlet1

+0

「response.sendRedirect();」についてはどうでしょうか。 – Kartic

+0

はい、Request DispatcherのForwardメソッドまたはIncludeメソッド( 'request'オブジェクトで利用可能)またはSend Redirectメソッド(' response'オブジェクトで利用可能)を使用して達成できます。 'ServletContext'は、すべてのサーブレットの情報を提供するものであるため、' servlet'コラボレーションを実現する方法の1つです。 – Mihir

答えて

1

にServlet2の機能を導入する必要があります。

CustomHttpServletResponseWrapperおよびCustomServletOutputStreamがこのための実装です。

import java.io.IOException; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 

import javax.servlet.ServletOutputStream; 
import javax.servlet.http.HttpServletResponse; 
import javax.servlet.http.HttpServletResponseWrapper; 

public class CustomHttpServletResponseWrapper extends HttpServletResponseWrapper { 
    private ServletOutputStream outputStream; 
    private PrintWriter writer; 
    private CustomServletOutputStream os; 

    public CustomHttpServletResponseWrapper(HttpServletResponse response) throws IOException { 
     super(response); 
    } 

    @Override 
    public ServletOutputStream getOutputStream() throws IOException { 
     if (writer != null) { 
      throw new IllegalStateException("getWriter() has already been called on this response."); 
     } 

     if (outputStream == null) { 
      outputStream = getResponse().getOutputStream(); 
      os = new CustomServletOutputStream(outputStream); 
     } 

     return os; 
    } 

    @Override 
    public PrintWriter getWriter() throws IOException { 
     if (outputStream != null) { 
      throw new IllegalStateException("getOutputStream() has already been called on this response."); 
     } 

     if (writer == null) { 
      os = new CustomServletOutputStream(getResponse().getOutputStream()); 
      writer = new PrintWriter(new OutputStreamWriter(os, getResponse().getCharacterEncoding()), true); 
     } 

     return writer; 
    } 

    @Override 
    public void flushBuffer() throws IOException { 
     if (writer != null) { 
      writer.flush(); 
     } else if (outputStream != null) { 
      os.flush(); 
     } 
    } 

    public byte[] getContent() { 
     if (os != null) { 
      return os.getContent(); 
     } else { 
      return new byte[0]; 
     } 
    } 

} 

customServletOutputStream.java

import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.OutputStream; 

import javax.servlet.ServletOutputStream; 
import javax.servlet.WriteListener; 

public class CustomServletOutputStream extends ServletOutputStream { 

     private OutputStream outputStream; 
     private ByteArrayOutputStream content; 

     public CustomServletOutputStream(OutputStream outputStream) { 
      this.outputStream = outputStream; 
      this.content = new ByteArrayOutputStream(1024); 
     } 

     @Override 
     public void write(int b) throws IOException { 
      outputStream.write(b); 
      content.write(b); 
     } 

     public byte[] getContent() { 
      return content.toByteArray(); 

} 

     @Override 
     public boolean isReady() { 
      // TODO Auto-generated method stub 
      return false; 
     } 

     @Override 
     public void setWriteListener(WriteListener writeListener) { 
      // TODO Auto-generated method stub 

     } 
} 

自分のメインクラス: S2に要求をリダイレクトしてCustomHttpServletResponseWrapperを渡すためにRequestDespetcher.include()を使用しています。

@ResponseBody 
    @RequestMapping("/s1")  
public String s1(HttpServletRequest req, HttpServletResponse res) throws Exception{ 
     RequestDispatcher rd = req.getRequestDispatcher("/oauth2/s2"); 
     CustomHttpServletResponseWrapper wrappedResponse = new CustomHttpServletResponseWrapper(res); 
     rd.include(req, wrappedResponse); 
     wrappedResponse.flushBuffer(); 
     byte[] result = wrappedResponse.getContent(); 
     System.out.println("result of servlet 2 "+new String(result)); 
    // here you got the result of servlet 2. manipulate it as you want. 

     return new String(result); 
    } 

    @ResponseBody 
    @RequestMapping("/s2") 
    public String s2(HttpServletRequest req, HttpServletResponse res){ 
     return "hello from s2"; 
    } 
+0

これは、S1の応答がS2 –

+0

@TuomasToivonenの応答から計算されるため、あなたのコメントに応じて答えを修正したため、どちらも動作しません。 – Suraj

+0

残念ながら、私たちのプロジェクトには、HttpServletResponseWrapperをサポートしない古いJavaプラットフォームがあります。これは装飾パターンのように思えるので、私はそれを自分で実装することができます。とにかく詳細な答えをありがとう、私は私の個人的なプロジェクトでこれをテストする必要があります。 –

関連する問題