doGet和doPost在Servlets中
我开发了一个将信息发送给Servlet的HTML页面。 在Servlet中,我使用了doGet()
和doPost()
:
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String id = req.getParameter("realname"); String password = req.getParameter("mypassword"); } public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String id = req.getParameter("realname"); String password = req.getParameter("mypassword"); }
在调用Servlet的html页面代码中:
<form action="identification" method="post" enctype="multipart/form-data"> User Name: <input type="text" name="realname"> Password: <input type="password" name="mypassword"> <input type="submit" value="Identification"> </form>
当我在Servlet中使用method = "get"
的时候,我得到了id和password的值,但是当使用method = "post"
,id和password被设置为null
。 为什么我不能在这种情况下获得价值?
另一件我想知道的是如何使用由Servlet生成或validation的数据。 例如,如果上面显示的Servletauthentication用户,我想在我的HTML页面中打印用户标识。 我应该能够发送string“id”作为回应,并在我的HTML页面中使用这个信息。 可能吗?
介绍
当你想拦截HTTP GET请求时,你应该使用doGet()
。 当您想拦截HTTP POST请求时,您应该使用doPost()
。 就这样。 不要移植到另一个,反之亦然(如在Netbeans的不幸的自动生成的processRequest()
方法)。 这没有任何意义。
得到
通常,HTTP GET请求是幂等的 。 也就是说,每次执行请求时,都会得到完全相同的结果(对授权/身份validation以及页面search结果,上一个消息等时间敏感的特性进行外部考虑)。 我们可以谈论一个可collections的请求。 点击一个链接,点击一个书签,在浏览器地址栏中input原始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>
POST
HTTP POST请求不是幂等的。 如果最终用户事先在URL上提交了一个POST表单,而这个表单没有执行redirect,那么该URL不一定是可collections的。 提交的表单数据不会反映在URL中。 将URL复制到新的浏览器窗口/选项卡中可能不一定产生与表单提交后完全相同的结果。 这样的URL然后是不可collections的。 如果一个Servlet正在监听有关的URL,那么它的doPost()
将被调用。 通常用于后处理请求。 即从提交的HTML表单收集数据,并用它做一些业务内容(转换,validation,保存在数据库等)。 最后,结果通常是从转发的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
在数据库中find(即用户名和密码是有效的),那么User
将被放在会话范围内(即“login”),该servlets器将redirect到一些主页(这个例子去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实例variables – 这不是线程安全 )。 所以我强烈推荐使用Oracle教程 (请参阅“Trails Covering the Basics”一章)以及如何正确使用这些教程来学习更多关于基本Java SE API的知识。
也可以看看:
- 我们的servlets wiki页面
- Java EE web开发,我从哪里开始,我需要什么技能?
- Servlet返回“HTTP状态404请求的资源(/ servlet)不可用”
- 在JSP页面中使用MVC和DAO模式在HTML中显示JDBC ResultSet
更新 :根据你的问题的更新(这是相当重要的,你不应该删除你原来的问题的一部分,这将使答案毫无价值..而是添加信息在一个新的块),事实certificate,你不必要地将表单的编码types设置为multipart/form-data
。 这将发送请求参数的组合不同于(缺省) application/x-www-form-urlencoded
,它将请求参数作为查询string发送(例如name1=value1&name2=value2&name3=value3
)。 只要在multipart/form-data
有一个<input type="file">
元素来上传可能是非字符数据(二进制数据)的文件,就只需要multipart/form-data
。 这不是你的情况,所以只要删除它,它会按预期工作。 如果您需要上传文件,那么您必须设置编码types,然后自己分析请求主体。 通常你使用的是Apache Commons FileUpload ,但是如果你已经使用了新的Servlet 3.0 API,那么你可以使用HttpServletRequest#getPart()
开始的内置工具。 另请参阅此答案的具体示例: 如何使用JSP / Servlet将文件上载到服务器?
浏览器使用GET和POST来从服务器请求单个资源。 每个资源都需要单独的GET或POST请求。
- GET方法是浏览器用来从服务器检索信息的最常用的方法(也是默认方法)。 当使用GET方法时,请求数据包的第三部分(请求主体)保持为空。
GET方法有两种使用方法:当没有指定方法时,即当你或浏览器正在请求一个简单的资源,如HTML页面,图像等。当提交一个表单,并且你select方法= HTML标记上的GET。 如果GET方法与HTML表单一起使用,则通过表单收集的数据通过附加“?”发送到服务器。 到URL的末尾,然后添加由“&”分隔的所有名称=值对(html表单字段的名称和在该字段中input的值)例如:GET /sultans/shop//form1.jsp?name= Sam%20Sultan&iceCream =香草HTTP / 1.0可选的headeroptional标题<<空行>>>
name = value表单数据将被存储在名为QUERY_STRING的环境variables中。 这个variables将被发送到一个处理程序(比如JSP,Java servlet,PHP等)
- 创buildHTML表单时使用POST方法,并请求method = POST作为标记的一部分。 POST方法允许客户端将表单数据发送到请求的请求正文部分中的服务器(如前所述)。 数据被编码,格式与GET方法类似,不同的是数据通过标准input发送到程序。
例如:POST /sultans/shop//form1.jsp HTTP / 1.0可选的headeroptional标题<<空行>>> name = Sam%20Sultan&iceCream = vanilla
当使用post方法时,QUERY_STRING环境variables将是空的。 GET与POST的优点/缺点
GET方法的优点:稍微快一些参数可以通过表单input,也可以在URL页面join参数后添加
GET方法的缺点:只能发送4K值的数据。 (使用textarea字段时,不应该使用它)参数在URL的末尾是可见的
POST方法的优点:参数在URL的末尾不可见。 (用于敏感数据)可以向服务器发送更多的4K值的数据
POST方法的缺点:不能用数据加书签
servlet容器的HttpServlet.service()方法的实现将根据需要自动转发到doGet()或doPost(),因此您不需要重写该服务方法。
难道是你通过获取传递数据,而不是后?
<form method="get" ..> .. </form>
如果您为您的html表单执行<form action="identification" >
,那么数据将默认使用“Get”传递,因此您可以在您的java servlet代码中使用doGet函数来捕获数据。 这样数据将在HTML标题下传递,因此在提交时将在URL中可见。 另一方面,如果你想在HTML体中传递数据,那么使用Post: <form action="identification" method="post">
并在doPost函数中捕获这个数据。 这是,数据将被传递到HTML正文,而不是HTML标题,并且在提交表单后,您将不会看到URL中的数据。
从我的html的例子:
<body> <form action="StartProcessUrl" method="post"> ..... .....
来自我的Java Servlet代码的例子:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub PrintWriter out = response.getWriter(); String surname = request.getParameter("txtSurname"); String firstname = request.getParameter("txtForename"); String rqNo = request.getParameter("txtRQ6"); String nhsNo = request.getParameter("txtNHSNo"); String attachment1 = request.getParameter("base64textarea1"); String attachment2 = request.getParameter("base64textarea2"); ......... .........