数据验证

数据验证是MVC框架中一个重要部分。

大体过程为:

从UI层收集数据,传送到ActionHandler层,在正式调用逻辑处理之前会首先校验,如果校验合格则进入业务处理,否则会将数据校验失败的部分封装成Error Message,存到Request中,ActionHandler返回到原始UI界面,UI界面获取Error Message显示校验失败的部分。根据UI所在地域的不同,从ActionHandler返回的Error Message需要以不同的语言显示,这就是Error Message的国际化显示。

过程分解:

1. 用户在表单内填写数据,点击提交。

2.请求被传送到总控制器。

3.总控制器找到ActionHandler。

4.调用ActionHandler中的验证模板方法进行参数校验。

5.如果校验成功,进入ActionHandler的execute方法;

6.如果校验失败,识别出校验失败项,从资源文件中读取失败提示消息,将消息封装到Message对象,存入Request。控制流跳转到原始UI界面,将消息渲染。


我们从5,6步开始。校验。


因为校验工作是每个ActionHandler中都需要处理的,因此从ActionHandler入手,将验证,执行业务逻辑写成模板方法,这样每一个具体的ActionHandler就可以根据自己的需求来重写验证逻辑,形成一套固定的处理流程。

有关BaseActionHandler中final方法的使用目的,可以参考Java final 关键字

public abstract class BaseActionHandler {

  public abstract boolean validate(HttpServletRequest request, HttpServletResponse response);

  public abstract void handleInvalidValidation(HttpServletRequest request, HttpServletResponse response);

  public abstract void execute(HttpServletRequest request, HttpServletResponse response);

  public final void _execute(HttpServletRequest request, HttpServletResponse response) {
    if (this.validate(request, response)) {
      this.execute(request, response);
    } else {
      this.handleInvalidValidation(request, response);
    }
  }
}

public class DemoActionHandler extends BaseActionHandler {

  @Override
  public boolean validate(HttpServletRequest request, HttpServletResponse response) {
    String title = request.getParameter("title");
    String content = request.getParameter("content");
    if (title == null || title.equals("")) {
      return false;
    }
    if (content == null || content.equals("")) {
      return false;
    }
    return true;
  }

  @Override
  public void handleInvalidValidation(HttpServletRequest request, HttpServletResponse response) {

    String baseName = "org/wales/message/validate";
    ResourceBundle resourceBundle = ResourceBundle.getBundle(baseName, Locale.ENGLISH);
    String errorMsg = resourceBundle.getString("validation.failed");

    request.setAttribute("errors", errorMsg);
    try {
      request.getRequestDispatcher("/index.jsp").forward(request, response);
    } catch (ServletException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override
  public void execute(HttpServletRequest request, HttpServletResponse response) {
    request.setAttribute("message", "Hi Wales");
    try {
      request.getRequestDispatcher("/home.jsp").forward(request, response);
    } catch (ServletException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

}


 

关于数据验证,一个是Validate,一个是验证失败之后的handleInvalidValidation。

先来看验证的过程。

最直接的方法就是获取HttpServletRequest,从request中挨个找出参数,然后用逻辑验证参数是否符合业务需求。

  @Override
  public boolean validate(HttpServletRequest request, HttpServletResponse response) {
    String title = request.getParameter("title");
    String content = request.getParameter("content");
    if (title == null || title.equals("")) {
      return false;
    }
    if (content == null || content.equals("")) {
      return false;
    }
    return true;
  }

 原始的验证虽然可行,但取值验证的工作量太大,在不用任何MVC框架之前, 
Commons Validator 是个不错的选择。 

如果用了流行的MVC框架,Stru2或者Spring MVC,这些验证工作就简单的多,有关Spring MVC的验证,我们后续分解。

如何处理handleInvalidValidation?

面对验证失败,最简单的处理方法是在界面上显示一个笼统的验证失败信息,高级的则是能明确具体哪一个项目验证失败,然后配上验证失败的提示信息。

我们实现最简单的情况:

  @Override
  public void handleInvalidValidation(HttpServletRequest request, HttpServletResponse response) {

    String baseName = "org/wales/message/validate";
    ResourceBundle resourceBundle = ResourceBundle.getBundle(baseName, Locale.ENGLISH);
    String errorMsg = resourceBundle.getString("validation.failed");

    request.setAttribute("errors", errorMsg);
    try {
      request.getRequestDispatcher("/index.jsp").forward(request, response);
    } catch (ServletException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

将验证失败的error message存入request,这样就能在原始的表单页面中读取errors参数,如果该参数有值,则显示error message。

<%@ 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>Demo</title>
</head>
<body>
	<%
	if(request.getAttribute("errors") != null){
	  String errorMsg = request.getAttribute("errors").toString();
	%>
	<%= errorMsg %>
	<%
	}
	%>
	<form action="/demo/controller" method="post">
		Title:<input type="text" name="title" value="please input title" /><br/>
		Content:<input type="text" name="content" value="please input content" /><br/>
		<input type="submit" name="submit" value="submit" />
	</form>
</body>
</html>

以上我们用最原始的方法构建了一个具有验证模块的处理框架,用Spring MVC中处理流程类似,只是验证部分被高度封装了。下方是Spring MVC的样例。

  @RequestMapping(value = "/team", method = RequestMethod.POST)
  public String createTeam(@Valid @ModelAttribute("team") Team team, BindingResult bindingResult, Model model) {
    if (bindingResult.hasErrors()) {
      return "team/create";
    }

    database.put("key-" + team.getTeamId(), team);
    model.addAttribute("teams", database);
    return "team/teams";
  }
@Controller
public class ValidationController {

	// enforcement of constraints on the JavaBean arg require a JSR-303 provider on the classpath
	
	@RequestMapping("/validate")
	public @ResponseBody String validate(@Valid JavaBean bean, BindingResult result) {
		if (result.hasErrors()) {
			return "Object has validation errors";
		} else {
			return "No errors";
		}
	}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值