对于struts2的struts.xml中的namespace的懂得
package中的namespace与URL有映射关系的。
引用一个自定义拦截器的小测试testInterceptor作为对namespace的说明,
拦截器类MyInterceptor代码:
package com.struts.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
/*
拦截器可以从AbstractInterceptor继承,又或者直接实现Interceptor接口,
因为AbstractInterceptor是从Interceptor结成的
*/
public class MyInterceptor extends AbstractInterceptor {
//拦截方法
@Override
public String intercept(ActionInvocation arg0) throws Exception {
//**
InterceptorAction ia = (InterceptorAction)arg0.getAction();
System.out.println("拦截器信息:HelloWorld拦截器!");
//执行Action或者执行下一个拦截器
String result = arg0.invoke();
//提示Action执行完毕
System.out.println("拦截器信息:Action执行完毕");
return result;
}
}
Action类InterceptorAction代码:
package com.struts.interceptor;
import java.util.Date;
import com.opensymphony.xwork2.ActionSupport;
public class InterceptorAction extends ActionSupport {
@Override
public String execute() throws Exception {
if(username != null && getPassword1().equals(getPassword2())
&& !getUsername().trim().equals("")) {
System.out.println("Action信息:正在执行Action.....");
return SUCCESS;
} else {
return INPUT;
}
}
private String username;
private String mymsg;
private String password1;
private String password2;
private Date birthday;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getMymsg() {
return mymsg;
}
public void setMymsg(String mymsg) {
this.mymsg = mymsg;
}
public String getPassword1() {
return password1;
}
public void setPassword1(String password1) {
this.password1 = password1;
}
public String getPassword2() {
return password2;
}
public void setPassword2(String password2) {
this.password2 = password2;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
响应页面代码:
interceptor_login.jsp
<%@ page contentType="text/html; charset=utf-8" language="java" %>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>用户注册</title>
<s:head/>
</head>
<body>
<table>
<s:form id="id" action="InterceptorAction">
<s:textfield name="username" label="用户名" />
<!--<s:textarea name="username" label="用户名" />-->
<s:password name="password1" label="密码" />
<s:password name="password2" label="确认密码" />
<s:submit value="注册" />
</s:form>
</table>
</body>
</html>
success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<%
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>My JSP 'success.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
注册成功 <br>
</body>
</html>
下面是的struts.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<!-- 定义包 -->
<package name="interceptor" extends="struts-default" namespace="/">
<!-- 定义拦截器 -->
<interceptors>
<interceptor name="MyInterceptor" class="com.struts.interceptor.MyInterceptor"></interceptor>
</interceptors>
<action name="InterceptorAction" class="com.struts.interceptor.InterceptorAction">
<result name="success">/success.jsp</result>
<!--<result name="input">/success.jsp</result> -->
<!-- 引用默认拦截器 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 引用自定义拦截器 -->
<interceptor-ref name="MyInterceptor"></interceptor-ref>
</action>
</package>
</struts>
直接访问http://localhost:8080/testInterceptor/interceptor_login.jsp,它的执行过程是:页面接收数据后,<s:form id="id" action="InterceptorAction">里面的action会从struts.xml的package找与之相匹配的action。这里只定义了一个package,里面的namespace=“/”(即对应http://localhost:8080/testInterceptor/),找到匹配的action之后,执行对应的Action类,根据Action类return回来的值result返回响应页面success.jsp。成功执行返回success.jsp的URL为http://localhost:8080/testInterceptor/InterceptorAction.
可见设置namespace=“/”对应http://localhost:8080/testInterceptor/。假如namespace=“/admin”,则返回的URL为http://localhost:8080/testInterceptor/admin/Interceptor。
另外,假如struts.xml里面有很多个package,struts的寻找方式是这样的(引自wdl13的http://wdl123.iteye.com/blog/340709):
1.获得请求路径的URI,例如url是:http://server/myapp/path1/path2/path3/test.action
2.首先寻找namespace为/path1/path2/path3的package,如果存在这个package,则在这个package中寻找名字为test的action,若找到则执行,否则报错;如果不存在这个package则转步骤3;
//问题的关键在这里:如果在寻找namespace的时候,没能找到符合的namespace,例如/path1/path2/path3,则一切如wdl123所写的,逐次往上目录当做namespace找,但是一旦存在/path1/path2/path3这样的namespace,那么如果在这个namespace下没能找到test.action,则他不会再逐次往上级目录匹配namespace,而是直接转向了namespace为""的去寻找action。
3.寻找namespace为/path1/path2的package,如果存在这个package,则在这个package中寻找名字为test的action,若找到则执行,否则报错;如果不存在这个package则转步骤4;
4.寻找namespace为/path1的package,如果存在这个package,则在这个package中寻找名字为test的action,若找到则执行,否则报错;
如果仍然不存在这个package,就去namaspace为空字符串的package下面去找名字为test的action,如果还是找不到,页面提示找不到action。