package org.springside.core.commons; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.beans.propertyeditors.CustomNumberEditor; import org.springframework.util.Assert; import org.springframework.validation.BindingResult; import org.springframework.validation.ValidationUtils; import org.springframework.validation.Validator; import org.springframework.web.bind.ServletRequestDataBinder; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.multiaction.MultiActionController; import org.springframework.web.util.WebUtils; import org.springside.core.utils.DateUtil; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * SpringSide Multiaction Controller的基类. * 对Spring的MultiActionController作了少量扩展,主要是对数据绑定校验的扩展, * 同时增加了{@link #saveMessage(HttpServletRequest, String) },一个{@link #rendText(HttpServletResponse,String)} * * @author calvin */ abstract public class BaseController extends MultiActionController { /** * 不设置任何action参数时的默认 Action. * 该函数名由xxx-servlet.xml配置文件中的 methodNameResolver节点配置. */ abstract public ModelAndView index(HttpServletRequest request, HttpServletResponse response) throws Exception; /** * 初始化binder的回调函数. * 默认以DateUtil中的日期格式设置DateEditor及允许Integer,Double的字符串为空. * * @see MultiActionController#createBinder(HttpServletRequest,Object) */ protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) { SimpleDateFormat dateFormat = new SimpleDateFormat(DateUtil.getDatePattern()); binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true)); binder.registerCustomEditor(Integer.class, new CustomNumberEditor(Integer.class, true)); binder.registerCustomEditor(Double.class, new CustomNumberEditor(Double.class, true)); } /** * 从Request中绑定对象并进行校验. * Spring MVC中的Bind函数未完全符合需求,因此参考原代码进行了扩展 * * @return 校验错误 * @see #preBind(HttpServletRequest,Object,ServletRequestDataBinder) */ protected BindingResult bindObject(HttpServletRequest request, Object command) throws Exception { Assert.notNull(command); //创建Binder ServletRequestDataBinder binder = createBinder(request, command); //回调函数,供子类扩展对binder做出更进一步设置,并进行不能由binder自动完成的绑定 preBind(request, command, binder); //绑定 binder.bind(request); //校验 Validator[] validators = getValidators(); if (validators != null) { for (Validator validator : validators) { if (validator.supports(command.getClass())) { ValidationUtils.invokeValidator(validator, command, binder.getBindingResult()); } } } return binder.getBindingResult(); } /** * 回调函数,在BindObject的最开始调用。负责 * 1.继续对binder进行设置 * 2.绑定一些不能由Binder自动绑定的属性.这些属性通常是需要查询数据库来获得对象的绑定. * 要注意设置这些属性为disallow. eg. *
binder.setDisallowedFields(new String[]{"image","category"});
*
* @see #bindObject(HttpServletRequest, Object)
* @see org.springframework.web.bind.ServletRequestDataBinder#setDisallowedFields(String[])
* @see org.springside.bookstore.admin.web.BookManageController#preBind(javax.servlet.http.HttpServletRequest, Object, org.springframework.web.bind.ServletRequestDataBinder)
*/
protected void preBind(HttpServletRequest request, Object object, ServletRequestDataBinder binder) throws Exception {
//在子类实现
}
/**
* 回调函数,声明CommandName--对象的名字,默认为首字母小写的类名.
*
* @see #bindObject(HttpServletRequest, Object)
*/
protected String getCommandName(Object command) {
return StringUtils.uncapitalize(command.getClass().getSimpleName());
}
/**
* 增加validator.
* 除了Spring配置文件注入的validators数组外,可以用此函数在子类的代码里再添加新的validator.
*/
protected void addValidator(Validator validator) {
ArrayUtils.add(getValidators(), validator);
}
/**
* 向View层传递message时将message放入httpSession的messages变量中.
* 放在session中能保证message即使Redirect也不会消失。需配合{@link org.springside.core.web.MessageFilter MessageFilter}使用
*/
protected void saveMessage(HttpServletRequest request, String message) {
if (StringUtils.isNotBlank(message)) {
List messages = (List) WebUtils.getOrCreateSessionAttribute(request.getSession(), "messages", ArrayList.class);
messages.add(message);
}
}
/**
* 直接向客户端返回Content字符串,不用通过View页面渲染.
*/
protected void rendText(HttpServletResponse response, String content) throws IOException {
response.setCharacterEncoding("UTF-8");
response.getWriter().write(content);
}
}