Servlet是如何实现MVC的?
时间:2022-04-27
本文章向大家介绍Servlet是如何实现MVC的?,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Servlet是一种服务器端的编程语言,是J2EE中比较关键的组成部分,Servlet技术的推出,扩展了Java语言在服务器端开发的功能,巩固了Java语言在服务器端开发中的地位,而且现在使用非常广泛的JSP技术也是基于Servlet的原理.
JSP+JavaBeans+Servlet成为实现MVC模式的一种有效的选择。
如果我们要实现一个对用户的增删改查,并且要求符合对扩展开发,对修改关闭的原则,该怎么做呢?
首先,这是我们的类图以及类与类之间调用的时序图。
根据UML图来实现代码:
TestServlet类
package com.bjpowernode.servlet;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String requestURI = request.getRequestURI();
System.out.println("requestURI=" + requestURI);
String path = requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf("."));
System.out.println("path = " +path);
String username = request.getParameter("username");
Action action = null;
if("/servlet/delUser".equals(path)){
action = new DelUserAction();
}else if("/servlet/addUser".equals(path)){
action = new AddUserAction();
}else if("/servlet/modifyUser".equals(path)){
action = new ModifyAction();
}else if("/servlet/queryUser".equals(path)){
action = new QueryUserAction();
}else{
throw new RuntimeException("请求失败");
}
String forward ="";
try {
forward= action.execute(request, response);
} catch (Exception e) {
e.printStackTrace();
}
request.getRequestDispatcher(forward).forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
抽象接口Action
package com.bjpowernode.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Action {
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception;
}
添加类,这里就只写添加类了,其他类一样
package com.bjpowernode.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class AddUserAction implements Action {
public String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String username = request.getParameter("username");
//int age = Integer.parseInt(request.getParameter("username"));
//String sex = request.getParameter("sex");
//调用业务逻辑
UserManager userManager = new UserManager();
userManager.add(username);
return "/add_success.jsp";
}
}
Web.xml配置
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>com.bjpowernode.servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<!--
<url-pattern>/servlet/TestServlet</url-pattern>
-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
这里我们发现,在testAction类中,用到了大量的if和else,而当我们需要扩展一个上传类的时候,就需要修改if/else,所以,这就不符合对扩展开发,对修改关闭原则,所以,我们需要把这部分提取出来,配置到配置文件里,用反射进行配置。
我们需要先配置配置文件
<action-config>
<action path ="/servlet/delUser" type = "com.bjpowernode.servlet.DelUserAction">
<forward name = "success">del_success.jsp</forward>
<forward name = "error">del_error.jsp</forward>
</action>
<action path ="/servlet/addUser" type = "com.bjpowernode.servlet.AddUserAction">
<forward name = "success">add_success.jsp</forward>
<forward name = "error">add_error.jsp</forward>
</action>
<action path ="/servlet/modifyUser" type = "com.bjpowernode.servlet.ModifyAction">
<forward name = "success">modify_success.jsp</forward>
<forward name = "error">modify_error.jsp</forward>
</action>
<action path ="/servlet/queryUser" type = "com.bjpowernode.servlet.QueryUserAction">
<forward name = "success">query_success.jsp</forward>
<forward name = "error">query_error.jsp</forward>
</action>
</action-config>
需要获取actionMapping对象
ActionMapping{
private String path;
private String type;
Map forwardMap;
}
forwardMap{
key = "success";
value ="/del_success.jsp"
key ="error"
value ="del_error.jsp";
}
Map map = new HashMap();
map.put("/servlet/delUser",actionMapping);
map.put("/servlet/addUser",actionMapping);
map.put("/servlet/modifyUser",actionMapping);
map.put("/servlet/queryUser",actionMapping);
// 如果是删除ActionMapping存储如下:
actionMapping{
path ="/servlet/delUser";
type ="com.bjpowernode.servlet.DelUserAction"
forwardMap{
key ="success",value ="/del_success.jsp"
key ="error",value"/del_error.jsp"
}
}
最后根据获取的对象采用反射来动态实例化Action,达到我们的目的。
String path = "/servlet/delUser";
/根据截取的URL请求,到Map中取得本次请求对应的Action
ActionMapping actionMapping =(ActionMapping)map.get(path);
/取得本次请求对应的Action类的完整路径
String type = actionMapping.getType(); //com.bjpowernode.servlet.DelUserAction
// 采用反射动态实例化Action
Action action = (Action)class.forName(type).newInstance();
/动态待用Action中的execute方法
String forward = action.execute(request.response);
//根据路径完成转向
request.getRequestDispatcher(forward).forward(request, response);
这样,我们基本就是实现了对扩展开发,对修改封闭的原则,但是,这仅仅是一个功能我们就需要做这么多事情,写这么多代码,对程序员来说这是一项不小的工作量,那么我们有没有其他的办法让我们的工作量小一点呢?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 二维树状数组-POJ 2155 Matrix
- 浙大版《C语言程序设计(第3版)》题目集 习题10-7 十进制转换二进制
- flink开发过程中遇到的问题集锦
- FLINK实战-使用CEP进行网站监控报警和报警恢复
- 浙大版《C语言程序设计(第3版)》题目集 习题10-8 递归实现顺序输出整数
- 浅谈DAO设计模式(示例)
- 浙大版《C语言程序设计(第3版)》题目集 习题11-1 输出月份英文名
- flink教程-flink 1.11 使用sql将流式数据写入hive
- flink实战-使用广播实现报警阈值动态更新
- 浅谈MVC设计模式(示例)
- flink实战-聊一聊flink中的聚合算子
- 浙大版《C语言程序设计(第3版)》题目集 习题11-2 查找星期
- flink实战-模拟简易双11实时统计大屏
- Android Studio首次运行指南
- PAT (Basic Level) Practice (中文)1047 编程团体赛