我需要手动将请求从其他 servlet 的服务方法转发/制作到另一个 servlet。这个调用另一个 servlet 的 servlet 应该从其他 servlet 的响应中提取数据并将其自己的响应发送给客户端。如何实现这样的功能?
Client <-----> Servlet1 <-----> Servlet2
我知道这样的设计很糟糕,但由于环境原因,我们必须将 Servlet2 的功能引入 Servlet1
最佳答案
您需要使用 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];
}
}
}
自定义ServletOutputStream.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";
}
关于java - 如何在另一个servlet中使用其他servlet服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38739160/