缺少 Servlet 内容
Servlet contents missing
image showing login page not getting contents of the included servlet Classnames
image showing login page before form processing
我正在尝试将请求从 servlet 转发到 jsp 页面,该 jsp 页面在页面中包含一个或多个 servlet,实际上将请求从 servlet 转发到页面不是我的问题,但是当它把我带到那个页面时,那个页面中包含的 servlet 的内容丢失了......
这是要包含在页面
中的 class 的源代码...
package Classes;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name = "Classnames", urlPatterns = {"/Classnames"})
public class Classnames extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
Connection conn= ConnectionPackage.MyConnection.getConnection();
PrintWriter out = response.getWriter();
PreparedStatement ps;
ResultSet rs;
String class_name;
int class_id;
ps = conn.prepareStatement("SELECT class.class_name,class.id FROM class WHERE 1");
rs = ps.executeQuery();
while(rs.next()){
class_name = rs.getString("class_name");
class_id = rs.getInt("id");
out.println("<option value="+class_id+">"+class_name+"</option>");
}
ps.close();
rs.close();
conn.close();
}catch(Exception ex){}
}
}
那么包含包含的 servlet 的页面在下面
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="author" content="David Tega">
<meta name="description" content="Cbt Training Platform">
<link rel="stylesheet" type="text/css" href="css/w3.css">
<link rel="stylesheet" type="text/css" href="css/style.css">
<link rel="stylesheet" type="text/css" href="css/responsiveness.css">
<meta name="copyright" content="copyright 2005-2020 Tech Giants"/>
<meta name="robots" content="noindex,nofollow,noarchive"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Brainfield School Platform</title>
</head>
<body id="login" style="background-image: url('images/headway-5QgIuuBxKwM-unsplash.jpg'); background-size: cover;" >
<div class="w3-padding-large w3-white">
<div class="w3-container">
<p class="w3-wide w3-text-brown w3-large">Login...</p>
<p class="w3-text-red w3-small">${loginErrorMessage}</p>
</div>
<form action="StudentLogin" method="POST">
<div class="w3-row-padding">
<div class="w3-half container">
<select class="w3-select w3-border" name="class_name">
<option disabled selected>Class</option>
<jsp:include page="Classnames" flush="true"></jsp:include>
</select>
</div>
<div class="w3-half container">
<input class="w3-input w3-border" name="student_rollno" type="text" placeholder="(XXX)" maxlength="3">
</div>
<button class="w3-button w3-col w3-margin-top w3-gray w3-border w3-padding-small w3-text-white">Submit</button>
</div>
</form>
</div>
</body>
</html>
最后,处理 StudentLogin 页面上的表单的 servlet 如下
package LoginPackage;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet(name = "StudentLogin", urlPatterns = {"/StudentLogin"})
public class StudentLogin extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
Connection conn= ConnectionPackage.MyConnection.getConnection();
int roleId =6,state=1;
PreparedStatement ps;
ResultSet rs;
HttpSession ss = request.getSession(true);
String classId = request.getParameter("class_name");
String rollno = request.getParameter("student_rollno"),role,name,picture;
String id;
ps = conn.prepareStatement("SELECT students.userId,user.full_name,user.picture,roleinfo.name FROM students INNER JOIN user ON (students.userId = user.id) INNER JOIN roleinfo ON (user.roleId = roleinfo.id) WHERE students.rollno = '"+rollno+"' AND students.classId ='"+classId+"' AND user.roleId ="+roleId+" AND user.state = "+state+" ");
rs = ps.executeQuery();
if(rs.next()){
role = rs.getString("name");
name = rs.getString("full_name");
picture = rs.getString("picture");
id = rs.getString("userId");
ss.setAttribute("full_name", name);
ss.setAttribute("user_role", role);
ss.setAttribute("user_picture", picture);
ss.setAttribute("userId", id);
response.sendRedirect(request.getContextPath()+ "/StudentProfile.jsp" );
}else{
request.setAttribute("loginErrorMessage", "Incorrect Details, Try Again");
RequestDispatcher rd =request.getRequestDispatcher("StudentLogin.jsp");
rd.forward(request, response);
}
}catch(Exception ex){}
}
}
提前致谢
当您第一次访问登录 JSP 页面时,您使用的是 GET 方法。 JSP 处理 <jsp:include />
调用 Classnames servlet 的 doGet 方法。
当您使用 POST 方法提交表单时,您在 StudentLogin servlet 上使用的是 RequestDispatcher.forward
,因此登录 JSP 页面会处理 POST请求,<jsp:include />
调用 Classnames servlet 的 doPost 方法。
您应该重构您的 Classnames servlet,以使用 doGet 或 doPost 输出相同的结果,或者您可以使用 POST-redirect-GET(并转换 loginErrorMessage
请求属性请求参数)
要重构您的 Classnames servlet,您可以将当前的 doGet 方法实现放在一个新方法中,例如:
protected void outputOptions(HttpServletRequest request, HttpServletResponse response)
并从 doGet
和 doPost
调用该方法。
或者您可以简单地覆盖 HttpSevlet class 的 service
方法。 service
方法,如 javadoc 中所述:
Receives standard HTTP requests from the public service method and dispatches them to the doXXX methods defined in this class
因此,将您的逻辑放在该方法中,您可以省略重写 doGet 和 doPost 方法,因为 service
方法在任何情况下都会被调用:
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
Connection conn= ConnectionPackage.MyConnection.getConnection();
PrintWriter out = response.getWriter();
PreparedStatement ps;
ResultSet rs;
String class_name;
int class_id;
ps = conn.prepareStatement("SELECT class.class_name,class.id FROM class WHERE 1");
rs = ps.executeQuery();
while(rs.next()){
class_name = rs.getString("class_name");
class_id = rs.getInt("id");
out.println("<option value="+class_id+">"+class_name+"</option>");
}
ps.close();
rs.close();
conn.close();
} catch(Exception ex) {
// normally you should'nt ignore exceptions silently
log("Error getting options", ex);
}
}
此选项的唯一缺点是 service
方法将被所有 HTTP 方法调用,而不仅仅是 GET 和 POST。但是在包含的 servlet 中,这并不是真正的问题。
image showing login page not getting contents of the included servlet Classnames
image showing login page before form processing
我正在尝试将请求从 servlet 转发到 jsp 页面,该 jsp 页面在页面中包含一个或多个 servlet,实际上将请求从 servlet 转发到页面不是我的问题,但是当它把我带到那个页面时,那个页面中包含的 servlet 的内容丢失了......
这是要包含在页面
package Classes;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name = "Classnames", urlPatterns = {"/Classnames"})
public class Classnames extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
Connection conn= ConnectionPackage.MyConnection.getConnection();
PrintWriter out = response.getWriter();
PreparedStatement ps;
ResultSet rs;
String class_name;
int class_id;
ps = conn.prepareStatement("SELECT class.class_name,class.id FROM class WHERE 1");
rs = ps.executeQuery();
while(rs.next()){
class_name = rs.getString("class_name");
class_id = rs.getInt("id");
out.println("<option value="+class_id+">"+class_name+"</option>");
}
ps.close();
rs.close();
conn.close();
}catch(Exception ex){}
}
}
那么包含包含的 servlet 的页面在下面
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="author" content="David Tega">
<meta name="description" content="Cbt Training Platform">
<link rel="stylesheet" type="text/css" href="css/w3.css">
<link rel="stylesheet" type="text/css" href="css/style.css">
<link rel="stylesheet" type="text/css" href="css/responsiveness.css">
<meta name="copyright" content="copyright 2005-2020 Tech Giants"/>
<meta name="robots" content="noindex,nofollow,noarchive"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Brainfield School Platform</title>
</head>
<body id="login" style="background-image: url('images/headway-5QgIuuBxKwM-unsplash.jpg'); background-size: cover;" >
<div class="w3-padding-large w3-white">
<div class="w3-container">
<p class="w3-wide w3-text-brown w3-large">Login...</p>
<p class="w3-text-red w3-small">${loginErrorMessage}</p>
</div>
<form action="StudentLogin" method="POST">
<div class="w3-row-padding">
<div class="w3-half container">
<select class="w3-select w3-border" name="class_name">
<option disabled selected>Class</option>
<jsp:include page="Classnames" flush="true"></jsp:include>
</select>
</div>
<div class="w3-half container">
<input class="w3-input w3-border" name="student_rollno" type="text" placeholder="(XXX)" maxlength="3">
</div>
<button class="w3-button w3-col w3-margin-top w3-gray w3-border w3-padding-small w3-text-white">Submit</button>
</div>
</form>
</div>
</body>
</html>
最后,处理 StudentLogin 页面上的表单的 servlet 如下
package LoginPackage;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet(name = "StudentLogin", urlPatterns = {"/StudentLogin"})
public class StudentLogin extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
Connection conn= ConnectionPackage.MyConnection.getConnection();
int roleId =6,state=1;
PreparedStatement ps;
ResultSet rs;
HttpSession ss = request.getSession(true);
String classId = request.getParameter("class_name");
String rollno = request.getParameter("student_rollno"),role,name,picture;
String id;
ps = conn.prepareStatement("SELECT students.userId,user.full_name,user.picture,roleinfo.name FROM students INNER JOIN user ON (students.userId = user.id) INNER JOIN roleinfo ON (user.roleId = roleinfo.id) WHERE students.rollno = '"+rollno+"' AND students.classId ='"+classId+"' AND user.roleId ="+roleId+" AND user.state = "+state+" ");
rs = ps.executeQuery();
if(rs.next()){
role = rs.getString("name");
name = rs.getString("full_name");
picture = rs.getString("picture");
id = rs.getString("userId");
ss.setAttribute("full_name", name);
ss.setAttribute("user_role", role);
ss.setAttribute("user_picture", picture);
ss.setAttribute("userId", id);
response.sendRedirect(request.getContextPath()+ "/StudentProfile.jsp" );
}else{
request.setAttribute("loginErrorMessage", "Incorrect Details, Try Again");
RequestDispatcher rd =request.getRequestDispatcher("StudentLogin.jsp");
rd.forward(request, response);
}
}catch(Exception ex){}
}
}
提前致谢
当您第一次访问登录 JSP 页面时,您使用的是 GET 方法。 JSP 处理 <jsp:include />
调用 Classnames servlet 的 doGet 方法。
当您使用 POST 方法提交表单时,您在 StudentLogin servlet 上使用的是 RequestDispatcher.forward
,因此登录 JSP 页面会处理 POST请求,<jsp:include />
调用 Classnames servlet 的 doPost 方法。
您应该重构您的 Classnames servlet,以使用 doGet 或 doPost 输出相同的结果,或者您可以使用 POST-redirect-GET(并转换 loginErrorMessage
请求属性请求参数)
要重构您的 Classnames servlet,您可以将当前的 doGet 方法实现放在一个新方法中,例如:
protected void outputOptions(HttpServletRequest request, HttpServletResponse response)
并从 doGet
和 doPost
调用该方法。
或者您可以简单地覆盖 HttpSevlet class 的 service
方法。 service
方法,如 javadoc 中所述:
Receives standard HTTP requests from the public service method and dispatches them to the doXXX methods defined in this class
因此,将您的逻辑放在该方法中,您可以省略重写 doGet 和 doPost 方法,因为 service
方法在任何情况下都会被调用:
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
Connection conn= ConnectionPackage.MyConnection.getConnection();
PrintWriter out = response.getWriter();
PreparedStatement ps;
ResultSet rs;
String class_name;
int class_id;
ps = conn.prepareStatement("SELECT class.class_name,class.id FROM class WHERE 1");
rs = ps.executeQuery();
while(rs.next()){
class_name = rs.getString("class_name");
class_id = rs.getInt("id");
out.println("<option value="+class_id+">"+class_name+"</option>");
}
ps.close();
rs.close();
conn.close();
} catch(Exception ex) {
// normally you should'nt ignore exceptions silently
log("Error getting options", ex);
}
}
此选项的唯一缺点是 service
方法将被所有 HTTP 方法调用,而不仅仅是 GET 和 POST。但是在包含的 servlet 中,这并不是真正的问题。