构建基于MVC模式的框架,必须要满足MVC模式的结构要求。下面我们就以用户登录的业务为例,按照MVC模式进行程序设计。使用MVC框架开发登录程序的结构如图所示。
如果希望按照图所示的程序结构实现登录功能,需要哪些步骤呢?
可参考的步骤如下。
(1)将所有的请求发送到控制器(基于Servlet API实现),并且系统中最好只有一个控制器负责接收请求。
(2)定义一个Action接口,用于代表请求的处理,并实现具体请求的处理,如登录。
(3)控制器根据请求的路径判断由哪个Action执行操作。
(4) Action调用模型,完成业务操作,获取操作的结果,最后将结果返回给视图(页面)。
具体代码参考如下:1) ===============Action接口======================
package com.obtk.actions;
public interface Action {
String SUCCESS="success";
String INPUT="input";
/**
* 处理请求
* @return
*/
String excute();
}
2) =============一般父类ActionSupport===================
package com.obtk.actions;
public class ActionSupport implements Action {
public String excute() {
return this.SUCCESS;
}
}
3) ============后端控制器LoginAction=====================
package com.obtk.actions;
public class LoginAction extends ActionSupport {
private String userName;
private String passWord;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public String excute() {
if(userName.equals("jack") && passWord.equals("123")){
return SUCCESS;
}else{
return "input";
}
}
}
<!DOCTYPE mystruts[
<!ELEMENT mystruts (package)>
<!ELEMENT package (action*)>
<!ELEMENT action (result*)>
<!ELEMENT result (#PCDATA)>
<!ATTLIST action name CDATA #REQUIRED
class CDATA #REQUIRED>
<!ATTLIST result name CDATA #IMPLIED
redirect (true|false) "false">
]>
<mystruts>
<package>
<action name="Login" class="com.obtk.actions.LoginAction">
<result name="success">index.jsp</result>
<result name="input" redirect="true">Login.jsp</result>
</action>
<action name="Register" class="com.obtk.actions.RegisterAction">
<result name="success">Login.jsp</result>
<result name="input" redirect="true">Register.jsp</result>
</action>
</package>
</mystruts>
5) ========================ActionMapping(用于保存mystruts.xml信息)=================
package com.obtk.entity;
import java.util.Map;
public class ActionMapping {
private String actionName;
private String className;
private Map<String, Result> resultMap;
public String getActionName() {
return actionName;
}
public void setActionName(String actionName) {
this.actionName = actionName;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public Map<String, Result> getResultMap() {
return resultMap;
}
public void setResultMap(Map<String, Result> resultMap) {
this.resultMap = resultMap;
}
}
6) ========================Result(也用于保存mystruts.xml信息)=================
package com.obtk.entity;
public class Result {
private String name;
private String isRedirect;
private String url;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIsRedirect() {
return isRedirect;
}
public void setIsRedirect(String isRedirect) {
this.isRedirect = isRedirect;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
7) ================ActionServlet(前端核心控制器)======================
package com.obtk.servlets;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.obtk.entity.ActionMapping;
import com.obtk.entity.Result;
public class ActionServlet extends HttpServlet {
private Map<String, ActionMapping> actionMap=new HashMap<String, ActionMapping>();
public void init(ServletConfig config) throws ServletException {
String configXml=config.getInitParameter("configName");
SAXReader reader=new SAXReader();
InputStream input=this.getClass().getClassLoader().getResourceAsStream(configXml);
try {
//1.获得文档对象
Document doc=reader.read(input);
//2.获得根元素
Element root=doc.getRootElement();
Element packageEle=root.element("package");
List<Element> actionEleList=packageEle.elements("action");
Element actionEle=null;
ActionMapping oneAction=null;
for(int i=0;i<actionEleList.size();i++){
oneAction=new ActionMapping();
actionEle=actionEleList.get(i);
oneAction.setActionName(actionEle.attributeValue("name"));
oneAction.setClassName(actionEle.attributeValue("class"));
List<Element> resultEleList=actionEle.elements("result");
Map<String,Result> resultMap=new HashMap<String, Result>();
Result oneReuslt=null;
Element resultEle=null;
for(int j=0;j<resultEleList.size();j++){
oneReuslt=new Result();
resultEle=resultEleList.get(j);
oneReuslt.setName(resultEle.attributeValue("name"));
oneReuslt.setIsRedirect(resultEle.attributeValue("redirect"));
oneReuslt.setUrl(resultEle.getText());
resultMap.put(oneReuslt.getName(), oneReuslt);
}
oneAction.setResultMap(resultMap);
actionMap.put(oneAction.getActionName(), oneAction);
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String requestUrl=request.getRequestURI();
System.out.println("url:"+requestUrl);
///mystruts/Login.do 得到action名称
String actionName=requestUrl.substring(requestUrl.lastIndexOf('/')+1, requestUrl.lastIndexOf('.'));
System.out.println("action:"+actionName);
//获得某个action的配置
ActionMapping theMapp=actionMap.get(actionName);
//得到类的具体路径
String claName=theMapp.getClassName();
try {
Class theCla=Class.forName(claName);
Object theObj=theCla.newInstance();
//获得所有表单名称
Enumeration<String> params=request.getParameterNames();
//通过反射执行类的set方法,设置表单参数
setParamValues(theCla,theObj,params,request);
//得到处理业务逻辑的方法对象
Method finalMethod=theCla.getDeclaredMethod("excute", null);
//执行方法,返回要跳转的地址
String url=(String)finalMethod.invoke(theObj, null);
Map<String, Result> resultMap=theMapp.getResultMap();
Result theResult=resultMap.get(url); //从map对象里面找到最终要跳转的url
//找到要跳转的具体jsp
String jspName=theResult.getUrl();
request.getRequestDispatcher(jspName).forward(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 通过反射设置表单参数值
* @param theCla
* @param theObj
* @param params
* @param request
*/
void setParamValues(Class theCla,Object theObj,Enumeration<String> params,HttpServletRequest request){
String theParam="";
Method theSetMeth=null;
String methName="";
while(params.hasMoreElements()){
theParam=params.nextElement();
methName="set"+theParam.substring(0, 1).toUpperCase()+theParam.substring(1);
try {
theSetMeth=theCla.getDeclaredMethod(methName, new Class[]{String.class});
theSetMeth.invoke(theObj, request.getParameter(theParam));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
8) ================web.xml=======================
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>ActionServlet</servlet-name>
<servlet-class>com.obtk.servlets.ActionServlet</servlet-class>
<init-param>
<param-name>configName</param-name>
<param-value>config/mystruts.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ActionServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>Login.jsp</welcome-file>
</welcome-file-list>
</web-app>
9) =======================Login.jsp================
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>登录</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<style type="text/css">
#show{ border: 2px solid blue; width:400px;}
#err{ color: red;}
</style>
</head>
<body>
<div id="show">
<form action="Login.do" method="post">
<div id="err">${requestScope.errMsg }</div>
<table border="1px" cellpadding="0">
<tr><td>请输入用户名:</td><td><input type="text" name="userName" /></td></tr>
<tr><td>请输入密码:</td><td><input type="password" name="passWord" /></td></tr>
<tr><td colspan="2"><input type="submit" value="提交" /></td></tr>
</table>
</form>
</div>
</body>
</html>
自己跑一下吧,觉得对您有帮助,请点一个赞!!