对于大多数Web开发人员而言,Web应用程序中的表单处理就像小菜一碟。 如果我们无法捕获用户的输入并进行处理,将不会有太大用处。 因此,我在servlet3示例中包含了一个简单的FormServlet ,该示例演示了您可能会遇到的很少使用的表单输入。 看起来是这样的:
package zemian.servlet3example.web;import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import zemian.service.logging.Logger;@WebServlet("/form")
public class FormServlet extends HtmlWriterServlet {private static final Logger LOGGER = new Logger(FormServlet.class);@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {HtmlWriter html = createHtmlWriter(req, resp); String message = getMessage(req);html.header().h(1, "User Data Form").p(message).println("<form method='post' action='form'>").println("<p/>Username: <input type='text' name='username'/>").println("<p/>Password: <input type='password' name='password'/>").println("<p/>Choose a country: <select name='country' size='1'>").println("<option default='true'>US</option>").println("<option>China</option>").println("<option>Korea</option>").println("</select>").println("<p/>Skills set: <input type='checkbox' name='skills' value='Java'/> Java").println("<input type='checkbox' name='skills' value='Java EE'/>Java EE").println("<input type='checkbox' name='skills' value='MySQL Database'/> MySQL Database").println("<p/>Notes: <textarea name='notes' cols='50' rows='3'></textarea>").println("<p/><input type='submit' value='Submit'/>").println("</form>").println(html.link("Back to Home", "/index")).footer();}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {LOGGER.info("Processing form.");Form form = new Form();form.setUsername(req.getParameter("username"));form.setPassword(req.getParameter("password"));form.setNotes(req.getParameter("notes"));form.setCountry(req.getParameter("country"));String[] skills = req.getParameterValues("skills");skills = (skills == null) ? new String[0] : skills;form.setSkills(Arrays.asList(skills));req.setAttribute("message", "Processed: " + form);doGet(req, resp);}private String getMessage(HttpServletRequest req) {String message = (String)req.getAttribute("message");if (message == null) {message = "";}return message;}
}
与往常一样,大多数表单都显示一个http GET请求,然后通过POST操作对其进行处理。 仔细研究一下,并密切注意Servlet如何处理单值或多值输入。 存在这些是因为HTML表单可能允许用户从单个输入标签/小部件中选择多个值。
开发人员在表单处理中常用的一种模式是将输入数据捕获到“命令对象”,“传输对象”或(在我的示例中)“表单”对象中; 这样就可以将数据传递到应用程序的另一层进行进一步处理。 这是一个很好的设计,因为它可以将Web层依赖项与后端层服务层分离。
表单处理中另一个经常处理的领域是数据验证。 如果将数据捕获为表单对象,则可能会有两层验证。 一层是当您直接从http请求(通常是从String输入)提取它时,然后您将进行验证,例如它是必填字段还是可选字段,是String值是否可以转换为预期和期望的类型(整数或日期等) )。 验证的第二层可能位于您的服务层中,在该层中您已经使用正确的类型构造了表单对象,但是根据您的应用程序要求,它们的值可能无效。 最常见的无效数据是由于不符合数据库约束,因此无法持久保存。 我没有在上面提供有关验证的示例,但是您可以轻松地改进Servlet并自己进一步进行研究。
我想再提一提。 那里有许多Java Web框架将很多注意力集中在表单处理上,它们应该可以帮助您以更少的重复代码轻松地开发应用程序。 通常使用非常具体的编程模型和样式来完成此工作,在许多情况下,这些模型和样式可以使您避免完全使用HttpServletRequest对象。 所有这些都是好的(假设框架是一种高质量的框架),但是请记住,在大多数情况下,当出现问题时,大多数情况是在框架特定层,甚至更有可能是您自己的使用框架的代码。 然后,您将花费大部分调试时间来学习特定于框架的领域,而不是Servlet规范层。
就我的示例目的而言,我试图仅关注EE API,所以我将远离标准API之外的任何其他框架。 如果您是初学者,我强烈建议您学习Servlet API并了解如何处理表单,这使您对Web应用程序中数据的产生方式有了更扎实的了解。 如果进一步研究Java EE堆栈,实际上它已经有了一个称为EE 6标准一部分的称为JSF的框架。 它的设计是帮助将网页构建为组件模型; 它使您可以捕获表单数据并以更加平滑和集成的方式自动绑定到Bean对象。 JSF值得在以后的帖子中使用自己的主题。
翻译自: https://www.javacodegeeks.com/2015/01/ee-servlet-3-simple-form-processing.html