如何在另一个 servlet 中使用其他 servlet 服务?
Posted
技术标签:
【中文标题】如何在另一个 servlet 中使用其他 servlet 服务?【英文标题】:How to use other servlets service in another servlet? 【发布时间】:2016-12-08 21:55:24 【问题描述】:我需要手动将请求从其他 servlet 的服务方法转发/制作到另一个 servlet。这个调用另一个 servlet 的 servlet 应该从其他 servlet 的响应中提取数据并将它自己的响应发送给客户端。如何实现这种功能?
Client <-----> Servlet1 <-----> Servlet2
我知道这是一个糟糕的设计,但由于情况我们不得不将 Servlet2 的功能引入到 Servlet1
【问题讨论】:
response.sendRedirect();
怎么样。
是的,您可以通过使用 Request Dispatcher 的 Forward 或 Include 方法(可用于 request
对象)或发送重定向方法(可用于 response
对象)来实现。 ServletContext
也是实现servlet
协作的方法之一,因为它提供了所有 servlet 的信息。
【参考方案1】:
你需要使用 HttpServletResponseWrapper 并覆盖它的 getOutputStream 方法。
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
您的主要课程:
使用RequestDespetcher.include()
将请求重定向到s2 并传递CustomHttpServletResponseWrapper
。
@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";
【讨论】:
这也不起作用,因为 S1 的响应将根据 S2 的响应计算 @TuomasToivonen,根据您的评论修改了答案。 不幸的是,我们的项目有不支持 HttpServletResponseWrapper 的旧 Java 平台。这似乎是一个装饰器模式,所以也许我可以自己实现它。无论如何,感谢您的详细回答,我必须在我的个人项目中对此进行测试。 不客气。我想知道没有HttpServletResponseWrapper你将如何实现它,只有这个类提供了HttpServletResponse的实现。如果您在没有 HttpServletResponseWrapper 的情况下解决它,请发布您的答案。一切顺利。 它肯定适用于您的个人项目。我在这里发布之前进行了测试。 :D以上是关于如何在另一个 servlet 中使用其他 servlet 服务?的主要内容,如果未能解决你的问题,请参考以下文章