原文: http://zetcode.com/articles/javaservletcheckbox/

在本教程中,我们创建一个经典的 Web 应用,该应用从 HTML 复选框中读取一个值。 表单值通过过滤器类进行验证。 使用 FreeMarker 模板创建视图。 该 Web 应用是使用 Java Servlet 创建的,并部署在 Tomcat 服务器上。

Servlet 是 Java 类,可响应特定类型的网络请求-最常见的是 HTTP 请求。 Servlet 用于实现 Web 应用。 它们在 Tomcat 或 Jetty 之类的 servlet 容器中运行。 在现代 Java Web 开发中,程序员使用在 Servlet 之上构建的框架。

Java 过滤器是一个对象,它对对资源(servlet 或静态内容)的请求,或对资源的响应,或两者都执行过滤任务。 它用于执行认证,审核,日志记录,数据加密或数据验证之类的任务。

FreeMarker 是 Java 编程语言的模板引擎。 模板以 FreeMarker 模板语言(FTL)编写。 在 Web 应用中使用模板来创建 UI。

Apache Tomcat 是由 Apache 软件基金会(ASF)开发的开源 Java Servlet 容器。 它是最受欢迎的 Java Web 服务器。

Bootstrap 是 HTML,CSS 和 JS 框架,用于在 Web 上开发响应式,移动优先项目。 它包含用于印刷,表单,按钮,导航和其他界面组件的 HTML 和 CSS 设计模板,以及可选的 JavaScript 扩展。

应用

以下 Web 应用具有一个简单的 Web 表单,该表单包含一个复选框和一个输入文本。 值将发送到 Web 应用的控制器,该控制器是 Java servlet。 在请求到达控制器之前,将在 Java 过滤器中验证这些值。 最后,这些值显示在 HTML 文件中,该文件是用 FreeMarker 模板构建的。 FreeMarker 将 HTML 与数据结合在一起。

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  5. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6. <modelVersion>4.0.0</modelVersion>
  7. <groupId>com.zetcode</groupId>
  8. <artifactId>FormCheckBox</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>war</packaging>
  11. <name>FormCheckBox</name>
  12. <properties>
  13. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  14. <maven.compiler.source>1.8</maven.compiler.source>
  15. <maven.compiler.target>1.8</maven.compiler.target>
  16. </properties>
  17. <dependencies>
  18. <dependency>
  19. <groupId>javax.servlet</groupId>
  20. <artifactId>javax.servlet-api</artifactId>
  21. <version>3.1.0</version>
  22. <scope>provided</scope>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.freemarker</groupId>
  26. <artifactId>freemarker</artifactId>
  27. <version>2.3.25-incubating</version>
  28. </dependency>
  29. </dependencies>
  30. <build>
  31. <plugins>
  32. <plugin>
  33. <groupId>org.apache.maven.plugins</groupId>
  34. <artifactId>maven-war-plugin</artifactId>
  35. <version>2.3</version>
  36. <configuration>
  37. <failOnMissingWebXml>false</failOnMissingWebXml>
  38. </configuration>
  39. </plugin>
  40. </plugins>
  41. </build>
  42. </project>

javax.servlet-api依赖项是用于构建 Java Servlet 的库。 freemarker工件用于 FreeMarker 模板引擎。 maven-war-plugin收集 Web 应用的所有工件依赖项,类和资源,并将它们打包到 Web 应用存档(WAR)中。

  1. $ tree
  2. .
  3. ├── pom.xml
  4. └── src
  5. ├── main
  6. ├── java
  7. └── com
  8. └── zetcode
  9. ├── filter
  10. └── FormFilter.java
  11. └── web
  12. └── MyController.java
  13. ├── resources
  14. └── webapp
  15. ├── index.html
  16. ├── META-INF
  17. └── context.xml
  18. └── WEB-INF
  19. ├── template
  20. ├── show.ftl
  21. └── unknown.ftl
  22. └── web.xml
  23. └── test
  24. └── java

tree命令显示项目目录结构。

web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
  5. http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
  6. <servlet>
  7. <servlet-name>freemarker</servlet-name>
  8. <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class>
  9. <init-param>
  10. <param-name>TemplatePath</param-name>
  11. <param-value>/WEB-INF/template/</param-value>
  12. </init-param>
  13. <init-param>
  14. <param-name>NoCache</param-name>
  15. <param-value>true</param-value>
  16. </init-param>
  17. <init-param>
  18. <param-name>ResponseCharacterEncoding</param-name>
  19. <param-value>fromTemplate</param-value>
  20. </init-param>
  21. <init-param>
  22. <param-name>ExceptionOnMissingTemplate</param-name>
  23. <param-value>true</param-value>
  24. </init-param>
  25. <init-param>
  26. <param-name>incompatible_improvements</param-name>
  27. <param-value>2.3.25-incubating</param-value>
  28. </init-param>
  29. <init-param>
  30. <param-name>template_exception_handler</param-name>
  31. <param-value>html_debug</param-value>
  32. </init-param>
  33. <init-param>
  34. <param-name>template_update_delay</param-name>
  35. <param-value>0 s</param-value>
  36. </init-param>
  37. <init-param>
  38. <param-name>default_encoding</param-name>
  39. <param-value>UTF-8</param-value>
  40. </init-param>
  41. <init-param>
  42. <param-name>output_encoding</param-name>
  43. <param-value>UTF-8</param-value>
  44. </init-param>
  45. <init-param>
  46. <param-name>locale</param-name>
  47. <param-value>en_US</param-value>
  48. </init-param>
  49. <init-param>
  50. <param-name>number_format</param-name>
  51. <param-value>0.##########</param-value>
  52. </init-param>
  53. <load-on-startup>1</load-on-startup>
  54. </servlet>
  55. <servlet-mapping>
  56. <servlet-name>freemarker</servlet-name>
  57. <url-pattern>*.ftl</url-pattern>
  58. </servlet-mapping>
  59. <security-constraint>
  60. <web-resource-collection>
  61. <web-resource-name>FreeMarker MVC Views</web-resource-name>
  62. <url-pattern>*.ftl</url-pattern>
  63. </web-resource-collection>
  64. <auth-constraint>
  65. </auth-constraint>
  66. </security-constraint>
  67. <session-config>
  68. <session-timeout>
  69. 30
  70. </session-timeout>
  71. </session-config>
  72. </web-app>

web.xml文件中,我们设置了 FreeMarker 模板。 它通过freemarker.ext.servlet.FreemarkerServlet起作用。 模板目录设置为/WEB-INF/template/

context.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Context path="/FormCheckBox"/>

context.xml文件是 Tomcat 的配置文件。 在文件内部,我们设置上下文路径(应用名称)。 该文件位于META-INF子目录中。

index.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Check box</title>
  5. <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  6. <meta charset="UTF-8">
  7. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  8. </head>
  9. <body>
  10. <div class="container">
  11. <div class="form">
  12. <form action="MyController">
  13. <input type="hidden" name="action" value="show">
  14. <div class="form-group">
  15. <label>Name:</label>
  16. <input type="text" name="name" class="form-control">
  17. </div>
  18. <div class="checkbox">
  19. <label><input type="checkbox" name="adult">Adult</label>
  20. </div>
  21. <button type="submit" class="btn btn-default">Submit</button>
  22. </form>
  23. </div>
  24. </div>
  25. </body>
  26. </html>

index.html文件是我们应用的主页。 它包含一个带文本输入和复选框的 HTML 表单。 页面外观是使用 Bootstrap 库创建的。

  1. <input type="hidden" name="action" value="show">

这个隐藏的input标记定义了一个动作参数,该参数在控制器 Servlet 中使用。

FormFilter.java

  1. package com.zetcode.filter;
  2. import java.io.IOException;
  3. import java.util.Map;
  4. import javax.servlet.Filter;
  5. import javax.servlet.FilterChain;
  6. import javax.servlet.FilterConfig;
  7. import javax.servlet.ServletException;
  8. import javax.servlet.ServletRequest;
  9. import javax.servlet.ServletResponse;
  10. import javax.servlet.annotation.WebFilter;
  11. @WebFilter(filterName = "FormFilter", servletNames = {"MyController"})
  12. public class FormFilter implements Filter {
  13. public FormFilter() {
  14. }
  15. @Override
  16. public void doFilter(ServletRequest request, ServletResponse response,
  17. FilterChain chain)
  18. throws IOException, ServletException {
  19. Map<String, String[]> params = request.getParameterMap();
  20. params.keySet().stream().forEach(key -> {
  21. String value = params.get(key)[0];
  22. if (key != null && ! value.trim().isEmpty())
  23. request.setAttribute(key, params.get(key)[0]);
  24. });
  25. chain.doFilter(request, response);
  26. }
  27. @Override
  28. public void destroy() {
  29. }
  30. @Override
  31. public void init(FilterConfig filterConfig) {
  32. }
  33. }

FormFilter在到达MyController Servlet 之前先处理请求。 它从请求中检索所有参数并进行验证。 我们需要确保值不为 null 或为空。

  1. Map<String, String[]> params = request.getParameterMap();

我们使用getParameterMap()方法从请求中获取所有参数。

  1. params.keySet().stream().forEach(key -> {
  2. String value = params.get(key)[0];
  3. if (key != null && ! value.trim().isEmpty())
  4. request.setAttribute(key, params.get(key)[0]);
  5. });

我们需要将请求参数变成请求属性。 如果请求的属性不为null或为空,则将其设置为该属性。 这些属性可供 FreeMarker 模板引擎处理。

  1. chain.doFilter(request, response);

请求继续到映射的 servlet。

MyController.java

  1. package com.zetcode.web;
  2. import com.zetcode.util.Validate;
  3. import java.io.IOException;
  4. import javax.servlet.RequestDispatcher;
  5. import javax.servlet.ServletException;
  6. import javax.servlet.annotation.WebServlet;
  7. import javax.servlet.http.HttpServlet;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10. @WebServlet(name = "MyController", urlPatterns = {"/MyController"})
  11. public class MyController extends HttpServlet {
  12. private static final String SHOW_ACTION = "show";
  13. private static final String SHOW_VIEW = "show.ftl";
  14. private static final String UNKNOW_VIEW = "unknown.ftl";
  15. @Override
  16. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  17. throws ServletException, IOException {
  18. String action = request.getParameter("action");
  19. String path = UNKNOW_VIEW;
  20. if (SHOW_ACTION.equals(action)) {
  21. path = SHOW_VIEW;
  22. }
  23. response.setContentType("text/html;charset=UTF-8");
  24. RequestDispatcher dispatcher = request.getRequestDispatcher(path);
  25. dispatcher.forward(request, response);
  26. }
  27. }

MyController Servlet 将处理由过滤器处理的请求。

  1. @WebServlet(name = "MyController", urlPatterns = {"/MyController"})

@WebServlet批注将具有MyController URL 模式的请求映射到MyController servlet。

  1. @Override
  2. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  3. throws ServletException, IOException {

该请求是一个 GET 请求,因此我们以doGet()方法为其提供服务。

  1. response.setContentType("text/html;charset=UTF-8");

使用setContentType()方法,我们设置内容类型(HTML)和字符集。

  1. RequestDispatcher dispatcher = request.getRequestDispatcher(path);
  2. dispatcher.forward(request, response);

使用RequestDispatcher,我们将请求转发到视图。 该视图是一个 FreeMarker 模板,该模板已转换为 HTML 页面。

show.ftl

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Show page</title>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. </head>
  8. <body>
  9. <#if adult??>
  10. <p>${name!"Guest"} is adult</p>
  11. <#else>
  12. <p>${name!"Guest"} is minor</p>
  13. </#if>
  14. </body>
  15. </html>

这是show.ftl模板。 两个属性传递给模板:adultname。 FreeMarker 使用${}语法来获取请求属性的值。

  1. <#if adult??>

使用#if指令,我们检查adult属性是否已设置。 ??判断左侧操作数的值是否丢失。

  1. <p>${name!"Guest"} is adult</p>

缺少值时,!用于提供默认值。 (请记住,我们没有为空或null的参数设置属性。)如果设置了name变量,则会显示它;否则,将显示它。 否则,显示"Guest"

unknown.ftl

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Unknow action</title>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. </head>
  8. <body>
  9. <p>Unknown action</p>
  10. </body>
  11. </html>

这是unknown.ftl模板文件。

在本教程中,我们已将数据从 HTML 表单发送到 Java servlet。 该表单包含一个输入标签和一个复选框。 请求参数已在 Java 过滤器中经过验证,并转换为请求属性,并发送到 FreeMarker 模板进行显示。

您可能也对以下相关教程感兴趣: Java RequestDispatcherJava Servlet 图像教程Servlet FreeMarker JdbcTemplate教程在 SpringBoot 中提供图像文件Java 教程jQuery DatePicker教程Stripes 教程