Struts2学习第三天

愿望总是很美好,给自己罗列的计划总想着能完成,但是执行起来总是大打折扣。。。

第三天才要把action这块结束了,效率真的很慢,希望这么慢的效率能有好的成长。

ModelDriven接口实现参数输入:

定义一个UserAction它继承于ActionSupport 实现了ModelDriven接口

public class UserAction extends ActionSupport implements ModelDriven<User>{

	private User user = new User();
	
	public String add(){
		System.out.println("name = " + user.getName());
		System.out.println("age = " + user.getAge());
		return SUCCESS;
	}

	@Override
	public User getModel() {
		return user;
	}

}

ModelDriven接口只有一个方法是getModel()方法,需要再定义一个vo包把属性和方法分开,通过得到对象的引用来得到那些属性


User类中:

public class User {

	private String name;
	private int age;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

一般这种方式不常用,但是这种设计理念一定要掌握

简单的数据验证:

新建一个UserAction类

public class UserAction extends ActionSupport {

	private String name;
	
	public String add(){
		if(name == null || !name.equals("admin")) {
			this.addFieldError("name", "name is error");
			this.addFieldError("name", "name is too long");
			System.out.println(name);
			return ERROR;
		}
		return SUCCESS;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

这个类中调用了一个this.addFieldError()方法,这个方法是struts2中的方法,这个方法会返回一个数据信息,但是前台如何才能接受到错误的信息呢?这个时候就需要用到ognl表达式标签了,首先先开struts.xml的配置:


result结果是error的话会定位到 User_Add_error.jsp页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>insert title here</title>
</head>
<body>
	User Add Error
	<s:fielderror fieldName="name" theme="simple" /><%-- 默认为simple --%> 
	<br/>
	<s:property value="errors.name[0]"/>
	<s:debug></s:debug>
</body>
</html>

ognl表达式使用前需要先引用一下 

<%@taglib uri="/struts-tags" prefix="s" %>
<s:fielderror fieldName="name"> 能够接受到
this.addFieldError

传递的name值。<s:property>标签是访问值栈对象的普通属性的,

值栈可以通过<s:debug>标签显示出:


我们可以看见errors 是一个map值,map 对应的key 和 value ,而value是一个数组(或者说是集合,通过看源码可以判定)。

通过给前台传递错误信息这种方式比较恶心,它的格式是固定的,这样就让程序员很头疼。。。


下面来说一个比较关键的:

通过web访问元素:

首先定义一个LoginAction1:

public class LoginAction1 extends ActionSupport{

	private Map request;
	private Map session;
	private Map application;
	
	public LoginAction1() {
		request = (Map)ActionContext.getContext().get("request");
		session = ActionContext.getContext().getSession();
		application = ActionContext.getContext().getApplication();
	}
	
	public String execute() {
		request.put("r1", "r1");
		session.put("s1", "s1");
		application.put("a1", "a1");
		return SUCCESS;
	}

}

这种方式用的比较少,它通过手动调用的方式来获取request、session和application ,

ActionContext是什么,以及ognl表达式如何 见博客 http://blog.csdn.net/super_yc/article/details/61629522

再看struts.xml中的配置:


index.jsp中的配置:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="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" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Action页面</title>
</head>
<body>
	取得request,session,application,HttpServletRequest,HttpServletSession,ServletContext的引用
	<ol>
		<li>前三者:依赖于容器</li>
		<li>前三者:IoC</li>
		<li>后三者:依赖于容器</li>
		<li>后三者:依赖于IoC</li>
	</ol>
	<br>
	<form name="f" action="" method="post">
		用户名: <input type="text" name="name"><br/>
		密码:<input type="password" name="password"><br/>
		<input type="button" value="submit1" onclick="javascript:document.f.action='login/login1';document.f.submit()" /><br/>
		<input type="button" value="submit2" onclick="javascript:document.f.action='login/login2';document.f.submit()" /><br/>
		<input type="button" value="submit3" onclick="javascript:document.f.action='login/login3';document.f.submit()" /><br/>
		<input type="button" value="submit4" onclick="javascript:document.f.action='login/login4';document.f.submit()" /><br/>
	</form>
</body>

jsp中没有指定action,他是一个动态的action,由dom来进行复制。

User_Login_success.jsp中:


我们看到<s:property>属性可以通过#来进行赋值,这里解释一下attr的属性,attr属性不同于request,session,application,它会自动搜索你想要得到的属性,它会在request,session,application中搜索你想要的属性,很方便,但是我们一般不用,因为假如你有两个r1你该怎么办?而且这三个对象的储存位置需要编程人员精确的知道其位置的。

再看LoginAction2:

public class LoginAction2 extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{

//	Ioc控制反转
	private Map<String,Object> request;
	private Map<String,Object> session;
	private Map<String,Object> application;
	
	public String execute() {
		request.put("r1", "r1");
		session.put("s1", "s1");
		application.put("a1", "a1");
		return SUCCESS;
	}
	
	public void setApplication(Map<String, Object> request) {
		this.request = request;
	}
	public void setSession(Map<String, Object> session) {
		this.session = session;
	}
	public void setRequest(Map<String, Object> application) {
		this.application = application;
	}
}
RequestAware,SessionAware,ApplicationAware

可以从字面上翻译,RequestAware意为知道request对象,另外两个也一样。

想一个问题: 为什么request、session、application 通过map.put()放入值之后就能被浏览器解析并且拿到这个值?

肯定有一种机制是把request、session、application三个对象和浏览器进行交互,由此引用IoC(控制反转)这个概念,编程人员不用再自己主动去调用,而是把这种交互注入到request、session、application中,让你可以拿来直接使用,这也是我们struts常用的方式。

下面再看LoginAction3:

public class LoginAction3 extends ActionSupport{

	private HttpServletRequest request;
	private HttpSession session;
	private ServletContext application;
	
	public LoginAction3() {
		request = ServletActionContext.getRequest();
		session = request.getSession();
		application = session.getServletContext(); 
	}
	
	public String execute() {
		request.setAttribute("r1", "r1");
		session.setAttribute("s1", "s1");
		application.setAttribute("a1", "a1");
		return SUCCESS;
	}
}

LoginAction4:

public class LoginAction4 extends ActionSupport implements ServletRequestAware{

	private HttpServletRequest request;
	private HttpSession session;
	private ServletContext application;
	
	public String execute() {
		request.setAttribute("r1", "r1");
		session.setAttribute("s1", "s1");
		application.setAttribute("a1", "a1");
		return SUCCESS;
	}
	
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
		session = request.getSession();
		application = session.getServletContext();
	}

}

上述两种方式使用的少之又少,可以不用考虑,直接忘掉即可。


Include 包含


这个标签比较简单,但是蕴含的道理很耐人寻味

新建一个login.xml:

<struts>

	 <package name="login" extends="struts-default" namespace="/login">  <!-- package包区分不同的类名 -->
        <action name="login*" class="com.liuxuan.struts.LoginAction{1}">
            <result>/User_Login_success.jsp</result> <!-- 默认即为success -->
        </action>
    </package>

</struts>

struts.xml持有对login.xml的引用:

 <constant name="struts.devMode" value="true" />
   		<include file="login.xml"></include>

由此带来的好处是如果是项目组的话,可以专注于各自手头的工作即可。


Default属性:

struts.xml中

 <constant name="struts.devMode" value="true" />
	<package name="default" extends="struts-default" namespace="/">  <!-- package包区分不同的类名 -->
		<default-action-ref name="index"></default-action-ref>
        <action name="index">
            <result>/default.jsp</result> <!-- 默认即为success -->
        </action>
    </package>
指定一个属性
<default-action-ref name="index"></default-action-ref>

这样无论在url地址中如何输入都会跳转到default.jsp页面



猜你喜欢

转载自blog.csdn.net/qq_36894974/article/details/79331364