对于大多数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);
@Override
protected 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();
}
@Override
protected 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