现在的位置: 首页 > 综合 > 正文

4、struts2异常处理及全局异常与结果剖析、struts2模型驱动及分层体系架构

2018年02月05日 ⁄ 综合 ⁄ 共 8461字 ⁄ 字号 评论关闭

1、我们可以自定义异常,并且指定当异常出现时,转向哪一个处理页面,首先针对LoginAction这个Action来说,在execute()方法中手工抛出两个异常:

UsernameException和PasswordException,异常定义:

package com.cdtax.exception;

public class UsernameException extends Exception
{
	private String message;
	
	public UsernameException(String message)
	{
		super(message);
		
		this.message = message;
	}

	public String getMessage()
	{
		return message;
	}

	public void setMessage(String message)
	{
		this.message = message;
	}
	
}

 

package com.cdtax.exception;

public class PasswordException extends Exception
{
	private String message;
	
	public PasswordException(String message)
	{
		super(message);
		
		this.message = message;
	}

	public String getMessage()
	{
		return message;
	}

	public void setMessage(String message)
	{
		this.message = message;
	}
	
}

然后配置struts.xml文件:

<action name="aas" class="com.cdtax.struts2.LoginAction">
	<exception-mapping result="usernameinvalid" exception="com.cdtax.exception.UsernameException"></exception-mapping>
	<exception-mapping result="passwordinvalid" exception="com.cdtax.exception.PasswordException"></exception-mapping>
	<result name="success">/result.jsp</result>
	<result name="usernameinvalid">/usernameexception.jsp</result>
	<result name="passwordinvalid">/passwordexception.jsp</result>
</action>

增加了两个exception-mapping和两个result

然后创建两个异常的处理页面usernameexception.jsp和passwordexception.jsp,这样当用户名抛出异常时,页面转向usernameexception.jsp,密码出现异常时,转向passwordexception.jsp。

2、全局的异常处理和全局的结果

全局的异常处理:struts.xml:

<global-results>
	<result name="usernameinvalid">/usernameexception.jsp</result>
	<result name="passwordinvalid">/passwordexception.jsp</result>
</global-results>
<action name="aas" class="com.cdtax.struts2.LoginAction">
	<exception-mapping result="usernameinvalid" exception="com.cdtax.exception.UsernameException"></exception-mapping>
	<exception-mapping result="passwordinvalid" exception="com.cdtax.exception.PasswordException"></exception-mapping>
	<result name="success">/result.jsp</result>
		
</action>

这时全局的异常处理:局部的优于全局的,就是说,如果在Action标签中也有<result name="usernameinvalid">/passwordexception.jsp</result>,那么页面将优先转向局部的result指向的页面,这里就是passwordexception.jsp。

全局的异常struts.xml:

<global-results>
	<result name="usernameinvalid">/usernameexception.jsp</result>
	<result name="passwordinvalid">/passwordexception.jsp</result>
</global-results>
<global-exception-mappings>
	<exception-mapping result="usernameinvalid" exception="com.cdtax.exception.UsernameException"></exception-mapping>
	<exception-mapping result="passwordinvalid" exception="com.cdtax.exception.PasswordException"></exception-mapping>
</global-exception-mappings>
<action name="aas" class="com.cdtax.struts2.LoginAction">
		
	<result name="success">/result.jsp</result>
		
</action>

也是局部优于全局的。

我们可以在action中定义异常与结果,也可以定义全局的异常和结果,局部总是优于全局的,如果定义成全局,俺么可以为所有action所共享,而局部的异常与结果只能被当前的action所独享,不能为其他action所共享。

3、struts2应用的分层体系结构:

登录的整个流程程序:

login.jsp:

<%@ page language="java" import="java.util.*" 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">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'login.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>
    <form action="aas.action">
    	username:<input type="text" name="username"><br>
    	password:<input type="password" name="password"><br>
    	age:<input type="text" name="aaa">
    	date:<input type="text" name="date">
    	<input type="submit" value="submit">
    </form>
  </body>
</html>

LoginAction:

package com.cdtax.struts2;

import java.util.Date;

import com.cdtax.exception.PasswordException;
import com.cdtax.exception.UsernameException;
import com.cdtax.service.LoginService;
import com.cdtax.service.impl.LoginServiceImpl;
import com.opensymphony.xwork2.ActionSupport;



public class LoginAction extends ActionSupport
{
	private String username;
	private String password;
	private int age;
	private Date date;
	private LoginService loginService = new LoginServiceImpl();
	
	public Date getDate()
	{
		return date;
	}
	public void setDate(Date date)
	{
		this.date = date;
	}
	public int getAge()
	{
		return age;
	}
	public void setAge(int age)
	{
		this.age = age;
	}
	public String getUsername()
	{
		return username;
	}
	public void setUsername(String username)
	{
		this.username = username;
	}
	public String getPassword()
	{
		return password;
	}
	public void setPassword(String password)
	{
		this.password = password;
	}
	
	
	
	public String execute() throws Exception
	{
		
//		if(!"hello".equals(username))
//		{
//			throw new UsernameException("username invalid");
//		}
//		if(!"world".equals(password))
//		{
//			throw new PasswordException("password invalid!");
//		}
		
		if(this.loginService.isLogin(username, password))
		{
			return SUCCESS;
		}
		
		return INPUT;
	}
	
	public String myExecute()
	{
		System.out.println("myExecute invoke!");
		return SUCCESS;
	}
}

在这里,action增加了一个成员变量,作为对service的引用,execute方法进行业务逻辑判断,调用此service。

service接口定义对上层的服务:

package com.cdtax.service;

public interface LoginService
{
	public boolean isLogin(String username,String password);
}

具体的service实现:

package com.cdtax.service.impl;

import com.cdtax.service.LoginService;

public class LoginServiceImpl implements LoginService
{

	@Override
	public boolean isLogin(String username, String password)
	{
		if("hello".equals(username) && "world".equals(password))
		{
			return true;
		}
		
		return false;
	}

}

struts.xml:

		<action name="aas" class="com.cdtax.struts2.LoginAction">
			
			<result name="success">/result.jsp</result>
			<result name="input">/login.jsp</result>
		</action>

定义成功后的转向页面result.jsp。

4、struts2的模型驱动(Model Driven)

相对于上面的action模式,叫做属性驱动(Property Driven)

要想实现模型驱动,我们写的action还需要实现ModelDriven接口。

编写一个bean:Person,作为页面提交参数的对象

package com.cdtax.bean;

import java.util.Date;

public class Person
{
	private String username;
	private String password;
	private int age;
	private Date date;
	public String getUsername()
	{
		return username;
	}
	public void setUsername(String username)
	{
		this.username = username;
	}
	public String getPassword()
	{
		return password;
	}
	public void setPassword(String password)
	{
		this.password = password;
	}
	public int getAge()
	{
		return age;
	}
	public void setAge(int age)
	{
		this.age = age;
	}
	public Date getDate()
	{
		return date;
	}
	public void setDate(Date date)
	{
		this.date = date;
	}
	
}

编写模型驱动的Action:LoginAction2:

package com.cdtax.struts2;

import com.cdtax.bean.Person;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

public class LoginAction2 extends ActionSupport implements ModelDriven<Person>
{
	private Person person = new Person();
	
	@Override
	public Person getModel()
	{
		return person;
	}
	
	@Override
	public String execute() throws Exception
	{
		System.out.println(person.getUsername());
		return SUCCESS;
	}
}

在struts.xml中添加action:

<action name="login2" class="com.cdtax.struts2.LoginAction2">
	<result name="success">/result.jsp</result>
</action>

编写登录jsp页面:login.jsp

<%@ page language="java" import="java.util.*" 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">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'login.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>
    <form action="login2a.action">
    	username:<input type="text" name="username"><br>
    	password:<input type="password" name="password"><br>
    	age:<input type="text" name="aaa">
    	date:<input type="text" name="date">
    	<input type="submit" value="submit">
    </form>
  </body>
</html>

编写结果页面result.jsp

<%@ page language="java" import="java.util.*" 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">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'result.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>
    username:${requestScope.username } <br>
    password:${requestScope.password }<br>
    age:${requestScope.age }
    date:${requestScope.date }
    aaa:${requestScope.aaa }
  </body>
</html>

 

属性驱动与模型驱动的比较:

1)属性驱动灵活,准确;模型驱动不灵活,因为很多时候,页面提交过来的参数并不属于模型中的属性,也就是说页面所提交过来的参数与模型中的属性并不一致,这是很常见的情况。
2)模型驱动更加符合面向对象的编程风格,使得我们获得是对象而不是一个一个的离散的值。

小结:推荐使用属性驱动编写Action。

 

抱歉!评论已关闭.