对于struts2的struts.xml中的namespace的懂得

对于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的寻找方式是这样的(引自wdl13http://wdl123.iteye.com/blog/340709):

1.获得请求路径的URI,例如url是:http://server/myapp/path1/path2/path3/test.action

2
.首先寻找namespace/path1/path2/path3package,如果存在这个package,则在这个package中寻找名字为testaction,若找到则执行,否则报错;如果不存在这个package则转步骤3

//问题的关键在这里:如果在寻找
namespace的时候,没能找到符合的namespace,例如/path1/path2/path3,则一切如wdl123所写的,逐次往上目录当做namespace找,但是一旦存在/path1/path2/path3这样的namespace,那么如果在这个namespace下没能找到test.action,则他不会再逐次往上级目录匹配namespace,而是直接转向了namespace""的去寻找action

3
.寻找namespace/path1/path2package,如果存在这个package,则在这个package中寻找名字为testaction,若找到则执行,否则报错;如果不存在这个package则转步骤4

4
.寻找namespace/path1package,如果存在这个package,则在这个package中寻找名字为testaction,若找到则执行,否则报错;


如果仍然不存在这个package,就去namaspace为空字符串的package下面去找名字为testaction,如果还是找不到,页面提示找不到action