java - 如何在另一个servlet中使用其他servlet服务?

标签 java http servlets web request

我需要手动将请求从其他 servlet 的服务方法转发/制作到另一个 servlet。这个调用另一个 servlet 的 servlet 应该从其他 servlet 的响应中提取数据并将其自己的响应发送给客户端。如何实现这样的功能?

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

我知道这样的设计很糟糕,但由于环境原因,我们必须将 Servlet2 的功能引入 Servlet1

最佳答案

您需要使用 HttpServletResponseWrapper 并重写其 getOutputStream 方法。

CustomHttpServletResponseWrapperCustomServletOutputStream 是此功能的实现。

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/

相关文章:

http - 带逗号的 header 值

python - 如何在 Python 中发出 PATCH 请求?

java - 在 § 之前附加一个特殊字符

java - JSP/Servlet : What causes Servlet Error when trying to record to SQL?

java - 使用 Java 中的属性的用户配置文件

java - 如何将 Jackson mixin 添加到读取器而不是对象映射器?

Angular HttpPost 方法返回 405 方法不允许

apache - 将内网IP映射到作为服务器的静态IP

java - 从 Struts2 jquery Autocomplete 获取类型值

java - 如果给出无效响应,请重新运行 main 方法?