前端控制器模式的定义是“提供集中化的请求处理机制,使所有请求都由一个处理器处理”。该处理器可以进行认证、授权、日志记录或跟踪请求,然后将请求传递给相应的处理器。

使用场景:

  • 当你想控制页面流和导航时。
  • 当你想访问和管理数据模型时。
  • 当你想处理业务逻辑时。

优点:

  • 它减少了JSP页面中代码的重复,尤其是在多个资源需要相同处理的情况下。
  • 它更有效地维护和控制Web应用程序。
  • 对于两层架构的Web应用程序,推荐使用前端控制器来处理用户请求。

前端控制器模式的UML:

12-1.png

前端控制器模式的实现:

步骤 1:

创建一个Login.html网页。

<!DOCTYPE html> 
<html> 
<head> 
<title>Login page</title> 
</head> 
<body style="color:green;"> 
<h1 style="font-family:Comic Sans Ms;text-align:center;font-size:20pt;color:#00FF00;"> 
Login Page 
</h1> 
<form method="POST" action="FrontControllerServlet" onsubmit="return checkForm(this);"> 
<p>Username: <input type="text" name="username"></p> 
<p>Password: <input type="password" name="pwd1"></p> 
<p>Confirm Password: <input type="password" name="pwd2"></p> 
<p><input type="submit" value="Login"></p> 
</form> 
<script type="text/javascript"> 
function checkForm(form) { 
    if(form.username.value == "") { 
        alert("Error: Username cannot be blank!"); 
        form.username.focus(); 
        return false; 
    } 
    re = /^\w+$/; 
    if(!re.test(form.username.value)) { 
        alert("Error: Username must contain only letters, numbers and underscores!"); 
        form.username.focus(); 
        return false; 
    } 
    if(form.pwd1.value != "" && form.pwd1.value == form.pwd2.value) { 
        if(form.pwd1.value.length < 6) { 
            alert("Error: Password must contain at least six characters!"); 
            form.pwd1.focus(); 
            return false; 
        } 
        if(form.pwd1.value == form.username.value) { 
            alert("Error: Password must be different from Username!"); 
            form.pwd1.focus(); 
            return false; 
        } 
        re = /[0-9]/; 
        if(!re.test(form.pwd1.value)) { 
            alert("Error: password must contain at least one number (0-9)!"); 
            form.pwd1.focus(); 
            return false; 
        } 
        re = /[a-z]/; 
        if(!re.test(form.pwd1.value)) { 
            alert("Error: password must contain at least one lowercase letter (a-z)!"); 
            form.pwd1.focus(); 
            return false; 
        } 
        re = /[A-Z]/; 
        if(!re.test(form.pwd1.value)) { 
            alert("Error: password must contain at least one uppercase letter (A-Z)!"); 
            form.pwd1.focus(); 
            return false; 
        } 
    } else { 
        alert("Error: Please check that you've entered and confirmed your password!"); 
        form.pwd1.focus(); 
        return false; 
    } 
    return true; 
} 
</script> 
</body> 
</html>

步骤 2:

创建一个FrontControllerServlet.java类,它是一个Servlet,也可以是一个JSP页面。

package controller;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class FrontControllerServlet
 */
@WebServlet("/FrontControllerServlet")
public class FrontControllerServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
        response.setContentType("text/html");  
        PrintWriter out = response.getWriter();  
         
        String username = request.getParameter("username"); 
        String password = request.getParameter("pwd2"); 
         
        if (password.equals("Ashwani1987")) { 
            RequestDispatcher rd = request.getRequestDispatcher("/Success.jsp"); 
            rd.forward(request, response); 
        } else { 
            RequestDispatcher rd = request.getRequestDispatcher("/Error.jsp"); 
            rd.forward(request, response); 
        } 
    }
}

步骤 3:

创建一个Success.jsp页面。

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" 
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Welcome Page</title>
</head>
<body style="background-color: gray;">
<%
    String name = request.getParameter("username");
%>
<b>Welcome,</b> <%= name %> 
</body>
</html>

步骤 4:

创建一个Error.jsp页面。

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" 
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Error Page</title>
</head>
<body style="background-color: olive;">
<b>You have entered wrong username or password!!</b><br>
<a href="Login.html">Back To Home Page</a>
</body>
</html>

步骤 5:

创建一个web.xml文件。

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> 
    <display-name>Front Controller Example</display-name> 
    <welcome-file-list> 
        <welcome-file>Login.html</welcome-file> 
    </welcome-file-list> 
</web-app>

输出:

12-2.png

12-3.png

12-4.png

12-5.png

12-6.png

12-7.png

通过上述实现,我们可以看到前端控制器模式如何集中处理请求并将其分发到相应的处理器,同时减少了代码重复,提高了代码的可维护性。

标签: Design Patterns, Design Patterns教程, 设计模式, 软件设计, 结构型模式, 行为型模式, 单例模式, 工厂模式, 观察者模式, 中介者模式, 访问者模式