我正在设计一个简单的基于Web的应用程序。我是这个基于Web的领域的新手,我需要您提供有关设计模式的建议,例如如何在Servlet之间分配职责,创建新Servlet的标准等。
实际上,我主页上的实体很少,而与每个实体相对应,我们几乎没有添加,编辑和删除等选项。早些时候,我为每个选项使用一个Servlet,例如Servlet1用于添加实体1,Servlet2用于编辑实体1,依此类推,这样我们最终拥有大量的Servlet。
现在,我们正在更改设计。我的问题是,如何正确选择如何选择servlet的责任。每个实体是否应该有一个Servlet,它将处理所有选项并将请求转发到服务层。还是应该为整个页面设置一个servlet,它将处理整个页面请求,然后将其转发到相应的服务层?同样,请求对象是否应该转发到服务层。
有点像样的Web应用程序由多种设计模式组成。我只会提到最重要的那些。
模型视图控制器模式
你要使用的核心(架构)设计模式是Model-View-Controller模式。该控制器是由一个Servlet其中(在)直接创造来表示/使用特定的模型和视图基于该请求。该模型将由Javabean类表示。在包含动作(行为)的业务模型和包含数据(信息)的数据模型中,这通常可以进一步划分。该视图是由具有对(直接访问JSP文件来表示数据)模型由EL(表达式语言)。
然后,根据操作和事件的处理方式而有所不同。最受欢迎的是:
基于请求(动作)的MVC:这是最简单的实现。(业务)模型直接与HttpServletRequest
和HttpServletResponse
对象一起使用。你必须自己(主要)收集,转换和验证请求参数。该视图可以用普通的HTML / CSS / JS
表示,并且不会在请求中保持状态。这就是Spring MVC,Struts
和Stripes
的工作方式。
基于组件的MVC:这很难实现。但是最终你得到了一个更简单的模型和视图,其中所有“原始” Servlet API都被完全抽象了。你不需要自己收集,转换和验证请求参数。所述控制器执行此任务,并设置在所收集的,转换后的和验证请求参数模型。你需要做的就是定义直接与模型属性一起使用的操作方法。该视图是通过“组件”在JSP标记库或依次产生HTML / CSS / JS的XML元素的风味表示。视图的状态在会话中维护后续请求。这对于服务器端转换,验证和值更改事件特别有用。这就是JSF,Wicket和Play的方式!作品。
附带说明,业余学习本地的MVC框架是一个非常不错的学习方法,只要你出于个人/私人目的保留它,我建议你这样做。但是一旦你成为专业人士,那么强烈建议你选择一个现有的框架,而不要重塑自己的框架。学习现有的和完善的框架所需的时间要比自己开发和维护一个健壮的框架花费的时间少。
在下面的详细说明中,我将自己限制为基于请求的MVC,因为它更易于实现。
前控制器模式(调解器模式)
首先,Controller部分应实现Front Controller模式(这是一种专门的Mediator模式)。它应该仅由一个servlet组成,该servlet提供所有请求的集中入口点。它应该创建模型基于由请求,如PATHINFO或servletpath,该方法和/或特定的参数可用信息。该商业模式被称为Action
在下面的HttpServlet
例子。
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Action action = ActionFactory.getAction(request);
String view = action.execute(request, response);
if (view.equals(request.getPathInfo().substring(1)) {
request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response);
}
else {
response.sendRedirect(view); // We'd like to fire redirect in case of a view change as result of the action (PRG pattern).
}
}
catch (Exception e) {
throw new ServletException("Executing action failed.", e);
}
}
执行该操作应返回一些标识符以定位视图。最简单的方法是将其用作JSP
的文件名。将此servlet
映射到特定url-pattern的web.xml
,例如/pages/*,*.do
甚至*.html
。
在前缀模式,例如情况下,/pages/*
你可以然后调用URL就像http://example.com/pages/register,http://example.com/pages/login
等,提供/WEB-INF/register.jsp,/WEB-INF/login.jsp
使用适当的GET和POST行为。然后,如上例所示,可以使用部件register,login
等等request.getPathInfo()
。
当你使用后缀模式,比如*.do,*.html等
等,那么你可以然后调用URL的喜欢http://example.com/register.do,http://example.com/login.do
,等你应该改变此答案中的代码示例(也包括ActionFactory
)来提取register
和login
部分request.getServletPath()
。
策略模式
本Action应遵循的策略模式。需要将其定义为抽象/接口类型,该类型应基于抽象方法的传入参数来完成工作(这与Command模式不同,其中抽象/接口类型应基于在实现的创建过程中传入的参数)。
public interface Action {
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
你可能希望Exception使用像这样的自定义异常进行更具体的说明ActionException。这只是一个基本的启动示例,其余的全由你决定。
这是一个LoginAction(如其名称所示)登录用户的示例。该User本身又一个数据模型。该视图是知道的存在User。
public class LoginAction implements Action {
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userDAO.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user); // Login user.
return "home"; // Redirect to home page.
}
else {
request.setAttribute("error", "Unknown username/password. Please retry."); // Store error message in request scope.
return "login"; // Go back to redisplay login form with error.
}
}
}
工厂方法模式
本ActionFactory应遵循工厂方法模式。基本上,它应该提供一种创建方法,该方法返回抽象/接口类型的具体实现。在这种情况下,它应该Action根据请求提供的信息返回接口的实现。例如,方法和pathinfo(pathinfo是请求URL中上下文和servlet路径之后的部分,不包括查询字符串)。
public static Action getAction(HttpServletRequest request) {
return actions.get(request.getMethod() + request.getPathInfo());
}
该actions反过来应该是一些静态/应用程序范围Map
actions.put("POST/register", new RegisterAction());
actions.put("POST/login", new LoginAction());
actions.put("GET/logout", new LogoutAction());
// ...
或可基于类路径中的属性/ XML配置文件进行配置:(伪)
for (Entry entry : configuration) {
actions.put(entry.getKey(), Class.forName(entry.getValue()).newInstance());
}
或动态地基于对类路径的扫描来实现实现特定接口和/或注释的类:(伪)
for (ClassFile classFile : classpath) {
if (classFile.isInstanceOf(Action.class)) {
actions.put(classFile.getAnnotation("mapping"), classFile.newInstance());
}
}
请记住,在Action没有映射的情况下创建“不执行任何操作” 。让它例如直接返回request.getPathInfo().substring(1)then
。
其他图案
这些是到目前为止的重要模式。
要更进一步,你可以使用Facade模式创建一个Context类,该类依次包装请求和响应对象,并提供几个委托给请求和响应对象的便捷方法,并将其作为参数传递给该Action#execute()方法。这增加了一个额外的抽象层以隐藏原始Servlet API。然后,你基本上应该在每个实现中都以零 import javax.servlet.*
声明结束Action。用JSF术语,这是FacesContext和ExternalContext类的作用。你可以在此答案中找到一个具体示例。
然后是一种情况下的状态模式,你想添加一个额外的抽象层来拆分收集请求参数,转换请求,验证请求,更新模型值和执行操作的任务。用JSF术语,这LifeCycle就是这样做的。
然后,有一个Composite模式用于你要创建基于组件的视图,该视图可以随模型一起附加,并且其行为取决于基于请求的生命周期的状态。用JSF术语UIComponent表示。
通过这种方式,你可以逐步向基于组件的框架发展。
问题内容: 我正在设计一个简单的基于Web的应用程序。我是这个基于Web的领域的新手,我需要您提供有关设计模式的建议,例如应如何在Servlet之间分配职责,创建新Servlet的条件等。 实际上,我主页上的实体很少,而与每个实体相对应,我们几乎没有添加,编辑和删除等选项。之前,我为每个选项使用一个Servlet,例如Servlet1用于添加实体1,Servlet2用于编辑实体1,依此类推,这样我
问题内容: 我有Java swing应用程序。我想转换为基于Web的应用程序。最简单的方法是什么?有没有可用的工具,最好是开放源代码? 问题答案: AjaxSwing是一种运行时工具,需要用于商业用途的服务器许可证。 您可能要尝试Mia Transformer-该网站的部分内容为法语-。他们将Swing Java代码更改为GWT Java代码,然后GWT将其更改为Javascript,然后,如果您
我没有在现实世界的Web项目上工作。在大学里,我们使用Servlets和Spring进行Java Web开发。在这两个项目中,我们都得到了已经配置的web.xml文件,我们只对它们进行了微小的更改。现在我需要从头开始构建一个 Web 应用。我在Eclipse中创建了新的Servlet类,它没有自动创建任何web.xml。然后我用谷歌搜索,我从几个资源中读到,web.xml并不是真正需要的,但是这个
本文向大家介绍基于Spring Boot保护Web应用程序,包括了基于Spring Boot保护Web应用程序的使用技巧和注意事项,需要的朋友参考一下 如果在类路径上添加了Spring Boot Security依赖项,则Spring Boot应用程序会自动为所有HTTP端点提供基本身份验证。端点“/”和“/home”不需要任何身份验证。所有其他端点都需要身份验证。 要将Spring Boot S
是否有工具和行业标准来确保和验证补丁或系统更新的完整性。作为发布过程的一部分,有时我会向基于ColdFusion/HTML/JS的应用程序交付更新集。我的问题是,我是否真的可以对软件包或单个更新进行即时签名,然后在安装之前让ColdFusion/application server自动验证它们。 请注意,有时我需要向单个JS文件提供更新,有时需要向一组ColdFusion、cfc/cfm文件提供更
有没有人有过自动化桌面应用程序(不是web)的经验?我需要一个类似于Appium的解决方案来将它与我的移动自动化集成(用Appium、Java编写)。 我们公司在3个平台上都有一个messenger客户端:Android、iOS和桌面。客户端数据在这些平台之间同步。我们已经有了移动平台的基本自动化(使用Appium)。现在我需要为桌面开发自动化。 我想要一个类似Appium的解决方案,这样就可以很