专门做视频的网站/百度竞价代运营外包
日期: 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和setterpublic 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())){//假如满足邮箱非空且符合邮箱格式则保存数据到usersuser.setEmail(getEmail());}//判断手机号码是不是满足非空且是正确的手机号码:这只是模拟实现,在真正的开发中还需要验证手机,邮箱,用户名是不是已经被注册了的chenxkif(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和setterpublic 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())){//假如满足邮箱非空且符合邮箱格式则保存数据到usersuser.setEmail(getEmail());}//判断手机号码是不是满足非空且是正确的手机号码:这只是模拟实现,在真正的开发中还需要验证手机,邮箱,用户名是不是已经被注册了的chenxkif(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();//首先判断密码为空的话就返回falseif(!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的。