感觉这自定义框架真的懵逼…跟着过了一遍,自己又过了1遍,一共看了5次,现在贴出来供参考 - - ,还有给自己以后来看看
下面是大概的流程,做的很简陋包包、拦截器都没有
filter —> 解析配置文件(映射用户请求到action)
—> 将用户提交数据设置到action —> 处理结果集
1、导入struts2core包+dom4j包(用来读取xml配置文件的)
commons-fileupload-1.3.2.jar
commons-io-2.4.jar
commons-lang3-3.4.jar
dom4j-1.6.1.jar
freemarker-2.3.23.jar
javassist-3.20.0-GA.jar
log4j-api-2.7.jar
ognl-3.1.12.jar
struts2-core-2.5.8.jar
2、创建framework(自定义).xml配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<framework>
<action name="hello" class="com.action.HelloAction">
<result>/index.jsp</result>
</action>
<action name="login" class="com.action.LoginAction">
<result>/success.jsp</result>
<result name="login">/login.jsp</result>
</action>
</framework>
3、创建com.core包(Action、Result、ActionMapper类)
1、Action.java
public class Action {
//属性声明
private String name;
private String classurl;
private String method="execute";//默认属性
//这里用map来装result结果集
private Map<String, Result> resultMap=new HashMap<String,Result>();
//构造方法
public Action() {
}
public Action(String name, String classurl) {
super();
this.name = name;
this.classurl = classurl;
}
public Action(String name, String classurl, String method) {
super();
this.name = name;
this.classurl = classurl;
this.method = method;
}
//get、set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClassurl() {
return classurl;
}
public void setClassurl(String classurl) {
this.classurl = classurl;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public Map<String, Result> getResultMap() {
return resultMap;
}
public void setResultMap(Map<String, Result> resultMap) {
this.resultMap = resultMap;
}
}
2、Result.java
public class Result {
//属性声明
private String name="success";
private String type="dispatcher";//默认属性
private String location;
//构造方法
public Result() {
}
public Result(String location) {
super();
this.location = location;
}
public Result(String type, String location) {
super();
this.type = type;
this.location = location;
}
public Result(String name, String type, String location) {
this.name = name;
this.type = type;
this.location = location;
}
//get、set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
3、ActionMapper.java(这里用dom4j读取文件)
public class ActionMapper {
//Action容器
public static Map<String, Action> actionMap=new HashMap<String,Action>();
//解析配置文件
public static void Parser() throws DocumentException{
//读取配置文件framework.xml
InputStream inputStream=ActionMapper.class.getClassLoader().getResourceAsStream("framework.xml");
Document document=new SAXReader().read(inputStream);
//获取根元素对象
Element root=document.getRootElement();
//System.out.println(root.getName());
//获取action对象
List<Element> listaction=root.elements();
for (Element itemaction : listaction) {
Action action=new Action();
//获取action属性
action.setName(itemaction.attributeValue("name"));
action.setClassurl(itemaction.attributeValue("class"));
String method=itemaction.attributeValue("method");
if (method!=null) {
action.setMethod(method);
}
//获取result对象
List<Element> listresult=itemaction.elements();
for (Element itemresult : listresult) {
Result result=new Result();
//获取result属性
String nameresult=itemresult.attributeValue("name");
if (nameresult!=null) {
result.setName(nameresult);
}
String typeresult=itemresult.attributeValue("type");
if (typeresult!=null) {
result.setType(typeresult);
}
result.setLocation(itemresult.getStringValue());
//将result对象添加到action对象
action.getResultMap().put(result.getName(), result);
}
//将action对象添加到actionMap对象
actionMap.put(action.getName(), action);
}
}
}
4、创建com.filter包(CoreFilter类)
1、CoreFilter.java(这里是重点核心,很难捉摸T.T)
public class CoreFilter implements Filter{
@Override
public void destroy() {
// TODO 自动生成的方法存根
}
@Override
public void init(FilterConfig arg0) throws ServletException {
try {
// 解析配置文件放到这里(该方法只执行一次)
ActionMapper.Parser();
} catch (DocumentException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
//处理事务都在doFilter里
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest httprequst=(HttpServletRequest) request;
HttpServletResponse httpresponse=(HttpServletResponse) response;
//我瞎设置的转码,目前只能传递常规字符串
httprequst.setCharacterEncoding("utf-8");
httpresponse.setCharacterEncoding("utf-8");
//下面把大概的5个步骤分开为单独的方法来吃
//1、将请求映射到action
Action targetAction=reqToAction(httprequst);
if (targetAction==null) {
//如果不是action请求就跳过
filterChain.doFilter(request, response);
return ;
}
//System.out.println(targetAction.getName()+"---"+targetAction.getClass());
try {
//2、创建action
Object proxyAction=createProxyAction(targetAction.getClassurl());
//3、将用户提交的属性设置到action上
setProperty(httprequst, proxyAction);
//4、执行action
String resultName=execute(proxyAction,targetAction.getMethod());
//5、处理result
Result result=targetAction.getResultMap().get(resultName);
resultExecute(httprequst,httpresponse,result,proxyAction);
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
//将请求映射到action
public Action reqToAction(HttpServletRequest httprequest){
//获取URL传递的请求名
String path=httprequest.getRequestURI();
if (!path.endsWith(".action")) {//测试此字符串是否以指定的后缀结尾。
return null;
}
//System.out.println(path.toString());
String reqName=path.substring(path.lastIndexOf("/")+1,path.lastIndexOf("."));//截取请求名
//System.out.println(reqName);
return ActionMapper.actionMap.get(reqName);
}
//创建action
public Object createProxyAction(String className) throws Exception {
Class clzz=Class.forName(className);
return clzz.newInstance();
}
//将用户提交的属性设置到action上
public void setProperty(HttpServletRequest httprequst,Object action) throws Exception {
//创建class
Class clzz=action.getClass();
Map parameterMap=httprequst.getParameterMap();
for (Iterator iterator = parameterMap.keySet().iterator(); iterator.hasNext();) {
Object key=iterator.next();
//根据提交参数去找field
Field field=clzz.getDeclaredField(key.toString());//返回此类中指定字段的对象
if (field==null) {
continue;
}
field.setAccessible(true);
field.set(action, httprequst.getParameter(key.toString()));
//System.out.println(key+"-----"+httprequst.getParameter(key.toString()));
}
}
//执行action
private String execute(Object proxyAction, String methodName) throws Exception{
Class clzz=proxyAction.getClass();
Method method=clzz.getDeclaredMethod(methodName);
return (String) method.invoke(proxyAction);
}
//处理result
private void resultExecute(HttpServletRequest httprequst, HttpServletResponse httpresponse, Result result,
Object proxyAction) throws Exception {
if (result.getType().equals("redirect")) {
httpresponse.sendRedirect(result.getLocation());
return;
}
//将action的属性值设置到httprequst的attribute中
Class clzz=proxyAction.getClass();
Field[] fields=clzz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
httprequst.setAttribute(field.getName(), field.get(proxyAction));
field.setAccessible(false);
}
httprequst.getRequestDispatcher(result.getLocation()).forward(httprequst, httpresponse);
}
}
JSP页面
1、login.jsp
<form action="login.action" method="post">
账号<input type="text" name="name"><br>
密码<input type="text" name="pwd"><br>
<input type="submit" value="登录"><br>
</form>
2、success.jsp
<h1>name:${name}</h1>
age:${pwd}
测试用例LoginAction.java
public class LoginAction extends ActionSupport {
private String name;
private String pwd;
@Override
public String execute() throws Exception {
if (name.equals("admin")&&pwd.equals("000")) {
return SUCCESS;
}
return LOGIN;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
效果图
大概就这样子 ,stuts2告一段落了~