导言
你应该用doGet()当你想拦截http获取请求..你应该用doPost()当你想拦截http POST请求..就这样。不要将其中一个移植到另一个,反之亦然(例如在netbeans的不幸的自动生成中)。processRequest()方法)。这完全没有道理。
到达
通常,HTTPGET请求是幂等..即。每次执行请求时,都会得到完全相同的结果(保留授权/身份验证以及页面搜索结果的时间敏感性、最后消息等-外部考虑)。我们可以讨论一个可书签的请求。点击一个链接,点击一个书签,在浏览器地址栏中输入原始URL,等等,都会触发一个HTTPGET请求。如果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 products = productService.list();
request.setAttribute("products", products); // Will be available as ${products} in JSP
request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
}}
${product.name} | detail |
另外,如上列所示,查看/编辑细节链接通常是幂等的。@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);
}}
-
ID
- ${product.id} Name
- ${product.name} Description
- ${product.description} Price
- ${product.price} Image
岗
http POST请求不是幂等的。如果Enduser事先在URL上提交了一个POST表单,但还没有执行重定向,那么这个URL不一定是可书签的。提交的表单数据未反映在URL中。将URL复制到新的浏览器窗口/选项卡并不一定会产生与表单提交后完全相同的结果。这样的URL是不可书签的。如果servlet正在侦听所述URL,则其doPost()会被召唤。通常用来后处理一个请求。即。从提交的HTML表单中收集数据,并使用它做一些业务工作(转换、验证、数据库保存等)。最后,通常将结果显示为来自转发的JSP页面的HTML。
${error}
.它可以与这个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在DB中找到(即用户名和密码是有效的),则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()而id和password似乎被声明为servlet实例变量-这不是线程安全)。因此,我强烈建议使用Oracle教程(查看“TrailsovertheBasics”一章),以及如何正确地使用JSP/Servlet那些教程.
另见:
更新:根据你的问题的更新(这是相当重要的,你不应该删除你原来问题的一部分,这将使答案变得毫无价值。)相反加(新块中的信息),结果是不必要地将表单的编码类型设置为multipart/form-data..这将在与(默认值)不同的组合中发送请求参数。application/x-www-form-urlencoded它将请求参数作为查询字符串发送(例如:name1=value1&name2=value2&name3=value3)。你只需要multipart/form-data每当你有一个元素来上载文件,这些文件可能是非字符数据(二进制数据)。这种情况在您的情况下不是这样的,所以只需删除它,它就会像预期的那样工作。如果您需要上传文件,那么您必须设置编码类型,然后自己解析请求体。通常使用ApacheCommonsFileUpload但是,如果您已经使用了新的Servlet3.0 API,那么您可以使用内置的工具,从HttpServletRequest#getPart()..另见这个具体例子的答案:如何使用JSP/Servlet将文件上传到服务器?