S3.1_Struts2_BasicConfiguration struts2主要配置文件和常用配置还有中文乱码问题以及简单验证

来源:互联网 发布:c语言结构体链表 编辑:程序博客网 时间:2024/05/30 23:40

struts2主要配置文件
struts.xml常用配置
中文乱码问题
简单验证

struts2主要配置文件:
web.xml(设置过滤器以及注解annotation初始化参数),它在项目中的位置:WebRoot/WEB-INF/web.xml;
struts.xml主配置文件(以后详细讲解),它在项目中的位置:src/struts.xml;
struts.properties属性文件,它在项目中的位置:src/struts.properties;
struts-default.xml,它在jar包中的路径:struts2-core-2.2.1.jar//META-INF/struts-default.xml;
struts2的默认配置;
struts-plugin.xml,每个插件jar包里面都有这样的配置文件,例如struts2-json-plugin-2.2.1.jar/struts-plugin.xml 再例如struts2-convention-plugin-2.2.1.jar/struts-plugin.xml;
struts2框架的插件配置文件;

web.xml、struts.xml还有struts-default.xml这3个xml文件的格式是一样的,因为它们使用同一个struts2-core-2.2.1.jar/struts-2.0.dtd文件,在xml文件中constant元素有两个必须的属性:name和value,dtd是文档类型定义的扩展名;

在struts.properties文件中,每一个entry都被视为一个常量;

在web.xml文件中FilterDispatcher的初始化参数被载入为常量;


struts2 主要配置文件加载顺序,后加载配置文件配置的内容会覆盖掉前面其它配置文件内定义的内容,这些配置文件加载的先后次序很重要,牢记!!!
首先加载struts-default.xml由上至下,依次为:
struts-default.xml
struts-plugin.xml
struts.xml
struts.properties
web.xml

如果在多个文件中配置了同一个struts2常量constant,则后一个文件中的配置的常量constant会覆盖前面文件中配置的常量constant的值;
在不同文件中配置常理的方式是不一样的,但不管哪个文件中,配置Struts2常量都要指定两个属性:常量name和常量value;
推荐在struts.xml文件中配置struts2常量constant


struts-default.xml详细讲解

<struts>
<!-- 两个对象工厂组件 -->
<bean class="com.opensymphony.xwork2.ObjectFactory" name="xwork" />
<bean  type="com.opensymphony.xwork2.ObjectFactory" name="struts" class="org.apache.struts2.impl.StrutsObjectFactory"  />
</struts>

浏览struts-default.xml的内容,您会发现<struts>是它的根元素,根元素下面定义了很多<bean >元素,每个bean就是一个组件,也可以理解成是一个类,

bean 里面的class值是指bean的实现类,name 值是指组件名称,type表示组件的类型,也可以理解type值实现了那些接口,相当于type这个bean里的子类要实现的接口

struts-default.xml还定义了 

<package name="struts-default" abstract="true"> 里面的abstract="true"说明它是一个抽象包,包里面没有定义<action>元素,就表示它是一个抽象包

<result-types> 定义结果集的类型,

<interceptors>定义拦截器的集合,

     <interceptor>定义一个拦截器

 <interceptor-stack name="basicStack"> 拦截器堆栈
                <interceptor-ref name="exception"/> 拦截器里面放了很多拦截器引用

最后还有一个默认的拦截器堆栈:

<interceptor-stack name="defaultStack">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="alias"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="i18n"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="chain"/>
                <interceptor-ref name="debugging"/>
                <interceptor-ref name="scopedModelDriven"/>
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="fileUpload"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="multiselect"/>
                <interceptor-ref name="staticParams"/>
                <interceptor-ref name="actionMappingParams"/>
                <interceptor-ref name="params">
                  <param name="excludeParams">dojo\..*,^struts\..*</param>
                </interceptor-ref>
                <interceptor-ref name="conversionError"/>
                <interceptor-ref name="validation">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
                <interceptor-ref name="workflow">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
            </interceptor-stack>

文件末尾有<default-interceptor-ref name="defaultStack"/> 默认拦截器引用继承了默认堆栈

bean 元素属性
class:必选,它指定了bean实例的实现类;
type:可选,通常是通过某个接口或者在此前定义过的bean;
name:可选,它指定的bean实例的名字,对于有相同type的多个bean。name必须唯一;
scope:可选,指定bean的作用域,只能是default、singleton、request、session或thread之一;
static:可选,它指定bean是否使用静态方法注入,通常而言,当指定了type属性时,该属性就不应该指定为true;
optional:可选,指定bean是否是一个可选bean;


struts.properties属性文件,它在项目中的位置:src/struts.properties;

在你自己的项目中的src/struts.properties文件中设置的常理值会覆盖掉jar包中struts2-core-2.2.1.jar/org.apache.struts2/default.properties默认配置中设置的值,简单的列出以下几项:

### This can be used to set your default locale and encoding scheme
# struts.locale=en_US
struts.i18n.encoding=UTF-8

### Used by the DefaultActionMapper
### You may provide a comma separated list, e.g. struts.action.extension=action,jnlp,do
### The blank extension allows you to match directory listings as well as pure action names
### without interfering with static resources.
struts.action.extension=action,,

### when set to true, Struts will act much more friendly for developers. This
### includes:
### - struts.i18n.reload = true
### - struts.configuration.xml.reload = true
### - raising various debug or ignorable problems to errors
###   For example: normally a request to foo.action?someUnknownField=true should
###                be ignored (given that any value can come from the web and it
###                should not be trusted). However, during development, it may be
###                useful to know when these errors are happening and be told of
###                them right away.
struts.devMode = false

为了演示src/struts.properties的用法,创建S3.1_Struts2_BasicConfiguration项目

我们演示完本篇主题所有范例需要创建的项目目录结构如下:


由项目S2.3_Struts2_ActionGetInputFormData (如何下载它:点击打开链接)复制粘贴生成一个新项目 ------ S3.1_Struts2_BasicConfiguration
详细操作截图参考S1.2_Struts2_ByManual 手工编写第一个Struts2范例篇,位置在项目目录结构图下面。

第1步:建立一个src/struts.properties文件,添加一行代码如下:
struts.action.extension=do

第2步: 将WebRoot/login.jsp文件中login.action改成login.do,login.jsp文件代码如下:

<%@ page language="java" import="java.util.*" %>
<%@ page contentType="text/html; charset=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">    
<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>
        <center>
    <h1>系统登录</h1>
    <hr>
    <form name="loginForm" action="<%=path%>/login.do" method="post" >
    用户名称:<input type="text" name="username"/><br>
    用户密码:<input type="password" name="password"/><br>
           <input type="submit" value="登录"/><br>
    </form>
    </center>
  </body>
</html>

第3步:发布项目运行程序
此步操作的详细过程参考S1.1_Struts2_Model2 手动创建一个简单的servlet项目,未使用Struts技术 点击打开链接 位置在最下面------发布项目运行程序

若成功发布运行本项目代码,启动后您会看到欢迎页地址:

http://localhost:8080/S3.1_Struts2_BasicConfiguration/login.jsp

用户名称:admin
用户密码:123456
点击登录按钮跳转到  http://localhost:8080/S3.1_Struts2_BasicConfiguration/login.do

登录成功和失败显示页如下图所示:


输入错误密码或者不输入密码点击登录按钮跳转到 

http://localhost:8080/S3.1_Struts2_BasicConfiguration/login.do

注意:跳转到了目标页面,无论登录成功还是失败,浏览器地址栏都是
http://localhost:8080/S3.1_Struts2_BasicConfiguration/login.do

浏览器地址栏并没有出现我们想象地JSP页面地址:
http://localhost:8080/S3.1_Struts2_BasicConfiguration/login_success.jsp
http://localhost:8080/S3.1_Struts2_BasicConfiguration/login_failure.jsp

struts.xml常见配置
constrant   ------ 常量
package     ------ 解决action重名,方便继承
 -name      ------ 包名
 -extends   ------ 父包名
 -namespace ------ 名称空间

action
 -name      ------ 动作名称
 -class     ------ 实现类,没有设置class的值相当于页面直接跳转

result


constrant   ------ 常量
中文乱码问题推荐解决方案
a) jsp页面编码设为utf-8:
<%@ page language="java" import="java.util.*" %>
<%@ page contentType="text/html; charset=UTF-8" %> 

b) 在src/struts.xml配置中插入以下常量编码元素:
<constant name="struts.i18n.encoding" value="utf-8" ></constant>

配置好的src/struts.xml文件代码如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="struts.devMode" value="true" ></constant>
    <constant name="struts.i18n.encoding" value="utf-8" ></constant>

    <package name="default" namespace="/" extends="struts-default">
        <!-- action的name值必须等于LoginAction.java类命名规范(XxxxAction)中Xxxx,即是Login(首字母要小写) -->
        <action name="login" class="net.nw.action.LoginAction3">
            <!-- result的name值必须等于LoginAction.java类里面被重写的execute方法的返回值 -->
            <result name="login_success">/login_success.jsp</result>
            <result name="login_failure">/login_failure.jsp</result>
        </action>
    </package>
</struts>

c)为了演示页面出现乱码,让用户名称不再只等于admin,只要用户名称有输入内容且不为空即可登录,

当然包括可以输入汉字用来演示乱码的出现的效果,我们需要调整用户操作类net.nw.dao.UserDao验证条件,修改后的代码如下:

package net.nw.dao;
import net.nw.vo.User;
//用户操作类
public class UserDao {
public boolean userLogin(User u){
if(!u.getUsername().equals("") && u.getPassword().equals("123456")){
return true;
} else {
return false;
}
}
}

只要此行改成非utf-8的编码格式<constant name="struts.i18n.encoding" value="gbk" ></constant>那么用户名称就会在登录成功的页面显示乱码效果


 package     ------ 解决action重名(例如 name="login"),方便继承
            <action name="login" class="net.nw.action.AdminAction">
            <action name="login" class="net.nw.action.LoginAction3">

第1步:在net.nw.action包下创建一个AdminAction.java的空类,

空类AdminAction隐式地执行execute()方法,若成功execute()方法直接返回默认的success值,AdminAction.java文件代码如下:
package net.nw.action;
import com.opensymphony.xwork2.ActionSupport;
public class AdminAction extends ActionSupport {
/**
* 对象序列化需要此serialVersionUID
*/
private static final long serialVersionUID = 1L;
}

第2步:创建WebRoot/admin/admin.jsp文件,代码如下:

<%@ page language="java" import="java.util.*" %>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/struts-tags" prefix="s" %>
<%
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">    
<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>
    <center>
    <h1>管理员界面</h1>
    <hr>
    <s:debug></s:debug>
    </center>
  </body>
</html>

第3步:为了解决两个同名称的action name="login"互相冲突,我们必须把它们分别放在不同的package包里面定义,为了演示action重名解

决办法,我们需要再一次的调整src/struts.xml配置的内容,其代码如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="struts.devMode" value="true" ></constant>
    <constant name="struts.i18n.encoding" value="utf-8" ></constant>
    <package name="user" namespace="/user" extends="struts-default">
        <action name="login" class="net.nw.action.loginAction3">
            <result name="login_success">/login_success.jsp</result>
            <result name="login_failure">/login_failure.jsp</result>
        </action>
    </package>
    <package name="admin" namespace="/admin" extends="struts-default">
        <action name="login" class="net.nw.action.AdminAction">
            <result>/admin/admin.jsp</result><!-- 这种简写形式接收Action动作类里面的execute()方法返回值success,跳转到admin.jsp页面 -->
        </action>
    </package>
</struts>

第4步:为了测试的方便,重新调整WebRoot/login.jsp页面文化的内容,注意红色字体标识处的写法,其代码如下:

<%@ page language="java" import="java.util.*" %>
<%@ page contentType="text/html; charset=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">    
<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>
        <center>
    <h1>系统登录</h1>
    <hr>
    <form name="loginForm" action="<%=path%>/user/login.do" method="post" >
    用户名称:<input type="text" name="username"/><br>
    用户密码:<input type="password" name="password"/><br>
           <input type="submit" value="登录"/><br>
           <br>
           <br><a href="<%=path%>/admin/login.do">管理员登录</a>
    </form>
    </center>
  </body>
</html>

理解上面红色字体标识路径的写法,下面配一幅图片作一个对比说明,这样就很容易掌握正确的路径书写格式



第5步:发布项目运行程序
此步操作的详细过程参考S1.1_Struts2_Model2 手动创建一个简单的servlet项目,未使用Struts技术 点击打开链接 位置在最下面------发布项目运行程序

若成功发布运行本项目代码,启动后您会看到欢迎页地址:

http://localhost:8080/S3.1_Struts2_BasicConfiguration/login.jsp

用户名称:童话
用户密码:123456
点击登录按钮跳转到  http://localhost:8080/S3.1_Struts2_BasicConfiguration/login.do

登录成功和失败显示页如下图所示:


输入错误密码或者不输入密码点击登录按钮跳转到 

http://localhost:8080/S3.1_Struts2_BasicConfiguration/login.do

注意:跳转到了目标页面,无论登录成功还是失败,浏览器地址栏都是
http://localhost:8080/S3.1_Struts2_BasicConfiguration/login.do

浏览器地址栏并没有出现我们想象地JSP页面地址:
http://localhost:8080/S3.1_Struts2_BasicConfiguration/login_success.jsp
http://localhost:8080/S3.1_Struts2_BasicConfiguration/login_failure.jsp

管理员登录地址显示:http://localhost:8080/S3.1_Struts2_BasicConfiguration/admin/login.do

而不是出现我们想象地JSP页面地址:http://localhost:8080/S3.1_Struts2_BasicConfiguration/admin/admin.jsp

补充struts.xml继承包的定义格式,上面struts.xml中定义的两个独立包user和admin可以改写成继承包的格式,改写成继承包的格式如下:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN""http://struts.apache.org/dtds/struts-2.3.dtd"><struts>    <constant name="struts.devMode" value="true" ></constant>    <constant name="struts.i18n.encoding" value="utf-8" ></constant>     <!-- 父包default -->     <package name="default" namespace="" extends="struts-default">        <global-results>        <result name="login_success">/login_success.jsp</result>            <result name="login_failure">/login_failure.jsp</result>        </global-results>     </package>    <!-- 子包user继承于父包default -->    <package name="user" namespace="/user" extends="default">        <action name="login" class="net.nw.action.LoginAction3">        </action>    </package>    <!-- 子包admin继承于父包default -->    <package name="admin" namespace="/admin" extends="default">        <action name="login" class="net.nw.action.AdminAction">            <result>/admin/admin.jsp</result>        </action>    </package></struts>

执行结果与上面贴图一样,这里就不贴同样的效果图片了,为了更容易理解独立包与继承包不同之处定义格式,加深一下我们的印象,下面贴一对比截图:


action
 -name      ------ 动作名称
 -class     ------ 实现类 (class的值没有定义,或者定义了但是class的值是一个空类,那么它起到的作用相当于页面直接跳转)

下面演示class的值没有定义情形:

第1步:在src/struts.xml文件中,找到父包default,在</global-results>全局结果集元素下面插入

        <action name="exit">
        <result>/login.jsp</result>
        </action>

这样一来,父包default的所有子包都具备exit动作的跳转的功能了,调整好的src/struts.xml文件代码如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="struts.devMode" value="true" ></constant>
    <constant name="struts.i18n.encoding" value="utf-8" ></constant>
     <!-- 父包default -->
     <package name="default" namespace="" extends="struts-default">
        <global-results>
        <result name="login_success">/login_success.jsp</result>
            <result name="login_failure">/login_failure.jsp</result>
        </global-results>
        <action name="exit">
        <result>/login.jsp</result>
        </action>

     </package>
    <!-- 子包user继承于父包default -->
    <package name="user" namespace="/user" extends="default">
        <action name="login" class="net.nw.action.LoginAction3">
        </action>
    </package>
    <!-- 子包admin继承于父包default -->
    <package name="admin" namespace="/admin" extends="default">
        <action name="login" class="net.nw.action.AdminAction">
            <result>/admin/admin.jsp</result>
        </action>
    </package>
</struts>

第2步:在WebRoot/login_failure.jsp文件中,找到<a href="<%=path%>/login.jsp">返回</a>,将其改写成更规范写法<a href="<%=path%>/exit.do">返回</a>

WebRoot/login_failure.jsp文件改写后代码如下:

<%@ page language="java" import="java.util.*" %>
<%@ page contentType="text/html; charset=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">    
<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>
    <center>
    <h1>登录失败</h1>
    <hr>
    <a href="<%=path%>/exit.do">返回</a>
    </center>
  </body>
</html>

接下来就是发布运行,点登录按钮(输入错误密码或者不输入密码)就不在此演示了。


简单验证
被调用的action动作类,错误信息的键-值对定义一般写在execute()方法里面,在jsp页面使用值栈技术读出键-值对信息:
addFieldError("key","value");

提示出错信息jsp页面,一般是在用户输入数据的页面上直接显示错误验证提示信息:
<%@ taglib uri="/struts-tags" prefix="s" %>

<s:filederror name="key" theme="simple"/>
<s:property value="errors.key[0]">
...
<s:property value="errors.key[n]">

以下演示简单验证还是在本项目S3.1_Struts2_BasicConfiguration里面进行

第1步:在net.nw.action包下的LoginAction3.java文件中找到execute()方法,在该方法相应的地方插入以下红色字体标识的代码:

package net.nw.action;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import net.nw.dao.UserDao;
import net.nw.vo.User;
public class LoginAction3 extends ActionSupport implements ModelDriven<User>{
/**
* 对象序列化需要此serialVersionUID
*/
private static final long serialVersionUID = 1L;
    private User user = new User();//注意:此处user一定要实例化
public LoginAction3() {
System.out.println("构造方法LoginAction3 ......");
}
//调用业务层操作类的方法
public String execute(){
UserDao dao = new UserDao();
if(dao.userLogin(user)){
return "login_success";
} else{
this.addFieldError("login_error","用户名称或者用户密码不正确");
return "login_failure";
}
}
@Override
public User getModel() {
// TODO Auto-generated method stub
return user;
}
}


第2步:在WebRoot/login_failure.jsp文件中插入红色字体标识的代码:

<%@ page language="java" import="java.util.*" %>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/struts-tags" prefix="s" %>
<%
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">    
<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>
    <center>
    <h1>登录失败</h1>
    <hr>
    <s:fielderror value="login_error" theme="simple"></s:fielderror>
    <a href="<%=path%>/exit.do">返回</a>
    </center>
  </body>
</html>

第3步:发布项目运行程序
此步操作的详细过程参考S1.1_Struts2_Model2 手动创建一个简单的servlet项目,未使用Struts技术 点击打开链接 位置在最下面------发布项目运行程序


若成功发布运行本项目代码,启动后您会看到欢迎页地址:
http://localhost:8080/S3.1_Struts2_BasicConfiguration/login.jsp

点击登录按钮测试,运行效果图如下:


本项目下载地址:点击打开链接


0 0