Servlet中包含带EL与JSP标签的JSP文件无法正常渲染解决方案咨询
问题分析与解决方案
首先咱们得搞清楚根源:当你在Servlet的doGet方法里用RequestDispatcher.include()包含.jspf文件时,容器并不会自动解析其中的EL表达式和JSP标签。因为.jspf是JSP片段,它的设计初衷是在JSP页面内部通过<%@ include %>或<jsp:include>被包含,这时JSP引擎会完整解析所有标签和EL;但如果直接被Servlet的include调用,容器会把它当作静态文本直接输出,跳过JSP解析流程,所以浏览器才会把EL和标签当作普通HTML显示。
下面给你两种解决思路,优先推荐第一种(符合最佳实践),第二种是针对你坚持要在Servlet里处理的场景:
推荐方案:遵循MVC模式,把视图渲染交给JSP
Servlet的核心职责应该是处理业务逻辑、控制请求流转,页面渲染这种视图层工作交给JSP才是合理的。你可以这么做:
- 创建一个主JSP页面(比如
menu.jsp) - 在这个JSP里用
<jsp:include>或者<%@ include %>引入header.jspf和footer.jspf - 在Servlet的
doGet方法里,直接转发到这个主JSP:protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 处理业务逻辑,把需要的数据放到request属性里 request.setAttribute("someData", "要传递给JSP的数据"); // 转发到主JSP页面 request.getRequestDispatcher("/WEB-INF/menu.jsp").forward(request, response); }
这种方式下,JSP引擎会完整解析所有包含的片段,EL和标签都会正常工作,代码结构也更清晰。
备选方案:让Servlet包含的JSP片段被解析
如果你一定要在Servlet里直接生成页面并包含这些片段,可以通过以下步骤让容器解析JSP标签和EL:
- 确保JSP片段被JSP引擎处理:
- 要么把
footer.jspf改名为footer.jsp(容器默认会把.jsp交给JSP引擎处理) - 要么在
web.xml里配置Servlet映射,让.jspf也被JSP servlet处理:<servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jspf</url-pattern> </servlet-mapping>
- 要么把
- 正确设置响应类型并调用include:
在Servlet的doGet方法里,先设置响应的内容类型为text/html,再依次包含头、输出中间内容、包含尾:protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); // 包含header RequestDispatcher headerDispatcher = request.getRequestDispatcher("/WEB-INF/header.jspf"); headerDispatcher.include(request, response); // 输出中间内容 PrintWriter out = response.getWriter(); out.println("<div class='content'>这里是Servlet生成的中间内容</div>"); // 包含footer(如果改了后缀就用footer.jsp) RequestDispatcher footerDispatcher = request.getRequestDispatcher("/WEB-INF/footer.jspf"); footerDispatcher.include(request, response); } - 确保EL启用:如果你的JSP版本比较旧,可能需要在
footer.jspf顶部添加<%@ page isELIgnored="false" %>来启用EL表达式。
最后提醒
虽然第二种方法能解决问题,但确实属于不太推荐的实践——Servlet做视图渲染会让代码耦合度变高,后期维护起来也麻烦。还是优先考虑把视图逻辑交给JSP,Servlet专注于业务和控制,这才是Java Web的标准MVC思路。
内容的提问来源于stack exchange,提问作者user9222777
相关产品推荐
相关产品推荐

