如何控制JSP及Servlet中Java代码与HTML的执行顺序?
解答你的Servlet/JSP执行顺序问题
问题1:Servlet中如何让HTML表单在Java代码前执行,或合理安排response输出流
Servlet的执行逻辑并非固定的“先Java后HTML”,核心取决于你什么时候向响应流写入内容。response的输出流是顺序写入的,先写的内容会先被客户端接收并渲染。
举个清晰的例子:
- 如果你的需求是先显示表单,再处理后续逻辑(比如表单提交后的业务),要区分GET和POST请求:
// GET请求时,先输出HTML表单供用户填写 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); // 先输出表单的HTML代码 out.println("<html><body>"); out.println("<form method='post' action='your-servlet-url'>"); out.println("用户名:<input type='text' name='username'><br>"); out.println("<input type='submit' value='提交'>"); out.println("</form></body></html>"); } // POST请求时,处理表单提交的数据 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); // 执行你的Java业务逻辑,比如数据库查询、数据校验等 // ... // 最后输出处理结果的HTML PrintWriter out = response.getWriter(); out.println("<html><body>提交成功,你的用户名是:" + username + "</body></html>"); }
如果你的逻辑不需要依赖表单数据,只是想让表单先显示,直接在对应方法中先通过response.getWriter()输出表单HTML,再执行Java逻辑即可。
问题2:JSP中jsp:include导航被Java代码输出挤到下方的问题
看你提供的JSP代码,问题出在直接使用response.getWriter()输出内容——JSP的内置out对象和response.getWriter()不是同一个输出流,直接调用response.getWriter()会绕过JSP的缓冲区,提前把内容写入响应流,导致列表内容跑到了<jsp:include>导入的导航前面。
具体解决步骤:
- 禁用
response.getWriter(),改用JSP内置的out对象或EL表达式输出内容 - 把Java逻辑仅放在页面顶部做数据准备,不要在逻辑中直接输出页面内容,然后在需要显示列表的位置再循环输出
修改后的代码示例:
<%@page import="com.DB.Config.TimeSheetData" import="java.util.List" import="com.DB.Config.Timesheet"%> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <jsp:include page="HomePage.jsp" /> <!-- 导航会按顺序先输出 --> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <link rel="stylesheet" href="css/style.css" /> <script src="https://code.jquery.com/jquery-1.10.2.js"></script> <title>Weekly generated Time Sheet</title> </head> <body> <style> .TimeSheetForm { margin-top: 100px; } </style> <% // 这里只做数据准备,不输出页面内容 HttpSession sessions = request.getSession(); String UserName = "", Password = ""; TimeSheetData timeSheetData = new TimeSheetData(); try { UserName = sessions.getAttribute("UserName").toString(); Password = sessions.getAttribute("Password").toString(); System.out.println("UserName : " + UserName + " and password is : " + Password); System.out.println(UserName + " user entered the TimeSheet Approval page"); } catch (NullPointerException ne) { System.out.println("This is coz User Details are null at time sheet page"); } List<Timesheet> TIMESHEET = timeSheetData.getTimeSheet(UserName); // 控制台打印不影响页面输出,可保留 for (Timesheet TS : TIMESHEET) { System.out.println(TS.getUserName() + " " + TS.getAttendence() + " " + TS.getWorkingime() + " " + TS.getActualWorkingTime() + " " + TS.getBreakTime() + " " + TS.getDate()); } %> <form class="TimeSheetForm"> <!-- 你的表单内容保持不变 --> </form> <!-- 在需要显示列表的位置,用JSP脚本输出内容 --> <div> <% int count = 0; for (Timesheet TS : TIMESHEET) { // 这里写你的列表输出逻辑,比如: out.println("<p>" + TS.getUserName() + " - " + TS.getDate() + "</p>"); count++; } %> </div> </body> </html>
额外优化建议:
尽量少用JSP脚本(<% %>),改用JSTL标签+EL表达式,代码更简洁易维护:
<!-- 先导入JSTL核心标签库 --> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!-- 在需要显示列表的位置替换成: --> <div> <c:forEach items="${TIMESHEET}" var="TS" varStatus="count"> <p>${TS.userName} - ${TS.date}</p> </c:forEach> </div>
内容的提问来源于stack exchange,提问作者Saif Tak
相关产品推荐
相关产品推荐

