`
oywl2008
  • 浏览: 1003631 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

基于Spring MVC的CRUD控制器

 
阅读更多

基于Spring MVC的CRUD控制器

package cn.jcwx.core.web;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.validation.Validator;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.util.WebUtils;

import cn.jcwx.core.service.HibernateDao;
import cn.jcwx.core.service.support.ScrollResult;
import cn.jcwx.core.tag.table.TableTag;
import cn.jcwx.core.utils.BeanUtils;
import cn.jcwx.core.utils.StringUtils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;

/**
 * 实现了CRUD功能的Controller <br/>
 * 建议子类重写回调函数 <br/><br/>
 *
 * 保存或更新实体:save.do <br/>
 * 删除实体:remove.do <br/>
 * 查询单个实体信息:show.do <br/>
 *
 * @author EwinLive@gmail.com
 * @date 2011-2-23
 * @version 1.0
 */
public abstract class CrudController<T>{
 @Resource
 private Validator validator;
 
 protected static final Logger logger = LoggerFactory.getLogger(CrudController.class);

 protected Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
 
 protected String className;
 
 protected String entityName;
 
 protected T entity;
 
 protected String listView = null;

 protected String formView = null;
 
 public static final String successView = "/share/common/success.jsp";
 
 public CrudController() {
  className = BeanUtils.getSuperClassGenricType(getClass()).getName();
  entityName = StringUtils.substringAfterLast(className, ".");
  entityName = entityName.substring(0, 1).toLowerCase() + entityName.substring(1, entityName.length());
  listView = "list.jsp";
  formView = "form.jsp";
 }

 /**
  * 获取实体服务类的实例
  * @return
  */
 protected abstract HibernateDao<T, Integer> getEntityService();
 
 @InitBinder
 public void initBinder(WebDataBinder binder) {
  SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
  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));
  binder.registerCustomEditor(MultipartFile.class, new ByteArrayMultipartFileEditor());
 }
 
 /**
  * 根据默认的请求参数进行分页查询。
  * 回调函数:beforeDoList(...), afterDoList(...)
  * @param request 当前的HttpServletRequest
  * @param filterMap 过滤条件,如:filterMap.put("id_EQ_I", 12)。    可以为null
  *      
  * @param sortMap 排序条件,如:sortMap.put("id", "desc"); asc为正序,desc为倒序。    可以为null
  * @return ScrollResult<T>
  */
 @RequestMapping(value = "list.do")
 public ModelAndView doList(HttpServletRequest request, HttpServletResponse response){
  ModelAndView mav = new ModelAndView(listView);
  
  //提取客户端可能传送的过滤条件和排序条件
  Map<String, Object> filterMap = WebUtils.getParametersStartingWith(request, "search_");
  Map<String, Object> sortMap = WebUtils.getParametersStartingWith(request, "sort_");
  
  Integer no, size;
  String pSize = (String) request.getParameter("p_size");
  String pNo = (String) request.getParameter("p_no");
  if (StringUtils.isEmpty(pNo)) {
   no = 1;
  } else {
   no = Integer.parseInt(pNo);
  }
  
  if (StringUtils.isEmpty(pSize)) {
   size = TableTag.DEF_ROWS_MIN;
  } else {
   size = Integer.parseInt(pSize);
  }
  
  beforeList(request, filterMap, sortMap);
  
  ScrollResult<T> result = (ScrollResult<T>) getEntityService().findScrollResult(no, size, filterMap, sortMap);
  mav.addObject(entityName + "s", result.getResultList());
  mav.addObject("totalRows", result.getTotal());
  
  afterList(request, response, mav);
  return mav;
 }
 
 /**
  * 分页查询(list.do)回调函数,该方法在执行查询之前调用。可以继续添加过滤条件和排序条件。
  * @param request
  * @param filterMap
  * @param sortMap
  */
 protected void beforeList(HttpServletRequest request, Map<String, Object> filterMap, Map<String, Object> sortMap){};
 
 /**
  * 分页查询(list.do)回调函数,该方法在返回视图之前调用。可以继续添加返回信息。
  * @param request
  * @param response
  * @param mav
  */
 protected void afterList(HttpServletRequest request, HttpServletResponse response, ModelAndView mav){};
 
 /**
  * 定向到新增实体的表单界面<br/>
  * 回调函数:onCreate(...)
  * @param request
  * @param response
  * @return
  * @throws Exception
  */
 @RequestMapping(value = "create.do")
 public ModelAndView doCreate(HttpServletRequest request, HttpServletResponse response) throws Exception {
  ModelAndView mav = new ModelAndView(formView);
  onCreate(request,response, mav);
  return mav;
 }
 
 /**
  * 新增实体的表单界面(create.do)回调函数。该方法在返回视图之前调用,可以继续添加返回信息。
  * @param request
  * @param response
  * @param mav
  */
 protected void onCreate(HttpServletRequest request, HttpServletResponse response, ModelAndView mav){};
 
 /**
  * 表单编辑界面
  */
 @RequestMapping(value = "edit.do")
 public ModelAndView edit(HttpServletRequest request, HttpServletResponse response) throws Exception {
  ModelAndView mav = new ModelAndView(formView);
  String id = request.getParameter("id");
  if (StringUtils.isNotEmpty(id)) {
   entity = getEntityService().get(Integer.valueOf(id));
   mav.addObject(entityName, entity);
  }
  
  onEdit(entity, mav, request);
  return mav;
 }
 
 protected void onEdit(T entity, ModelAndView mav, HttpServletRequest request){};
 
 /**
  * 保存实体<br/>
  * 回调函数:beforeDoSave(...), afterDoSave(...)
  * @param request
  * @param response
  * @return
  * @throws Exception
  */
 @SuppressWarnings("unchecked")
 @RequestMapping(value = "save.do")
 public ModelAndView doSave(HttpServletRequest request, HttpServletResponse response) throws Exception {
  ModelAndView mav = new ModelAndView(successView);
  
  String id = request.getParameter("id");
  if (StringUtils.isEmpty(id)) {
   entity = (T) BeanUtils.getSuperClassGenricType(getClass()).newInstance();
  } else {
   entity = getEntityService().get(Integer.valueOf(id));
  }
  
  boolean check = beforeBindRequestEntity(request, entity, mav);
  if(!check)
   return mav;
  
  beforeBindRequestEntity(request, entity, mav);
  BindException errors = bindRequestEntity(request, entity);

  beforeSave(request, entity, errors, mav);
  
  if (errors.hasErrors()) {
   logger.error(errors.getMessage());
   mav.addObject("msg", getMessageFromErrors(errors));
   mav.addObject("state", "failed");
   mav.addObject("url", "list.do");
   return mav;
  }
  
  getEntityService().save(entity);
  mav.addObject("msg", "保存成功!");
  mav.addObject("state", "ok");
  afterSave(request, response, mav, entity);
  
  return mav;
 }
 
 /**
  * 从Request中绑定对象并进行校验.
  */
 protected BindException bindRequestEntity(HttpServletRequest request, T entity) throws Exception {
  ServletRequestDataBinder binder = new ServletRequestDataBinder(entity);
  initBinder(binder);
  binder.bind(request);
  BindException errors = new BindException(binder.getBindingResult());
  validator.validate(entity, errors);
  return errors;
 }
 
 /**
  * 保存实体(save.do)回调函数,在执行实体与Request参数绑定之前调用用。
  * 注意:由于entity可能是托管对象,对entity所做的修改都将反映到数据库。
  * 所以有必要在此方法中进行前期的数据校验,以免发生意外。
  * @param request
  * @param entity
  * @param mav
  * @return 是否通过校验
  */
 protected boolean beforeBindRequestEntity(HttpServletRequest request, T entity, ModelAndView mav){ return false;};
 
 /**
  * 保存实体(save.do)回调函数,在执行保存之前调用用。可以进行数据校验。
  * @param request HttpServletRequest
  * @param entity 实体对象
  * @param errors BindException 可以添加错误信息
  * @param mav ModelAndView
  */
 protected void beforeSave(HttpServletRequest request, T entity, BindException errors, ModelAndView mav){};
 
 /**
  * 保存实体(save.do)回调函数,在返回视图之前调用用。可以继续添加返回信息。
  * @param request
  * @param response
  * @param mav
  */
 protected void afterSave(HttpServletRequest request, HttpServletResponse response, ModelAndView mav, T entity){};
 
 @RequestMapping(value = "remove.do")
 public ModelAndView doRemove(HttpServletRequest request, HttpServletResponse response) throws Exception {
  ModelAndView mav = new ModelAndView(successView);
  String id = request.getParameter("id");

  T t = getEntityService().load(Integer.valueOf(id));
  
  beforeRemove(request, response, t);
  getEntityService().remove(t);
  afterRemove(request, response, mav, new StringBuilder().append("成功删除")
             .append("1个").append(entityName)
             .append(" id:").append(id).toString());

  return mav;
 }
 
 /**
  * 批量删除实体<br/>
  * 回调函数:beforeDoRemove(...), afterDoRemove(...)
  * @param request
  * @param response
  * @return
  * @throws Exception
  */
 @RequestMapping(value = "batchRemove.do")
 public ModelAndView doBatchRemove(HttpServletRequest request, HttpServletResponse response) throws Exception {
  ModelAndView mav = new ModelAndView(successView);
  String[] ids = request.getParameterValues("itemlist");
  String entity = request.getParameter("entityName");
  StringBuilder sb = null;
  int success = 0;
  T t = null;
  if (ids != null) {
   for (String id : ids) {
    t = getEntityService().get(Integer.valueOf(id));
    beforeRemove(request, response, t);
    getEntityService().remove(t);
    success++;
   }
   sb = new StringBuilder().append("成功删除")
        .append(success).append("个").append(entity)
        .append(" ids:").append(Arrays.toString(ids));
   mav.addObject("msg", sb.toString());
  } else {
   mav.addObject("msg", "未选择" + entity);
  }
  
  afterRemove(request, response, mav, sb.toString());
  return mav;
 }
 
 /**
  * 删除实体(remove.do)回调函数,在执行保存之前调用用。可以进行数据校验。
  * @param request
  * @param response
  * @param entity 实体对象
  */
 protected void beforeRemove(HttpServletRequest request, HttpServletResponse response, T entity){};
 
 /**
  * 删除实体(remove.do)回调函数,在返回视图之前调用用。可以继续添加返回信息。
  * @param request
  * @param response
  * @param mav
  */
 protected void afterRemove(HttpServletRequest request, HttpServletResponse response, ModelAndView mav, String msg){};

 /**
  * 查询实体信息<br/>
  * 回调函数:onShow(...)
  * @param request
  * @param response
  * @return
  * @throws Exception
  */
 @RequestMapping(value = "show.do")
 public ModelAndView doShow(HttpServletRequest request, HttpServletResponse response) throws Exception {
  ModelAndView mav = new ModelAndView(formView);
  
  entity = getEntityService().get(Integer.valueOf(request.getParameter("id")));
  mav.addObject(entityName, entity);
  
  onShow(request, response, entity, mav);
  return mav;
 }
 
 /**
  * 查询实体信息(show.do)回调函数,在返回视图之前调用用。可以继续添加返回信息。
  * @param request
  * @param response
  * @param entity 实体对象
  * @param mav
  */
 protected void onShow(HttpServletRequest request, HttpServletResponse response, T entity, ModelAndView mav){};

 @SuppressWarnings("unchecked")
 private String getMessageFromErrors(BindException errors){
  StringBuilder sb = new StringBuilder();
  sb.append("错误信息:");
  List<ObjectError> list= errors.getAllErrors();
  for(ObjectError error : list){
   sb.append(error.getDefaultMessage()).append(";");
  }
  return sb.toString();
 }
 
 /**
  * 向客户端写入JSON数据
  * @param response
  * @param element JsonElement的子类可以是JsonArray或JsonObject
  */
 protected void writeJsonDate(HttpServletResponse response, JsonElement element){
  try {
   response.setCharacterEncoding("UTF-8");
   response.getWriter().print(element.toString());
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

 

 

http://www.oschina.net/code/snippet_93992_4535

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics