我正在尝试将现有应用程序从带有ServletExec的IIS迁移到tomcat。除了有两个servlet的servlet链的情况以外,我都能正常工作。
第一个servlet进行一些处理,第二个servlet进行一些转换。
request-->ProcessServlet--> (untranslated html) -->TranslateServlet --> response
就我而言,我可以调用ProcessServlet并生成带有未翻译标签的html。第二个servlet看起来像它获取html一样,找到了众所周知的翻译标签并对其进行翻译,并向浏览器生成可读的输出。
从谷歌搜索看来,不再支持/不推荐使用servlet别名的servlet链接(来自此页面),并且可以使用过滤器实现相同的功能,但是类必须实现接口,但是不幸的是,我必须使用现有的类文件。
该页面指定了概念,但没有示例。
也是从这个页面
如何使用Servlet别名配置Servlet链 使用“管理工具”中“设置”部分的“ Servlet别名”小节,可以为特定的URL请求命名Servlet列表。在servlets表中,添加新映射时,允许您输入以逗号分隔的servlet列表,该顺序是在到达特定URL的请求时应调用的顺序。这配置了每次与URL匹配的请求到达时都要调用的servlet链。
如何使用Servlet别名配置Servlet链
使用“管理工具”中“设置”部分的“ Servlet别名”小节,可以为特定的URL请求命名Servlet列表。在servlets表中,添加新映射时,允许您输入以逗号分隔的servlet列表,该顺序是在到达特定URL的请求时应调用的顺序。这配置了每次与URL匹配的请求到达时都要调用的servlet链。
任何人都可以指定一个示例或为我指出正确的方向,如何使该链从web.xml运行?
更新:
Per kschneid在回答中的概述,这是对我有用的完整实现
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class TranslateFilter implements Filter { private FilterConfig config = null; public void init(FilterConfig config) throws ServletException { this.config = config; } public void destroy() { config = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse httpResponse = (HttpServletResponse) response; MyHttpServletResponseWrapper processResponse = new MyHttpServletResponseWrapper(httpResponse); chain.doFilter(request, processResponse ); String content = processResponse.toString(); config.getServletContext().log("CONTENT: " + content); HttpServletRequest httpRequest = (HttpServletRequest) request; MyHttpServletRequestWrapper processResponseAsRequest = new MyHttpServletRequestWrapper(httpRequest, content); RequestDispatcher dispatch = request.getRequestDispatcher("/Translate"); response.setContentType("text/html"); dispatch.forward(processResponseAsRequest, response); // forward to translate servlet with response from process servlet as the request and the original response } } class MyHttpServletResponseWrapper extends HttpServletResponseWrapper { private StringWriter sw = new StringWriter(); public MyHttpServletResponseWrapper(HttpServletResponse response) { super(response); } public PrintWriter getWriter() throws IOException { return new PrintWriter(sw); } public ServletOutputStream getOutputStream() throws IOException { throw new UnsupportedOperationException(); } public String toString() { return sw.toString(); } } class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { private String content; public MyHttpServletRequestWrapper(HttpServletRequest request) { super(request); } public MyHttpServletRequestWrapper(HttpServletRequest request, String content) { super(request); this.content = content; } public ServletInputStream getInputStream() { return new MyServletInputStream(content); } public BufferedReader getReader() { InputStreamReader in= new InputStreamReader(getInputStream()); return new BufferedReader(in); } } class MyServletInputStream extends ServletInputStream { private InputStream is; public MyServletInputStream(String content) { is = new ByteArrayInputStream(content.getBytes()); } public int read() throws IOException { return is.read(); } }
我不太熟悉servlet链接的实现细节,但是这是一种可行的通用方法。将两个servlet映射到不同的URL:
<servlet-mapping> <servlet-name>process</servlet-name> <url-pattern>/process</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>translate</servlet-name> <url-pattern>/translate</url-pattern> </servlet-mapping>
然后将过滤器映射到processservlet:
process
<filter-mapping> <filter-name>processChain</filter-name> <servlet-name>process</servlet-name> </filter-mapping>
该processChain过滤器会做这样的事情:
processChain
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { ServletResponseWrapper processResponse = ...; // response buffer chain.doFilter(request, processResponse); // let process servlet populate response buffer ServletRequestWrapper processResponseAsRequest = ...; // use processResponse to create request for translate servlet RequestDispatcher dispatch = request.getRequestDispatcher("/translate"); dispatch.forward(processResponseAsRequest, response); // forward to translate servlet with response from process servlet as the request and the original response }
…或类似的东西 ;)