- 处理表单数据的Servlet,代码是这样子的:
//将表单的数据封装到formBean中
FormBeanformBean=WebUtils.request2Bean(request,FormBean.class);
//验证表单的数据是否合法,如果不合法就跳转回去注册的页面
if(formBean.validate()==false){
request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request,response);
return;
}
try{
//将表单的数据封装到User对象中
Useruser=WebUtils.request2Bean(request,User.class);
user.setId(WebUtils.makeId());
//调用service层的注册方法,实现注册
ServiceBussinessserviceBussiness=newUserServiceXML();
serviceBussiness.register(user);
}catch(Exceptione){
e.printStackTrace();
}
- 接下来我们测试一下吧!将所有的信息都按照规定的输入!
没有问题!已经将记录写到XML文件上了!
但是,如果我没有输入日期呢?
它抛出了错误!原因也非常简单:表单数据提交给Servlet,Servlet将表单的数据(Parameter中的数据)用BeanUtils封装到User对象中,当封装到日期的时候,发现日期为null,无法转换成日期对象!
那我们现在要怎么解决呢?
首先我们要明确:因为我们在设定的时候,已经允许了email和birthday可以为空,那么在DAO层就应该有相应的逻辑判断email和birthday是否为空!
if(user.getEmail()==null){
newElement.addAttribute("email","");
}else{
newElement.addAttribute("email",user.getEmail());
}
//如果不是空才格式化信息
if(user.getBirthday()!=null){
//日期返回的是指定格式的日期
SimpleDateFormatsimpleDateFormat=newSimpleDateFormat("yyyy-MM-dd");
Stringdate=simpleDateFormat.format(user.getBirthday());
newElement.addAttribute("birthday",date);
}else{
newElement.addAttribute("birthday","");
}
解决办法:
- Parameter中的数据如果是"",我就不把数据封装到User对象中,执行下一次循环!
publicstatic<T>Trequest2Bean(HttpServletRequesthttpServletRequest,Class<T>tClass){
try{
//创建tClass的对象
Tbean=tClass.newInstance();
//获取得到Parameter中全部的参数的名字
Enumerationenumeration=httpServletRequest.getParameterNames();
//日期转换器
ConvertUtils.register(newDateLocaleConverter(),Date.class);
//遍历上边获取得到的集合
while(enumeration.hasMoreElements()){
//获取得到每一个带过来参数的名字
Stringname=(String)enumeration.nextElement();
//获取得到值
Stringvalue=httpServletRequest.getParameter(name);
//如果Parameter中的数据为"",那么我就不封装到User对象里边去!执行下一次循环
if(value==""){
continue;
}else{
//把数据封装到Bean对象中
BeanUtils.setProperty(bean,name,value);
}
}
returnbean;
}catch(Exceptione){
e.printStackTrace();
thrownewRuntimeException("封装数据到Bean对象中出错了!");
}
}
- 效果:
将数据封装到User对象中还有另外一个办法:
- 我们知道BeanUtils有个copyProperties()方法,可以将某个对象的成员数据拷贝到另外一个对象的成员变量数据上(前提是成员变量的名称相同!)我们FormBean对象的成员变量名称和User对象的成员变量的名称是一致的!并且,前面在验证的时候,我们已经把Parameter中带过来的数据封装到了FormBean对象中了,所以我们可以使用copyProperties()方法!
- 使用该方法时,值得注意的是:第一个参数是拷贝到哪一个对象上(也就是User对象),第二个参数是被拷贝的对象(也就是formbean对象),口诀:后拷前....不要搞混了!!!!!(我就是搞混了,弄了很久...)
- 处理表单的Servlet完整代码如下:
//将表单的数据封装到formBean中
FormBeanformBean=WebUtils.request2Bean(request,FormBean.class);
//验证表单的数据是否合法,如果不合法就跳转回去注册的页面
if(formBean.validate()==false){
request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request,response);
return;
}
try{
//这是第一种--------------------------
/*User user = new User();
user.setId(WebUtils.makeId());
BeanUtils.copyProperties(user,formBean);*/
//------------------------------------------
//这是第二种
Useruser1=WebUtils.request2Bean(request,User.class);
user1.setId(WebUtils.makeId());
//-----------------------------------
//调用service层的注册方法,实现注册
ServiceBussinessserviceBussiness=newUserServiceXML();
serviceBussiness.register(user1);
}catch(Exceptione){
e.printStackTrace();
}
现在还有问题,如果我填写信息不合法,提交给服务器验证以后,服务器应该告诉用户哪个信息不合法,而不是直接把跳转回注册界面,把所有的信息全部清空,让用户重新填写!
我们应该这样做:当发现用户输入的信息不合法时,把错误的信息记录下来,等到返回注册页面,就提示用户哪里出错了!
- 在FormBean对象中添加一个HashMap集合(因为等会还要根据关键字把错误信息显示给用户!)
- FormBean的全部代码如下:
//表单提交过来的数据全都是String类型的,birthday也不例外!
privateStringusername;
privateStringpassword;
privateStringpassword2;
privateStringemail;
privateStringbirthday;
//记录错误的信息
privateHashMap<String,String>error=newHashMap<>();
/*用于判断表单提交过来的数据是否合法*/
publicbooleanvalidate(){
//用户名不能为空,并且要是3-8的字符 abcdABcd
if(this.username==null||this.username.trim().equals("")){
error.put("username","用户名不能为空,并且要是3-8的字符");
returnfalse;
}else{
if(!this.username.matches("[a-zA-Z]{3,8}")){
error.put("username","用户名不能为空,并且要是3-8的字符");
returnfalse;
}
}
//密码不能为空,并且要是3-8的数字
if(this.password==null||this.password.trim().equals("")){
error.put("password","密码不能为空,并且要是3-8的数字");
returnfalse;
}else{
if(!this.password.matches("\\d{3,8}")){
error.put("password","密码不能为空,并且要是3-8的数字");
returnfalse;
}
}
//两次密码要一致
if(this.password2!=null&&!this.password2.trim().equals("")){
if(!this.password2.equals(this.password)){
error.put("password2","两次密码要一致");
returnfalse;
}
}
//邮箱可以为空,如果为空就必须合法
if(this.email!=null&&!this.email.trim().equals("")){
if(!this.email.matches("\\w+@\\w+(\\.\\w+)+")){
error.put("email","邮箱不合法!");
returnfalse;
}
}
//日期可以为空,如果为空就必须合法
if(this.birthday!=null&&!this.birthday.trim().equals("")){
try{
DateLocaleConverterdateLocaleConverter=newDateLocaleConverter();
dateLocaleConverter.convert(this.birthday);
}catch(Exceptione){
error.put("birthday","日期不合法!");
returnfalse;
}
}
//如果上面都没有执行,那么就是合法的了,返回true
returntrue;
}
//.....各种的setter和getter
- 在跳转到注册页面之前,把formbean对象存到request域中。在注册页面就可以把错误的信息取出来(使用EL表达式)!
- 处理表单的Servlet的部分代码
//验证表单的数据是否合法,如果不合法就跳转回去注册的页面
if(formBean.validate()==false){
//在跳转之前,把formbean对象传递给注册页面
request.setAttribute("formbean",formBean);
request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request,response);
return;
}
- 在注册页面中,使用EL表达式把错误的信息写出来
测试:
效果: