Struts学习总结(三)---使用Struts实现一个模拟前后台的注册功能实现。

日期: 2016-8-30


内容:使用Struts实现一个模拟前后台的注册功能实现。



这里由于只是模拟试下用户登录实现,所以没有数据库的持久化操作,只是简单的模拟数据库操作持久化数据。


一、 用户实体类的设计:

Users.java

package com.onlyone.struts.register.action;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import com.onlyone.struts.register.entity.Users;
import com.onlyone.www.util.util_char.StringOperationUtil;
import com.onlyone.www.util.util_date.DateOperationUtil;
import com.opensymphony.xwork2.ActionSupport;

public class UserRegisterAction extends ActionSupport {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * 这里测试使用属性驱动的方式获取前端传过来的数据
	 * 
	 * 使用属性驱动的一个好处就是,在前端的画面内容的<input>框中可以简单的写需要传到后台的属性名称就可以了。
	 * 但是弊端就是增大了action中的代码量。这里又把Users里面的字段信息重新写了一遍,增大了不可以复用的代码,这就叫做冗余代码
	 */
	
	/**************************************************获取前端传过来的数据*********************************************************/
	// 用户名
	private String userName;

	// 密码
	private String password;

	// 电话号码
	private String phoneNumber;

	// 邮箱
	private String email;

	// 确认密码
	private String rePassword;

	// 生成对应的getter和setter
	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 getPhoneNumber() {
		return phoneNumber;
	}

	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getRePassword() {
		return rePassword;
	}

	public void setRePassword(String rePassword) {
		this.rePassword = rePassword;
	}
	/**************************************************获取前端传过来的数据*********************************************************/
	
	//为了能够将注册信息保存在数据库中,合理需要获得一个Users对象的实例
	public Users user = new Users();
	
	//获得字符串操作类实例
	StringOperationUtil sou = new StringOperationUtil();
	
	//获得日期操作类的实例
	DateOperationUtil dou = new DateOperationUtil();
	
	//声明两个返回值
	
	public String register() throws Exception {
		/*将数据整理之后持久化到数据库*/
		//设置用户编号:用户编号是具有唯一性的,因此使用UUID生成一个唯一的值
		user.setUid(UUID.randomUUID().toString().replaceAll("_", ""));
		
		//判断用户名假如符合规范的话就保存:这里只是简单的测试非空即符合要求
		//用户名不可以有一些非法字符:在这里省略这部分内容
		if(sou.isNotEmpty(getUserName()))
		{
			//添加用户名
			user.setUserName(getUserName());
		}
		
		//判断邮箱是不是满足邮箱格式并且非空
		if(sou.isNotEmpty(getEmail()) && sou.isEmail(getEmail()))
		{
			//假如满足邮箱非空且符合邮箱格式则保存数据到users
			user.setEmail(getEmail());
		}
		
		//判断手机号码是不是满足非空且是正确的手机号码:这只是模拟实现,在真正的开发中还需要验证手机,邮箱,用户名是不是已经被注册了的chenxk
		if(sou.isNotEmpty(getPhoneNumber()) && sou.isMobileNo(getPhoneNumber()))
		{
			//保存手机
			user.setPhoneNumber(getPhoneNumber());
		}
		
		//判断用户密码:用户密码一般要求长度在6~20位数,并且两次输入的密码要相等
		if(sou.isRightPassword(getPassword()) && getPassword().equals(getRePassword()))
		{
			//保存密码
			user.setPassword(getPassword());
		}
		
		/*设置创建日期,删除日期,更新日期,删除标志位等信息*/
		//获得格式化之后的当前日期
		String date = dou.toDateString(new Date(), "yyyy-MM-dd: HH:mm:ss");
		//设置创建日期
		user.setCreateDateTime(date);
		//设置删除日期为null:因为这条记录刚创建还尚未执行删除(逻辑删除)
		user.setDeleteDateTime(null);
		//设置更新时间为创建时间
		user.setUpdateDateTime(date);
		//设置删除标志位为0(0:表示未删除,1:表示删除)
		user.setDeleteFlag("0");
		
		//数据设置完成之后保存数据库执行持久化操作
		/**
		 * 假如使用的是SSH框架的话,应该是action层去调用service层,service层去调用dao层,执行数据库持久
		 * 但是由于这里未使用到数据库操作,因此就将信息打印在屏幕上即可
		 */
		//打印信息
		System.out.println("用户信息: " +user);
		
		
		return ActionSupport.SUCCESS;
	}
}
用户实体类的设计基本上就是对应数据库中的某一张具体的表,他是和数据库表相对应的,包含一些基本数据信息。


二、用户Action设计:

UserRegisterAction.java

package com.onlyone.struts.register.action;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import com.onlyone.struts.register.entity.Users;
import com.onlyone.www.util.util_char.StringOperationUtil;
import com.onlyone.www.util.util_date.DateOperationUtil;
import com.opensymphony.xwork2.ActionSupport;

public class UserRegisterAction extends ActionSupport {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * 这里测试使用属性驱动的方式获取前端传过来的数据
	 * 
	 * 使用属性驱动的一个好处就是,在前端的画面内容的<input>框中可以简单的写需要传到后台的属性名称就可以了。
	 * 但是弊端就是增大了action中的代码量。这里又把Users里面的字段信息重新写了一遍,增大了不可以复用的代码,这就叫做冗余代码
	 */
	
	/**************************************************获取前端传过来的数据*********************************************************/
	// 用户名
	private String userName;

	// 密码
	private String password;

	// 电话号码
	private String phoneNumber;

	// 邮箱
	private String email;

	// 确认密码
	private String rePassword;

	// 生成对应的getter和setter
	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 getPhoneNumber() {
		return phoneNumber;
	}

	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getRePassword() {
		return rePassword;
	}

	public void setRePassword(String rePassword) {
		this.rePassword = rePassword;
	}
	/**************************************************获取前端传过来的数据*********************************************************/
	
	//为了能够将注册信息保存在数据库中,合理需要获得一个Users对象的实例
	public Users user = new Users();
	
	//获得字符串操作类实例
	StringOperationUtil sou = new StringOperationUtil();
	
	//获得日期操作类的实例
	DateOperationUtil dou = new DateOperationUtil();
	
	//声明两个返回值
	
	public String register() throws Exception {
		/*将数据整理之后持久化到数据库*/
		//设置用户编号:用户编号是具有唯一性的,因此使用UUID生成一个唯一的值
		user.setUid(UUID.randomUUID().toString().replaceAll("_", ""));
		
		//判断用户名假如符合规范的话就保存:这里只是简单的测试非空即符合要求
		//用户名不可以有一些非法字符:在这里省略这部分内容
		if(sou.isNotEmpty(getUserName()))
		{
			//添加用户名
			user.setUserName(getUserName());
		}
		
		//判断邮箱是不是满足邮箱格式并且非空
		if(sou.isNotEmpty(getEmail()) && sou.isEmail(getEmail()))
		{
			//假如满足邮箱非空且符合邮箱格式则保存数据到users
			user.setEmail(getEmail());
		}
		
		//判断手机号码是不是满足非空且是正确的手机号码:这只是模拟实现,在真正的开发中还需要验证手机,邮箱,用户名是不是已经被注册了的chenxk
		if(sou.isNotEmpty(getPhoneNumber()) && sou.isMobileNo(getPhoneNumber()))
		{
			//保存手机
			user.setPhoneNumber(getPhoneNumber());
		}
		
		//判断用户密码:用户密码一般要求长度在6~20位数,并且两次输入的密码要相等
		if(sou.isRightPassword(getPassword()) && getPassword().equals(getRePassword()))
		{
			//保存密码
			user.setPassword(getPassword());
		}
		
		/*设置创建日期,删除日期,更新日期,删除标志位等信息*/
		//获得格式化之后的当前日期
		String date = dou.toDateString(new Date(), "yyyy-MM-dd: HH:mm:ss");
		//设置创建日期
		user.setCreateDateTime(date);
		//设置删除日期为null:因为这条记录刚创建还尚未执行删除(逻辑删除)
		user.setDeleteDateTime(null);
		//设置更新时间为创建时间
		user.setUpdateDateTime(date);
		//设置删除标志位为0(0:表示未删除,1:表示删除)
		user.setDeleteFlag("0");
		
		//数据设置完成之后保存数据库执行持久化操作
		/**
		 * 假如使用的是SSH框架的话,应该是action层去调用service层,service层去调用dao层,执行数据库持久
		 * 但是由于这里未使用到数据库操作,因此就将信息打印在屏幕上即可
		 */
		//打印信息
		System.out.println("用户信息: " +user);
		
		
		return ActionSupport.SUCCESS;
	}
}


三、Web.xml配置文件配置:

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
    <!-- 配置struts2的filter和filter-mapping -->
    <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>
</web-app>


四、画面内容:

  1、register.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<!--
        	作者:offline
        	时间:2016-08-04
        	描述:引入bootstrap和jquery(由于bootstrap的js是依赖于jquery实现的,因此在导入bootstrap.min.js之前应该先引入jquery)
        -->
        <link rel="stylesheet" href="<%=request.getContextPath() %>/bootstrap/css/bootstrap.min.css" />
        <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery/jquery-1.8.3.js" ></script>
        <script type="text/javascript" src="<%=request.getContextPath() %>/bootstrap/js/bootstrap.min.js" ></script>
        
        <!--
        	作者:offline
        	时间:2016-08-08
        	描述:编写输入框验证功能。
        -->
        <script type="text/javascript">
        	$(document).ready(function(){
        		$("#submitStyle").click(function(){
        			//获得用户名输入框的内容
        			var userEmail = $("#userEmail").val();
        			//获得手机号的内容
        			var phoneNumber = $("#userPhone").val();
        			//获取密码的内容
        			var password1 = $("#userPassword").val();
        			//获取确认密码的内容
        			var password2 = $("#reUserPassword").val();
        			
        			//Email的正则表达式验证
        			var reg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/;
        			//获得验证后的结果
        			var flag = reg.test(userEmail);
        			alert("是不是邮箱: "+flag);
          			
        			//输入框无值就将注册按钮置为灰色
        			$("#userEmail,#phoneNumber,#password1,#password2").bind('input propertychange', function() {
					    $('#submitStyle').attr("disabled",true);
					});
        		});
        	});
        </script>
        <!--
        	作者:offline
        	时间:2016-08-04
        	描述:引入外部样式表
        -->
        <link rel="stylesheet" href="<%=request.getContextPath() %>/css/register/register.css" />
		<meta charset="utf-8" />
		<title>user register block</title>
	</head>
	<body>
		<!--
        	作者:offline
        	时间:2016-08-04
        	描述:编写用户注册表单
        -->
        <div class="formStyle">
        	<form class="form-horizontal" action="userRegisterAction" id="userRegister" method="post">
	        	<div class="formInput">
	        		<div class="control-group success">
					    <div class="controls">
					    	<div class="input-prepend">
					    		<span class="add-on imageStyle"><i class="icon-envelope iconStyle"></i></span>
				      			<input type="text" class="span4 textStyle checkVal" name="userName" id="userName" placeholder="userName">
					    	</div>
					    </div>
				    </div>
	        		<div class="control-group success">
					    <div class="controls">
					    	<div class="input-prepend">
					    		<span class="add-on imageStyle"><i class="icon-envelope iconStyle"></i></span>
				      			<input type="text" class="span4 textStyle checkVal" name="email" id="userEmail" placeholder="Email">
					    	</div>
					    </div>
				    </div>
				    <div class="control-group success">
					    <div class="controls">
					    	<div class="input-prepend">
					    		<span class="add-on imageStyle"><i class="icon-list-alt iconStyle"></i></span>
					    		<input type="text" class="span4 textStyle checkVal" name="phoneNumber" id="userPhone" placeholder="Phone">
					    	</div>
					    </div>
				    </div>
					<div class="control-group success">
					    <div class="controls">
							<div class="input-prepend">
								<span class="add-on imageStyle"><i class="icon-lock iconStyle"></i></span>
								<input type="password" class="span4 textStyle checkVal" name="password" id="userPassword" placeholder="password">
							</div>
					    </div>
				    </div>
				    <div class="control-group success">
					    <div class="controls">
					    	<div class="input-prepend">
					    		<span class="add-on imageStyle"><i class="icon-lock iconStyle"></i></span>
					    		<input type="password" class="span4 textStyle checkVal" name="rePassword" id="reUserPassword" placeholder="rePassword">
					    	</div>
					    </div>
				    </div>
				    <div class="control-group">
					    <div class="controls">
					      	<!--<input type="submit" class="btn btn-success" id="submitStyle" value="REGISTER" >-->
					      	<button class="btn btn-success" id="submitStyle" value="REGISTER">REGISTER</button>
					    </div>
				    </div>
	        	</div>
	        </form>
        </div>
        
	</body>
</html>

2、register_success.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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>
	<h1>Hello!<span style="color:red;">${request.userName}</span>欢迎注册本网张!</h1>
</body>
</html>


3、register_failure.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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>
	<center>
		<h1>Sorry! 用户信息错误,注册失败!</h1>
	</center>
</body>
</html>


五、使用到的工具类:

1、字符串处理工具类:

package com.onlyone.www.util.util_char;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符及其字符串操作工具类
 * @author cj(copy jobs)
 *
 */
public class StringOperationUtil {

	/**
	 * 功能描述: 将执行的字符串转换为用下划线分割的字符串:
	 * 比如: HelloWOrld转换之后的字符串就是hello_world;
	 * @param targetStr 需要转换的字符串
	 * @return 返回结果
	 */
	public static String camelToSnake(final String targetStr) {
		String convertedStr =
				targetStr.replaceAll("([A-Z]+)([A-Z][a-z])", "$1_$2").replaceAll("([a-z])([A-Z])", "$1_$2"); 
		return convertedStr.toLowerCase();
	}
	
	/**
	 * 功能描述: 判断一个字符串是不是为空,当为空的时候就返回true否则返回false
	 * @param value 需要判断的字符串
	 * @return 返回boolean值
	 */
	public static boolean isEmpty(final String value)
	{
		return (value == "") || (value.length() == 0);
	}
	
	/**
	 * 功能描述: 判断一个字符串是不是为空,当为空的时候就返回false否则返回true
	 * @param value
	 * @return
	 */
	public static boolean isNotEmpty(final String value)
	{
		return (value != null) && (value.length() > 0);
	}
	
	/**
	 * 功能描述: 假如字符串不为空或者全部为空格组成的话返回false,假如为空字符串的话返回true
	 * @param value 判断的字符串
	 * @return 返回的boolean值
	 */
	public static boolean isBlankOrWhSpace(final String value)
	{
		return isEmpty(value) || value.matches("^\\s$");
	}
	
	/**
	 * 判断字符串是不是为空:返回false,否则假如为空或者或者全部由空格组成返回true
	 * @param value
	 * @return
	 */
	public static boolean isBlankOrAllSpace(final String value)
	{
		return isEmpty(value) || value.matches("^\\s|^[\\s\\p{Zs}]+$");
	}
	
	/**
	 * 判断指定的对象是不是为空:这里没有局限于一个字符串了,而是可以传递一个对象
	 * @param str
	 * @return
	 */
	public static boolean isEmpty(final Object str)
	{
		return (str == null) || ((str instanceof CharSequence) && str.toString().isEmpty());
	}
	
	
	/**
	 * 功能描述: 将指定的字符串转换为驼峰式的大小写:比如Hello_world_welcome_to_home---->helloWorldWelcomeToHome;
	 * @param targetStr 需要转化的字符创
	 * @return 转换之后的字符串
	 */
	public static String snakeToCamel(final String targetStr)
	{
		Pattern pattern = Pattern.compile("_([a-z])");
		Matcher matcher = pattern.matcher(targetStr.toLowerCase());
		
		//初始化一个字符容器
		StringBuffer sb = new StringBuffer(targetStr.length());
		
		while(matcher.find())
		{
			matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
		}
		matcher.appendTail(sb);
		
		return sb.toString();
	}
	
	/**
	 * 将字符串转换为无隐式转换
	 * @param value
	 * @return
	 * @throws ClassCastException
	 */
	public static String valueOf(final Object value) throws ClassCastException {
		if (value == null) {
			return null;
		} else if (value instanceof CharSequence) {
			if (value.toString().isEmpty()) {
				return null;
			}
			return value.toString();
		} else {
			throw new ClassCastException();
		}
	}
	
	/**
	 * 功能描述: 将指定的字符串用指定的连接字符连接起来
	 * @param slashStr
	 * @param strings
	 * @return
	 */
	public static String combineStr(final String slashStr, final String... args)
	{
		//初始化一个放字符的容器
		StringBuilder sb = new StringBuilder();
		
		for(int i = 0;i<args.length;i++)
		{
			if(!isBlankOrWhSpace(args[i]))
			{
				if(i == args.length - 1)
				{
					//假如是最后一个字符串就直接添加在末尾而不需要添加分割符
					sb.append(args[i]);
				}
				else
				{
					//在添加字符串之后再添加指定的分割符号
					sb.append(args[i]).append(slashStr);
				}
			}
		}
		return sb.toString().trim();
	}
	
	/**
	 * 判断邮箱是不是符合格式要求
	 * 
	 * @param email: 需要判断的邮箱
	 * @return:返回的结果,邮箱格式正确就返回true否则返回false
	 * 
	 */
	public static boolean isEmail(final String email)
	{
		//邮箱判断正则表达式
		String checkEmail = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
		
		//邮箱验证
		Pattern regex = Pattern.compile(checkEmail);
		
		Matcher matcher = regex.matcher(email);
		
		//返回验证的结果
		return matcher.matches();
	}
	
	/**
	 * 判断手机是不是正确的手机格式: 
	 * @param phoneNumber : 需要判断的手机号码
	 * @return:返回判断结果,如果是正确的手机则返回true,否则返回false
	 */
	public static boolean isMobileNo(final String phoneNumber)
	{
		//判断手机号码的正则表达式
		String checkPhone = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
		
		Pattern pattern = Pattern.compile(checkPhone);
		
		Matcher matcher = pattern.matcher(phoneNumber);
		
		//返回验证的结果
		return matcher.matches();
	}
	
	/**
	 * 判断密码的格式不不是正确
	 * @param password : 需要判断的密码
	 * @return:返回判断后的结果:true密码判断正确,否则判断不正确
	 */
	public static boolean isRightPassword(final String password)
	{
		//返回标志位
		boolean returnFlag;
		
		//获得密码的长度:首先取出两边的空格然后获得长度,密码不可以有空格
		int length = (password.trim()).length();
		
		//首先判断密码为空的话就返回false
		if(!isNotEmpty(password))
		{
			return false;
		}else{
			//密码位数不在6~20位之间的话就返回错误
			if(length>20 || length<6)
			{
				returnFlag = false;
			}else
			{
				returnFlag = true;
			}
		}
		return returnFlag;
	}
	
}



2、日期处理工具类:

package com.onlyone.www.util.util_date;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.el.parser.ParseException;

import com.onlyone.www.util.util_char.StringOperationUtil;

/**
 * 日期操作工具类
 * @author cj(copy jobs)
 *
 */
public class DateOperationUtil {
	/**
	 * 在获得的一个日期的基础上追加指定的天数。
	 * @param specifieDay
	 * @param day
	 * @return
	 */
	public static Date calucateDate(final Date specifieDay,final int day)
	{
		//得到日历类的实例
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(specifieDay);
		
		//在当前日期上追加指定天数
		calendar.add(Calendar.DAY_OF_MONTH, day);
		
		return calendar.getTime();
	}
	
	/**
	 * 功能介绍: 将日期格式化成指定的格式
	 * @param dt
	 * @param formatType
	 * @return
	 */
	public static Date toDate(final String dt, String formatType)
	{
		//获得日期格式化实例
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(formatType);
		
		try{
			//假如日期合法
			if(!StringOperationUtil.isBlankOrAllSpace(dt))
			{
				Date date = simpleDateFormat.parse(dt);
				
				return date;
			}
		}
		catch (java.text.ParseException e) {
			e.printStackTrace();
		}
		return null; 
	}
	
	/**
	 * 功能介绍: 将日期格式化为指定格式的形式
	 * @param date
	 * @param formatType
	 * @return
	 */
	public static String toDateString(final Date date,String formatType)
	{
		if(StringOperationUtil.isEmpty(date.toString()))
		{
			return "";
		}
		
		//获得格式化格式
		SimpleDateFormat sdf = new SimpleDateFormat(formatType);
		
		return sdf.format(date);
	}
	

	/**
	 * 将日期格式化为指定格式的日期
	 * @param date 需要格式化的日期
	 * @param formatType 格式化类型
	 * @return
	 */
	public String formatDate(Date date,String formatType)
	{
		//获得一个SimpleDateFormat对象
		SimpleDateFormat sdf = new SimpleDateFormat(formatType);
		
		String formatedDate = sdf.format(date);
		
		//将格式化之后的日期返回
		return formatedDate;
	}
}


六、测试结果截图显示:

1、启动Tomcat:



2、画面访问:



3、后台log:


七、总结:

struts2是一个强大并且成熟的框架,为开发提供了很大的便利,但是目前的开发形式使用Spring MVC的偏多。但是个人还是比较喜欢struts2的。














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值