介绍
doGet()
当您想拦截HTTP GET请求时应使用。doPost()
当您想拦截HTTP POST请求时应使用。就这样。不要将一个移植到另一个,反之亦然(例如,在Netbeans不幸的自动生成processRequest()
方法中)。这完全没有道理。
得到
通常,HTTP GET请求是幂等的。也就是说,每次执行请求时,您都会获得完全相同的结果(无需考虑授权/身份验证和页面的时间敏感性(搜索结果,最新消息等))。我们可以谈论一个可收藏的请求。单击链接,单击书签,在浏览器地址栏中输入原始URL,等等都会触发HTTP GET请求。如果Servlet正在侦听有问题的URL,则将doGet()
调用其方法。通常用于预处理请求。即在呈现来自JSP的HTML输出之前进行一些业务工作,例如收集数据以显示在表中。
@WebServlet("/products")
public class ProductsServlet extends HttpServlet {
@EJB
private ProductService productService;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Product> products = productService.list();
request.setAttribute("products", products); // Will be available as ${products} in JSP
request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
}
}
<table>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.name}</td>
<td><a href="product?id=${product.id}">detail</a></td>
</tr>
</c:forEach>
</table>
同样,如上最后一列所示,查看/编辑详细信息链接通常也是幂等的。
@WebServlet("/product")
public class ProductServlet extends HttpServlet {
@EJB
private ProductService productService;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Product product = productService.find(request.getParameter("id"));
request.setAttribute("product", product); // Will be available as ${product} in JSP
request.getRequestDispatcher("/WEB-INF/product.jsp").forward(request, response);
}
}
<dl>
<dt>ID</dt>
<dd>${product.id}</dd>
<dt>Name</dt>
<dd>${product.name}</dd>
<dt>Description</dt>
<dd>${product.description}</dd>
<dt>Price</dt>
<dd>${product.price}</dd>
<dt>Image</dt>
<dd><img src="productImage?id=${product.id}" /></dd>
</dl>
开机自检
HTTP POST请求不是幂等的。如果最终用户事先在URL上提交了POST表单,但尚未执行重定向,则该URL不一定是可书签的。提交的表单数据未反映在URL中。将URL复制粘贴到新的浏览器窗口/选项卡中不一定会产生与提交表单后完全相同的结果。这样,这样的URL就无法添加书签。如果Servlet正在侦听有问题的URL,则将doPost()
调用它。通常用于对请求进行后处理。即从提交的HTML表单中收集数据并进行一些处理(转换,验证,保存到DB等)。最后,通常结果从转发的JSP页面以HTML形式呈现。
<form action="login" method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="login">
<span class="error">${error}</span>
</form>
...可以与这部分Servlet结合使用:
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@EJB
private UserService userService;
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userService.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user);
response.sendRedirect("home");
}
else {
request.setAttribute("error", "Unknown user, please try again");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
}
您会看到,如果User
在数据库中找到(即用户名和密码有效),则会User
将其放入会话范围(即“登录”),并且servlet将重定向到某个主页(此示例转到http://example.com/contextname/home
),否则它将设置一条错误消息,并将请求转发回同一JSP页面,以使该消息显示为${error}
。
如有必要,您也可以“隐藏”其中login.jsp
,/WEB-INF/login.jsp
以便用户只能通过servlet访问它。这样可以保持URL干净http://example.com/contextname/login
。您需要做的就是doGet()
像这样向servlet 添加一个:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
(并相应地更新同一行doPost()
)
就是说,我不确定它是否只是在黑暗中玩耍而已,但是您发布的代码看起来并不好(例如使用compareTo()
代替而不是equals()
并挖掘参数名,而不是仅仅使用getParameter()
and id
和and password
似乎被声明为servlet实例变量-不是threadsafe)。所以我强烈建议使用多了解一些关于基本的Java SE API 的Oracle教程(检查章“路线涵盖基础知识”)以及如何使用JSP / Servlet的使用正确的方法的教程。
也可以看看:
更新:根据您的问题的更新(这是相当重要的,您不应该删除原始问题的一部分,这会使答案毫无价值..而是在新的块中添加信息),事实证明您是不必要将表单的编码类型设置为multipart/form-data
。这将以与(默认)不同的构成发送请求参数,该(默认)application/x-www-form-urlencoded
发送请求参数作为查询字符串(例如name1=value1&name2=value2&name3=value3
)。你只需要multipart/form-data
一有空就<input type="file">
表单中的元素,以上传可能是非字符数据(二进制数据)的文件。您的情况并非如此,因此只需将其删除即可正常工作。如果您需要上传文件,则必须将编码类型设置为so,然后自己解析请求主体。通常,您在那里使用Apache Commons FileUpload,但是如果您已经在使用新的Servlet 3.0 API,那么您可以使用以开头的内置工具HttpServletRequest#getPart()
。另请参见此答案以获取具体示例:如何使用JSP / Servlet将文件上传到服务器?