SpringMVC 通用Controller

Easter79
• 阅读 598
public abstract class AbstractController<T extends AbstractEntity> {

    @Resource
    private Validator validator;

    protected static final Logger logger = LoggerFactory.getLogger(AbstractController.class);

    protected String className;

    protected String entityName;

    public AbstractController() {
        className = ReflectionUtils.getSuperClassGenricType(getClass()).getName();
        entityName = StringUtils.substringAfterLast(className, ".").toLowerCase();
    }

    /**
     * 获取实体服务类的实例
     * 
     * @return
     */
    protected abstract Manager<T, String> getEntityService();

    /**
     * 获取View的基础位置,例如ugr/user/ ,系统会自动添加list,edit等
     * 
     * @return
     */
    protected abstract String getBasePagePath();

    /**
     * 选择删除项目的模式,默认为空或是logic表示逻辑删除,不等于logic则表示物理删除
     * 
     * @return
     */
    protected abstract String getDeleteMode();

    @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", "12222222")。 可以为null
     * 
     * @param sortMap
     *            排序条件,如:sortMap.put("id", "desc"); asc为正序,desc为倒序。 可以为null
     * @return ScrollResult<T>
     */
    @RequestMapping(value = "list", method = { RequestMethod.POST, RequestMethod.GET })
    public ModelAndView list(HttpServletRequest request) {

    
        // 提取客户端可能传送的过滤条件和排序条件
        Map<String, Object> filterMap = WebUtils.getParametersStartingWith(request, "search_");
        Map<String, Boolean> sortMap = HcUtils.getOrderFromPage(request, "sort_");

        // 自定义查询、排序条件
        beforeList(request, filterMap, sortMap);

        HibernateCriteria hc = HcUtils.creat(filterMap, sortMap);

        ModelAndView mav = new ModelAndView();

        doList(mav, request, hc);
        
        afterList(mav, request);
        
        // 向叶面发送查询和排序条件
        for(String key:filterMap.keySet()){            
            mav.addObject(StringUtils.substringBefore(key, "_"), filterMap.get(key));
        }
        
        for(String key:sortMap.keySet()){
            mav.addObject(StringUtils.substringBefore(key, "_"), sortMap.get(key));
        }

        mav.setViewName(getBasePagePath() + "list");

        return mav;
    }

    /**
     * 分页查询(list)回调函数,该方法在执行查询之前调用。可以继续添加过滤条件和排序条件。
     * 
     * @param request
     * @param filterMap
     * @param sortMap
     */
    protected void beforeList(HttpServletRequest request, Map<String, Object> filterMap, Map<String, Boolean> sortMap) {
    };

    protected void doList(ModelAndView model, HttpServletRequest request, HibernateCriteria hc) {
        int pageNumber = com.gbhk.core.util.WebUtils.getPageNumber(request);
        int pageSize = com.gbhk.core.util.WebUtils.getPageSize(request);

        Page<T> datas = null;
        if (hc.criterion.isEmpty()) {
            datas = getEntityService().getPage(pageNumber, pageSize, "id", true);
        } else {
            datas = getEntityService().getPageByCriteria(pageNumber, pageSize, hc);
        }
        model.addObject("datas", datas);
        model.addObject("pageNumber", pageNumber);
    }

    /**
     * 分页查询(list)回调函数,该方法在返回视图之前调用。可以继续添加返回信息。
     * 
     * @param request
     * @param response
     * @param mav
     */
    protected void afterList(ModelAndView model, HttpServletRequest request) {
    };

    @SuppressWarnings("unchecked")
    @RequestMapping(value = "preCreate", method = { RequestMethod.POST, RequestMethod.GET })
    public ModelAndView preCreate(int page, HttpServletRequest request) throws Exception {
        T bean = (T) ReflectionUtils.getSuperClassGenricType(getClass()).newInstance();
        ModelAndView mav = new ModelAndView();
        beforePreCreate(mav, bean, request);

        mav.addObject("bean", bean);
        mav.addObject("page", page);

        afterPreCreate(mav, bean, request);

        mav.setViewName(getBasePagePath() + "create");

        return mav;
    }

    protected void beforePreCreate(ModelAndView model, T bean, HttpServletRequest request) {
    };

    protected void afterPreCreate(ModelAndView model, T bean, HttpServletRequest request) {
    };

    /**
     * 定向到新增实体的表单界面<br/>
     * 回调函数:onCreate(...)
     * 
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "create", method = RequestMethod.POST)
    public ModelAndView create(int page, T bean, HttpServletRequest request, RedirectAttributes redirectAttributes)
            throws Exception {

        beforeCreate(request);

        getEntityService().save(bean);
        
        afterCreate(redirectAttributes);
        
        ModelAndView mav = new ModelAndView("redirect:edit/" + bean.getId() + "/" + page + "/");
        redirectAttributes.addFlashAttribute("msg", "添加成功!");

        // 重定向到Edit
        return mav;
    }

    protected void beforeCreate(HttpServletRequest request) {
    };

    protected void afterCreate(RedirectAttributes redirectAttributes) {
    };

    /**
     * 表单编辑界面
     */
    @RequestMapping(value = "edit/{id}/{page}", method = RequestMethod.GET)
    public ModelAndView edit(@PathVariable("id") String id, @PathVariable("page") int page, HttpServletRequest request)
            throws Exception {

        ModelAndView mav = new ModelAndView();
        T bean = getEntityService().get(id);
        beforeEdit(mav, bean, request);

        mav.addObject("bean", bean);
        mav.addObject("id", id);
        mav.addObject("page", page);

        afterEdit(mav, bean, request);

        mav.setViewName(getBasePagePath() + "edit");

        return mav;
    }

    protected void beforeEdit(ModelAndView model, T bean, HttpServletRequest request) {
    };

    protected void afterEdit(ModelAndView model, T bean, HttpServletRequest request) {
    };

    @RequestMapping(value = "save", method = RequestMethod.POST)
    public ModelAndView save(@RequestParam String id, @RequestParam int page, HttpServletRequest request,
            @ModelAttribute("bean") T bean, RedirectAttributes redirectAttributes) throws Exception {
        ModelAndView mav = new ModelAndView();
        try {

            BindException errors = bindRequestEntity(request, bean);

            beforeSave(mav, bean, request);

            if (errors.hasErrors()) {
                logger.error(errors.getMessage());
                redirectAttributes.addFlashAttribute("msg", getMessageFromErrors(errors));
                mav.addObject("msg", "11");
                mav.setViewName("redirect:" + "edit/" + id + "/" + page + "/");
                return mav;
            }

            getEntityService().save(bean);

        } catch (Exception e) {
            e.printStackTrace();
        }

        mav.addObject("bean", bean);
        mav.addObject("id", id);
        mav.addObject("page", page);
        mav.addObject("msg", "保存成功");

        afterSave(mav, bean, request);

        mav.setViewName(getBasePagePath() + "edit");

        return mav;
    }

    protected void beforeSave(ModelAndView model, T bean, HttpServletRequest request) {
    };

    protected void afterSave(ModelAndView model, T bean, HttpServletRequest request) {
    };

    /**
     * 所有RequestMapping方法调用前的Model准备方法, 实现Struts2
     * Preparable二次部分绑定的效果,先根据form的id从数据库查出User对象,再把Form提交的内容绑定到该对象上。
     * 因为仅update()方法的form中有id属性,因此仅在update时实际执行.
     */
    @ModelAttribute
    public void getEntity(@RequestParam(value = "id", defaultValue = "") String id, Model model) {
        if (!"".equals(id)) {
            model.addAttribute("bean", getEntityService().get(id));
        }
    }

    /**
     * 从Request中绑定对象并进行校验.
     */
    protected BindException bindRequestEntity(HttpServletRequest request, T bean) throws Exception {
        ServletRequestDataBinder binder = new ServletRequestDataBinder(bean);
        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) {
        return false;
    };

    @RequestMapping(value = "delete/{id}/{page}",method = RequestMethod.GET)
    public String delete(@PathVariable("id") String id, @PathVariable("page") int page, RedirectAttributes ra,
            HttpServletRequest request) throws Exception {

        T bean = getEntityService().get(id);
        beforeDelete(request, bean, ra);

        if (StringUtils.isBlank(getDeleteMode()) || "logic".equals(getDeleteMode())) {
            // 物理删除
            getEntityService().delete(bean);
        } else {
            // 逻辑删除
            bean.setEnabled(false);
            getEntityService().update(bean);
        }

        ra.addAttribute("page", page);
        ra.addFlashAttribute("msg", "删除成功");

        afterDelete(request, bean, ra);
        
        //截取uri动态拼接返回list路径
        //示例:uri:uri:/gbhk-web/admin/property/delete/8a8a89be5114b516015114bea7c30002/1/
        //      返回字符串:/admin/property/list
        String uri = request.getRequestURI();
        String[] array = uri.split("/");
        String retStr="";
        for(int i=2;i<array.length-3;i++){
             retStr+="/"+array[i];
        }
        return "redirect:"+retStr+"/list";
    }

    /**
     * 批量删除实体<br/>
     * 回调函数:beforeDoRemove(...), afterDoRemove(...)
     * 
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "delete", method = RequestMethod.POST)
    public ModelAndView deleteBatch(@RequestParam("ids") String ids, @RequestParam("page") int page,
            RedirectAttributes ra, HttpServletRequest request) throws Exception {

        beforeDelete(request, null, ra);

        if (StringUtils.isBlank(ids)) {
            ra.addFlashAttribute("msg", "请选择要删除的信息!");
        } else {
            String[] id_s = StringUtils.split(ids, ",");
            if (StringUtils.isBlank(getDeleteMode()) || "logic".equals(getDeleteMode())) {
                // 物理删除
                for (String id : id_s) {
                    getEntityService().deleteById(id.trim());
                }
            } else {
                // 逻辑删除
                for (String id : id_s) {
                    T bean = getEntityService().get(id.trim());
                    bean.setEnabled(false);
                    getEntityService().update(bean);
                }
            }

            ra.addFlashAttribute("msg", "删除成功");
        }

        ra.addAttribute("page", page);

        afterDelete(request, null, ra);

        return new ModelAndView(getBasePagePath() + "list");
    }

    protected void beforeDelete(HttpServletRequest request, T entity, RedirectAttributes ra) {
    };

    protected void afterDelete(HttpServletRequest request, T entity, RedirectAttributes ra) {
    };

    /**
     * 查询实体信息<br/>
     * 回调函数:onShow(...)
     * 
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "view/{id}/{page}", method = RequestMethod.GET)
    public ModelAndView view(@PathVariable("id") String id, @PathVariable("page") int page, HttpServletRequest request)
            throws Exception {
        ModelAndView mav = new ModelAndView();

        T bean = getEntityService().get(id);
        beforeView(mav, bean, request);

        mav.addObject("bean", bean);
        mav.addObject("id", id);
        mav.addObject("page", page);

        afterView(mav, bean, request);

        mav.setViewName(getBasePagePath() + "view");

        return mav;
    }

    protected void beforeView(ModelAndView model, T bean, HttpServletRequest request) {
    };

    protected void afterView(ModelAndView model, T bean, HttpServletRequest request) {
    };

    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();
    }

    
}

 

@Controller
@RequestMapping(value = "/admin/user")
public class UserController extends AbstractController<User>{
    
    @Autowired
    private UserManager userManager;

    @Override
    protected Manager<User, String> getEntityService() {
        return userManager;
    }

    @Override
    protected String getBasePagePath() {
        return "ugr/user/";
    }

    @Override
    protected String getDeleteMode() {
        return null;
    }

    
}
点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
2年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k