Struts2学习笔记(一)

/**

一、搭建Struts2的开发环境
	1、找到所需的jar包:发行包的lib目录中(不同版本需要的最小jar包是不同的,参见不同版本的文档。2.1.7)
		struts2-core.jar  核心jar包
		xwork-2.jar  xwork核心jar包
		
		ognl.jar  ognl表达式
		
		freemarker.jar  FreeMarker模板
		
		commons-logging.jar  日志
		commons-fileupload.jar  文件上传
		
		commons-io.jar  文件上传依赖的包
		
	2、在应用的WEB-INF/classes目录下建立一个名称为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>

		</struts>
	3、配置核心控制器,就是一个过滤器
		<filter>
			<filter-name>struts2</filter-name>
			<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
		</filter>
		<filter-mapping>
			<filter-name>struts2</filter-name>
			<url-pattern>/*</url-pattern>
		</filter-mapping>
	4、如果TOmcat启动成功,没有报错,证明环境搭建成功!
	
二、开发第一个Struts2案例
	1、编写struts.xml配置文件
		<?xml version="1.0" encoding="UTF-8"?>
		<!DOCTYPE struts PUBLIC
			"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
			"http://struts.apache.org/dtds/struts-2.1.7.dtd">
		<struts><!--这是Struts2配置文件的根元素-->
			<package name="itcast" namespace="/test" extends="struts-default">
			<!--
			pageckage:方便管理动作元素
				name:必须有。包的名称,配置文件中必须保证唯一。
				namespace:该包的名称空间,一般是以"/"开头
				extends:集成的父包的名称。struts-default名称的包是struts2框架已经命名好的一个包。(在struts2-core.jar中有一个struts-default.xml中)
				abstract:是否是抽象包。没有任何action元素的包就是抽象包(java类)
				
			-->
				<action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="sayHello">
				<!--
				action:代表一个请求动作
					name:同包中必须唯一。动作的名称
					class:负责处理的JavaBean的类全名
					method:JavaBean中的对应处理方法。(动作方法:特点是,public String 方法名(){})
				-->
					<result name="success">/1.jsp</result>
					<!--
					result:结果类型
						name:动作方法返回的字符串
						主体内容:View的具体地址。
					-->
				</action>
			</package>
		</struts>
	2、根据配置文件,创建需要的javabean和对应的动作方法,	在动作方法中完成你的逻辑调用。
	
	package cn.itcast.action;
	
	public class HelloWorldAction implements Serializable {
		private String message;

		public String getMessage() {
			return message;
		}

		public void setMessage(String message) {
			this.message = message;
		}
		public String sayHello(){
			message = "helloworld by struts2";
			return "success";
		}
	}
	3、编写View,显示结果
	 ${message}
	 
	4、访问helloworld动作的方式:http://localhost:8080/struts2day01/test/helloworld   应用名称/包的名称空间/动作的名称
		默认情况下:访问动作名helloworld,可以直接helloworld,或者helloworld.action
		
		http://localhost:8080/struts2day01/test/a/b/c/helloworld
			/test/a/b/c:名称空间
			helloworld:动作名称
			
			搜索顺序:名称空间
						/test/a/b/c  没有helloworld
						/test/a/b	 没有helloworld
						/test/a      没有helloworld
						/test        有了,调用执行
			
三、Struts2配置文件的详解
1、struts.xml配置文件编写是没有提示的问题?
	方法一:上网即可
	方法二:
		1、拷贝http://struts.apache.org/dtds/struts-2.1.7.dtd地址
		2、Eclipse的window、preferences,搜索XML Catelog
		3、点击add按钮
			Location:dtd文件的路径
			Key Type:URI
			Key:http://struts.apache.org/dtds/struts-2.1.7.dtd
2、Struts配置文件中的各种默认值。
action:
	class:默认值是com.opensymphony.xwork2.ActionSupport
			常量: 	SUCCESS   success
					NONE	none
					ERROR	error
					INPUT	input
					LOGIN	login
	method:默认值是public String execute(){}

	实际开发中:自己编写的动作类一般情况下继承com.opensymphony.xwork2.ActionSupport
result:
	type:转到目的地的方式。默认值是转发,名称是dispatcher
		(注:type的取值是定义好的,不是瞎写的。在struts-default.xml中的package中有定义)
		
		<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
		<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
		<result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
		<result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
		<result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
		<result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
		<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
		<result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
		<result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
		<result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
		
		dispatcher:普通的转发到某个页面
		chain:普通的抓发到某个动作名称
		redirect:重定向到一个页面
		redirectAction:重定向到一个动作名称
		plainText:以纯文本的形式输出JSP内容
	result元素的写法:
		方式一:
			<result type="chain" name="success">a2</result>
		方式二:
			<result type="chain" name="success">
				<param name="actionName">a2</param><!--name对应的chain的处理器中的setActionName()方法-->
			</result>
			
		注意:如果要转向的是在另外一个名称空间的动作,那么只能使用方式二
			<package name="p1" namespace="/namespace1" extends="struts-default">
				<action name="a2">
					<result type="dispatcher" name="success">/3.jsp</result>
				</action>
			</package>
			<package name="p2" namespace="/namespace2" extends="struts-default">
				<action name="a1">
					<result type="chain" name="success">
						<param name="namespace">/namespace1</param>
						<param name="actionName">a2</param>
					</result>
				</action>
			</package>
			
3、开发中配置文件的更改,在访问时让框架自动重新加载:
struts.devMode = false(default.properties)
利用strutx.xml中的constant元素来覆盖掉default.properties默认行为
<struts>
	<constant name="struts.devMode" value="true"></constant>
</struts>


动态方法  url+!methodName()  or <action name="order_*" class=..., method='{1}'>
	<result name='success'>/orders/{1}.jsp</result>




ActionContext  --> ActionContext.getContext()
	-->put(key,value)

--------------------------------------------------------------------------------------------------------------

一、自定义类型转换器
	1、编写一个类,继承com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter
	2、覆盖掉其中的public Object convertValue(Map<String, Object> context, Object value,Class toType)
			context:OGNL表达式的上下文
			value:实际的值。用户输入的都是字符串,但他是一个String数组。
			toType:目标类型
	public class DateConvertor extends DefaultTypeConverter {
		/*
		 context:ognl表达式的上下文
		 value:用户输入的值( 保存数据时)或者模型中的属性。用户输入的值是String数组
		 toType:目标类型
		 */
		@Override
		public Object convertValue(Map<String, Object> context, Object value,
				Class toType) {
			DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
			if(toType==Date.class){
				//2013/05/31----->java.util.Date 保存数据时
				String strValue = ((String[])value)[0];
				try {
					return df.parse(strValue);
				} catch (ParseException e) {
					throw new RuntimeException(e);
				}
			}else{
				//java.util.Date----->2013/05/31 获取数据时
				Date dValue = (Date)value;
				return df.format(dValue);
			}
		}
	}
	3、注册类型转换器
		3.1局部类型转换器:只对当前的Action有效
		具体做法:在动作类相同的包中,建立一个名称是“动作类名-conversion.properties”的配置文件,
			文件中增加以下内容:要验证的字段=验证器的类全名
					birthday=cn.itcast.convertor.DateConvertor
		3.2全局类型转换器:对所有的Action都有效
		具体做法:在WEB-INF/classes目录下,建立一个名称为"xwork-conversion.properties"的配置文件,
			文件中增加以下内容:目标类型全名=验证器的类全名
					java.util.Date=cn.itcast.convertor.DateConvertor
		
		
		
	注意:如果转换失败,Struts2框架会寻找name=input的结果页面
二、自定义拦截器
	1、编写一个类,实现com.opensymphony.xwork2.interceptor.Interceptor
	2、主要实现public String intercept(ActionInvocation invocation) throws Exception{}方法
		该方法的返回值就相当于动作的返回值
		如果调用了String result = invocation.invoke();得到了动作类的返回的值。
	public String intercept(ActionInvocation invocation) throws Exception {
		//判断用户是否登录
		HttpSession session = ServletActionContext.getRequest().getSession();
		Object obj = session.getAttribute("user");
		if(obj==null){
			return "login";
		}else{
			return invocation.invoke();//调用动作方法
		}
	}
	3、拦截器定义好后,一定要在配置文件中进行注册:
		<interceptors> 只是定义拦截器,并没有起作用 
			<interceptor name="permissionInterceptor" class="cn.itcast.interceptor.PermissionInterceptor"></interceptor>
		</interceptors>
	4、配置文件中的动作,要通过
		<interceptor-ref name="permissionInterceptor"></interceptor-ref>使用该拦截器
	注意:一旦动作中使用了自定义的拦截器,那么默认的就不起作用了。一般应该采用如下的做法:
		<interceptor-ref name="defaultStack"></interceptor-ref>
		<interceptor-ref name="permissionInterceptor"></interceptor-ref>
		
	多个动作类都要使用的话,可以通过package来进行组合。
三、用户输入数据的验证
	1、手工编程验证,针对该动作类中的所有的动作方法
	步骤:
	a、动作类继承ActionSupport
	b、覆盖调用public void validate()方法
	c、在validate方法中,编写不符合要求的代码判断,并调用父类的addFieldError(String fieldName,String errorMessage)
		如果fieldError(存放错误信息的Map)有任何的元素,就是验证不通过,动作方法不会执行。
		Struts2框架会返回到name=input的result
	d、在name=input指定的页面上使用struts2的标签显示错误信息。<s:fielderror/>
	
	


--------------------------------------------------------------------------------------------------------------



一、用户输入验证
	1、编程方式:
		动作类中的所有方法进行验证:
		
			步骤:
			a、动作类继承ActionSupport
			b、覆盖调用public void validate()方法
			c、在validate方法中,编写不符合要求的代码判断,并调用父类的addFieldError(String fieldName,String errorMessage)
				如果fieldError(存放错误信息的Map)有任何的元素,就是验证不通过,动作方法不会执行。
				Struts2框架会返回到name=input的result
			d、在name=input指定的页面上使用struts2的标签显示错误信息。<s:fielderror/>
		
		动作类中指定的方法进行验证:
			编写步骤与上面相同
			
			验证方法书写有要求:
				public void validateXxx()   Xxx代表的是要验证的动作方法名,其中要把动作方法名的首字母变为大写。
				
	
	2、基于XML配置文件的方式:
		动作类中的所有方法进行验证:
			在动作类的包中,建立一个名称为:动作简单类名-validation.xml ,比如要验证的动作类名是UserAction   UserAction-validation.xml
			内容如下:
			<?xml version="1.0" encoding="UTF-8"?>
			<!DOCTYPE validators PUBLIC
					"-//OpenSymphony Group//XWork Validator 1.0.3//EN"
					"http://www.opensymphony.com/xwork/xwork-validator-1.0.3.dtd">
			<validators>
				<field name="username">
					<!-- 内置验证器都是定义好的,在xwork-core.jar com.opensymphony.xwork2.validator.validators包中的default.xml文件中 -->
					<field-validator type="requiredstring"><!-- 不能为null或者""字符串,默认会去掉前后的空格 -->
						<message>用户名不能为空</message>
					</field-validator>
				</field>
			</validators>
		动作类中指定的方法进行验证:
			配置文件的名称书写有一定要求。
					动作类名-动作名(配置文件中的动作名)-validation.xml
					UserAction-user_add-validation.xml
	3、自定义基于XML的验证器
		a、编写一个类,继承FieldValidatorSupport类。
		b、在public void validate(Object object)编写你的验证逻辑
				不符合要求的就向fieldErrors中放消息
		c、一定注册你的验证器才能使用
				在WEB-INF/classes目录下建立一个名称为validators.xml的配置文件,内容如下:
				<validators>
					<validator name="strongpassword" class="cn.itcast.validators.StrongPasswordValidator"/>
				</validators>
		d、日后就可以像使用Struts2提供的16个验证器方式去使用了。
		
二、Struts2对于i18n的支持
	全局资源文件/包范围资源文件/动作类的资源文件
	全局资源文件:放到WEB-INF/classes目录下
	包范围资源文件:服务于Java类中的包下的动作类的。
			取名:package_语言_国家.properties
	
	动作类的资源文件:放到与动作类相同的包中
			取名:动作类名_语言_国家.properties
			
			
	jsp中如何读取国际化的消息
	动作类中如何读取国际化的消息
三、OGNL表达式:
	OGNL是从ActionContext中获取数据的。
	
	ActionContext的结构:
		ValueStack:
			List:动作类放在此处。取存放在ValueStack中的root的对象的属性,直接写即可
			
			访问以下内容中的对象要使用#+(范围)session
		application:ServletContext中的那个Map
		session:HttpSession中的那个Map
		request:ServletRequest中的那个Map
		parameters:请求参数的那个Map。(如同EL表达式的paramValues内置对象)
		attr:相当于PageContext的findAttribute方法。${username}
	小技巧:在页面中使用<s:debug/>查看上下文中的对象
	
四、Struts2中常用的标签
五、防止表单重复提交
六、CURD:单表
七、如何使用Struts的插件。(牵扯与其他框架整合)JFreeChart整合




--------------------------------------------------------------------------------------------------------------


一、防止表单的重复提交
	1、在表单中加入<s:token/>标签
	2、在动作类中加入token的拦截器
		<interceptor-ref name="defaultStack"></interceptor-ref>
		<interceptor-ref name="token"></interceptor-ref>
	3、增加一个名称为invalid.token的结果视图
		<result name="invalid.token">/success.jsp</result>








*/

你可能感兴趣的:(freemarker,struts,struts2.0)