先看MVC模式流程图(其实MVC设计模式就是java中的model2。):
就像图上所标识的C层主要是Servlet层控制页面跳转,M层就是具体的业务处理逻辑,而JSP就是所谓的V层。MVC是有别于我们所说的三层,我们平常所说的三层是UI层、BLL层、DAL层,具体的区别如图:
从图上能看出来,JSP和Servlet构成了UI层,而Model层分成了BLL层和DAL层(也就是业务逻辑和数据持久层)。
从理论上认清了MVC设计模式之后,下面开始动手敲一个MVC设计模式示例代码:
JSP索引页面index.jsp:
<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> <!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=GB18030"> <title>Insert title here</title> </head> <body> <form action="servlet/addUser.action" method="post"> 姓名:<input type="text" name="username" > <input type="submit" value="提交"> </form> </body> </html>
业务逻辑代码UserManager:
package com.bjpowernode.servlet;
import java.util.ArrayList;
import java.util.List;
public class UserManager {
public void addUser(String username){
System.out.println("UserManager.addUsre()--->username:"+username);
}
public void delUser(String username){
System.out.println("UserManager.delUser()--->username:"+username);
}
public void modifyUser(String username){
System.out.println("UserManager.modifyUser()--->username"+username);
}
public List queryUser(String username){
System.out.println("UserManager.queryUser()--->username"+username);
List userList=new ArrayList();
userList.add("a");
userList.add("b");
userList.add("c");
return userList;
}
}
Servlet控制代码:
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("request="+requestURI);
String path=requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf("."));
System.out.println("path="+path);
String username=request.getParameter("username");
UserManager userManager=new UserManager();
//userManager.addUser(username);
String forward="";
if("/servlet/delUser".equals(path)){
userManager.delUser(username);
forward="/del_success.jsp";
}else if("/servlet/addUser".equals(path)){
userManager.addUser(username);
forward="/add_success.jsp";
}else if("/servlet/modifyUser".equals(path)){
userManager.modifyUser(username);
forward="/modify_success.jsp";
}else if("/servlet/queryUser".equals(path)){
List userList=userManager.queryUser(username);
request.setAttribute("userList", userList);
forward="/query_success.jsp";
}else{
throw new RuntimeException("请求失败");
}
request.getRequestDispatcher(forward).forward(request, response);
}
这个servlet代码主要实现的功能判断是那个页面请求服务器做那些操作,之后调用业务逻辑实现相应业务操作。
配置Servlet:
<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>test_Servlet</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>TestServlet</servlet-name> <servlet-class>com.cjq.servlet.TestServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>TestServlet</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> </web-app>
输出结果:
通过上面的示例已经对MVC设计模式有了初步的认识,其实这个示例是对Struts框架学习的基础,只有弄清楚了这个实例才能弄清楚Struts框架的实现原理和Struts框架使用。
那么我们怎么才能通过这个示例引入Struts框架呢?这个问题从IF-Eles开始。
首先我们看到了TestServlet中出现了许多if-else语句,这样是非常不稳定的,这样的程序是非常不灵活的,以后如果有变化,那么维护是非常差的;而且我们在if-else中出现了大量的字符串,这样在coding的时候会出现写错,这样无形中给调试带来了麻烦。所以去掉if-else成了我们重构的第一步,也是我们进行Struts框架学习的第一步。因为在TestServlet中出现了If-Else语句块,所以让程序变得不再灵活,让应付需求变化时变得笨拙。所以就承接上篇文章来重构一下TestServlet代码,主要是用继承多态来进一步对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("request="+requestURI);
String path=requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf("."));
System.out.println("path="+path);
String username=request.getParameter("username");
UserManager userManager=new UserManager();
//userManager.addUser(username);
String forward="";
if("/servlet/delUser".equals(path)){
userManager.delUser(username);
forward="/del_success.jsp";
}else if("/servlet/addUser".equals(path)){
userManager.addUser(username);
forward="/add_success.jsp";
}else if("/servlet/modifyUser".equals(path)){
userManager.modifyUser(username);
forward="/modify_success.jsp";
}else if("/servlet/queryUser".equals(path)){
List userList=userManager.queryUser(username);
request.setAttribute("userList", userList);
forward="/query_success.jsp";
}else{
throw new RuntimeException("请求失败");
}
request.getRequestDispatcher(forward).forward(request, response);
}
}
首先我们看到了在每个语句块中都出现了给forward赋值,其实也就是给页面跳转的路径赋值,针对每个请求路径判断来赋值跳转路径。另外每个IF-Else语句块中都有业务处理,我们要把这些业务处理分别放到类里面,让职责更加单
一,这样更加符合面向对象的思路。
就从这里我们开始重构,我们可以将这个跳转路径和业务逻辑封装起来。
既然封装,那么我们就抽象出来一个借口,主要完成一个方法,这个方法主要的功能就是要完成业务逻辑封装和路径跳转的返回。随后建立四个类,主要实现相应的增删改查的业务处理和处理之后的跳转路径返回。
代码如下:
接口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");
UserManager userManager=new UserManager();
userManager.addUser(username);
return "/add_success.jsp";
}
}
删除用户实现类:
package com.bjpowernode.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DelUserAction implements Action {
public String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String username=request.getParameter("username");
UserManager userManager=new UserManager();
userManager.delUser(username);
return "/del_success.jsp";
}
}
更新用户实现类:
package com.bjpowernode.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ModifyUserAction implements Action {
@Override
public String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String username=request.getParameter("username");
UserManager userManager=new UserManager();
userManager.modifyUser(username);
return "/modify_success.jsp";
}
}
查询用户实现类:
package com.bjpowernode.servlet;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class QueryUserAction implements Action {
@Override
public String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String username=request.getParameter("username");
UserManager userManager=new UserManager();
List userList=userManager.queryUser(username);
request.setAttribute("userList", userList);
return "/query_success.jsp";
}
}
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("request="+requestURI);
String path=requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf("."));
System.out.println("path="+path);
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 ModifyUserAction();
}else if("/servlet/queryUser".equals(path)){
action=new QueryUserAction();
}else{
throw new RuntimeException("请求失败");
}
String forward=null;
try{
forward=action.execute(request, response);
}catch(Exception e){
e.printStackTrace();
}
request.getRequestDispatcher(forward).forward(request, response);
}
}
运行结果:
这样TestServlet类虽然没有彻底去掉If-Else,但是这样的代码变得更加简练,利用多肽实现业务逻辑处理和路径跳转返回。职责更加清晰,让维护变得更加轻松。
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("request="+requestURI);
String path=requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf("."));
System.out.println("path="+path);
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 ModifyUserAction();
}else if("/servlet/queryUser".equals(path)){
action=new QueryUserAction();
}else{
throw new RuntimeException("请求失败");
}
String forward=null;
try{
forward=action.execute(request, response);
}catch(Exception e){
e.printStackTrace();
}
request.getRequestDispatcher(forward).forward(request, response);
}
}
解决字符串问题,当然就要用到配置文件了,用到配置文件就要有用来读取配置文件的相关的类和方法,这里就用dom4j中的类来读取配置文件,这里的配置文件的书写是有点逻辑上的难度的。
我们来看TestServlet中的代码,我们要在这个testservlet中实现读取配置文件和path比较,还有利用多肽实例化相应的实现类,最后通过实例化的实现类的方法来返回跳转路径,最终跳转到相应的页面。
所以我们的配置文件就要不仅配上testservlet中出现的字符串,还要配置相应的Action接口的实现类(我们可以利用反射来实例化该类的对象,进而使用这个类的所有属性和方法),另外还有跳转路径字符串。这样我们的配置文件就变成了如下代码所示:
<?xml version="1.0" encoding="UTF-8"?>
<action-config>
<action path="/servlet/delUser" type="com.cjq.servlet.DelUserAction">
<forward name="success">/del_success.jsp</forward>
<forward name="error">/del_error.jsp</forward>
</action>
<action path="/servlet/addUser" type="com.cjq.servlet.AddUserAction">
<forward name="success">/add_success.jsp</forward>
<forward name="error">/add_error.jsp</forward>
</action>
<action path="/servlet/modifyUser" type="com.cjq.servlet.ModifyUserAction">
<forward name="success">/modify_success.jsp</forward>
<forward name="error">/modify_error.jsp</forward>
</action>
<action path="/servlet/queryUser" type="com.cjq.servlet.QueryUserAction">
<forward name="success">/query_success.jsp</forward>
<forward name="error">/query_error.jsp</forward>
</action>
</action-config>
我们有了配置文件之后就要想法通过相关类读取,并且实现相应的功能。所以这里用dom4j来读取完成。其实如果能把这个逻辑捋顺之后就能发现,其实懂我们利用dom4j读取完配置文件的时候,我们是取得的是一个配套的匹配路径字符串、相应业务逻辑类还有处理业务逻辑之后跳转页面路径字符串。这样我们就能直截了当的去掉了if-else。(这里可能逻辑上会出现一些困难,但是看到下面的重构之后的testservlet中的代码和读取配置文件之后的代码就会一目了然)。
现在等待解决的问题就是我们要把从配置文件取得的一整套内容放到那里,当然这是毋庸置疑的要放到类中。所以我们就建立一个ActionMapping类来放我们的那一整套内容。
ActionMapping中的代码如下:
package com.bjpowernode.servlet;
import java.util.Map;
public class ActionMapping {
private String path;
private Object type;
private Map forwardMap;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public Object getType() {
return type;
}
public void setType(Object type) {
this.type = type;
}
public Map getForwardMap() {
return forwardMap;
}
public void setForwardMap(Map forwardMap) {
this.forwardMap = forwardMap;
}
}
现在ActionMapping类已经有了,剩下的工作就是要利用dom4j来读取配置文件类,具体代码如下:
package com.bjpowernode.servlet;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class XmlConfigReader {
private static XmlConfigReader instance=new XmlConfigReader();
ActionMapping actionMapping=new ActionMapping();
private Document doc;
private Map actionMap=new HashMap();
private XmlConfigReader(){
try {
SAXReader reader=new SAXReader();
InputStream in=Thread.currentThread().getContextClassLoader().getResourceAsStream("action_config.xml");
doc=reader.read(in);
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public ActionMapping getActionMapping(String path){
synchronized(this){
Object type=null;
/*if(action.containsKey(path)){
type=action.get(path);
}*/
Element eltAction = (Element)doc.selectObject("//action[@path=\"" + path + "\"]");
try{
type=Class.forName(eltAction.attributeValue("type")).newInstance();
}catch(Exception e){
e.printStackTrace();
}
Element eltForwards = eltAction.element("forward");
for (Iterator iter = eltForwards.elementIterator(); iter.hasNext();) {
Element eltForward = (Element) iter.next();
actionMap.put( eltForward.attributeValue("name"),eltForward.getTextTrim());
}
actionMapping.setPath(path);
actionMapping.setType(type);
actionMapping.setForwardMap(actionMap);
return actionMapping;
}
}
public static synchronized XmlConfigReader getInstance(){
return instance;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ActionMapping actionMapping=XmlConfigReader.getInstance().getActionMapping("/servlet/delUser");
System.out.println(actionMapping.getPath());
System.out.println(actionMapping.getType());
System.out.println(actionMapping.getForwardMap().toString());
}
}
我们通过返回ActionMapping来动态创建出action相应的实现类,进而完成业务逻辑和页面跳转,重构之后的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("request="+requestURI);
String path=requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf("."));
System.out.println("path="+path);
String forward="";
ActionMapping actionMapping=XmlConfigReader.getInstance().getActionMapping(path);
Action action=(Action)actionMapping.getType();
try {
forward=action.execute(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
request.getRequestDispatcher(forward).forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
我们可以清晰的看到if-else已经没有了,字符串也已经没有了。通过这篇文章对if-else还有字符串问题的解决,又一次重构了testservlet代码,程序相对灵活许多。通过这一次的重构,我们已经看到了struts框架的雏形,
# struts
# mvc
# struct
# mvc的详解
# 彻底掌握struts
# Java框架Struts2实现图片上传功能
# Java框架学习Struts2复选框实例代码
# struts2标签总结_动力节点Java学院整理
# Struts1之url截取_动力节点Java学院整理
# struts1之ActionServlet详解_动力节点Java学院整理
# Struts1教程之ActionMapping_动力节点Java学院整理
# java struts2框架简介
# Java struts2 package元素配置及实例解析
# 配置文件
# 跳转
# 重构
# 出现了
# 成了
# 就能
# 我们可以
# 要把
# 看到了
# 变得更加
# 弄清楚
# 图上
# 主要是
# 的是
# 这是
# 没有了
# 就会
# 都有
# 就像
# 要有
相关文章:
微网站制作教程,我微信里的网站怎么才能复制到浏览器里?
如何选择香港主机高效搭建外贸独立站?
我的世界制作壁纸网站下载,手机怎么换我的世界壁纸?
如何通过wdcp面板快速创建网站?
太平洋网站制作公司,网络用语太平洋是什么意思?
公司网站制作需要多少钱,找人做公司网站需要多少钱?
建站主机选哪种环境更利于SEO优化?
大型企业网站制作流程,做网站需要注册公司吗?
如何在腾讯云免费申请建站?
javascript基本数据类型及类型检测常用方法小结
如何在IIS7中新建站点?详细步骤解析
建站中国必看指南:CMS建站系统+手机网站搭建核心技巧解析
微信h5制作网站有哪些,免费微信H5页面制作工具?
如何高效配置香港服务器实现快速建站?
家庭建站与云服务器建站,如何选择更优?
网站app免费制作软件,能免费看各大网站视频的手机app?
如何在橙子建站上传落地页?操作指南详解
网站制作和推广的区别,想自己建立一个网站做推广,有什么快捷方法马上做好一个网站?
php json中文编码为null的解决办法
制作网站的基本流程,设计网站的软件是什么?
Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解
定制建站价位费用解析与套餐推荐全攻略
如何在VPS电脑上快速搭建网站?
青岛网站建设如何选择本地服务器?
怎么用手机制作网站链接,dw怎么把手机适应页面变成网页?
如何撰写建站申请书?关键要点有哪些?
宝塔建站助手安装配置与建站模板使用全流程解析
免费网站制作appp,免费制作app哪个平台好?
网页设计与网站制作内容,怎样注册网站?
如何在阿里云部署织梦网站?
如何选择适配移动端的WAP自助建站平台?
如何在宝塔面板中创建新站点?
如何确保西部建站助手FTP传输的安全性?
潮流网站制作头像软件下载,适合母子的网名有哪些?
php8.4新语法match怎么用_php8.4match表达式替代switch【方法】
清单制作人网站有哪些,近日“兴风作浪的姑奶奶”引起很多人的关注这是什么事情?
招商网站制作流程,网站招商广告语?
香港服务器WordPress建站指南:SEO优化与高效部署策略
建站主机选哪家性价比最高?
如何优化Golang Web性能_Golang HTTP服务器性能提升方法
交易网站制作流程,我想开通一个网站,注册一个交易网址,需要那些手续?
网站制作大概多少钱一个,做一个平台网站大概多少钱?
教学网站制作软件,学习*后期制作的网站有哪些?
个人网站制作流程图片大全,个人网站如何注销?
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
如何在宝塔面板创建新站点?
建站之星伪静态规则如何正确配置?
网站微信制作软件,如何制作微信链接?
宝塔面板创建网站无法访问?如何快速排查修复?
如何快速完成中国万网建站详细流程?
*请认真填写需求信息,我们会在24小时内与您取得联系。