springboot中扩展ModelAndView实现asp.net core mvc的ActionResult效果
- 2021 年 2 月 6 日
- 筆記
- MVC, springboot
最近在写spring boot项目,写起来感觉有点繁琐,为了简化spring boot中的Controller开发,对ModelAndView进行简单的扩展,实现net mvc中ActionResult的写法
asp.net core mvc中控制器中提供了IActionResult接口来返回Aciton结果,可以用来返回视图view或者json,当然也可以实现接口返回自定义结果,当时写EasyCMS的时候实现过一个HtmlResult用来返回模板渲染生成的HTML内容,在asp.net core mvc中开发非常简便,那么我们可以看下在asp.net core mvc中的写法
//返回视图 [HttpGet] public IActionResult Index(){ return View(); } //返回json [HttpGet] public IActionResult GetJson(){ return Json(); } //返回字符串 [HttpGet] public IActionResult GetJson(){ return Content(); }
再来看下在spring boot中原始的写法是啥样子的
//返回index页面 @GetMapping("/index") public String index() { return "home/index"; } //或者 @GetMapping("/tesView") public ModelAndView tesView(){ return new ModelAndView("/home/testView"); } //返回json @GetMapping("/getJson") @ResponseBody public Hashtable<String,Object> getJson(){ Hashtable<String,Object> data=new Hashtable<>(); data.put("status",true); data.put("message","message from json"); return map; }
可以看到spring boot默认的写法并不是很简化,比如使用String返回视图view的时候必须指定视图路径,返回json必须添加@ResponseBody注解,
而使用ModelAndView 当视图路径和路由一致时是可以简化不写视图路径的 ,所以我们可以对ModelAndView来进一步扩展来简化控制器的开发,统一返回view或者json
1,首先定义一个ActionResult
public class ActionResult extends ModelAndView { public ActionResult() { super(); } public ActionResult(View view) { super(view); } }
2,在BaseController中来封装 ActionResult ,来提供统一的返回结果
package com.easycms.framework.web; import cn.hutool.core.util.StrUtil; import com.easycms.constant.JacksonConstants; import com.easycms.framework.domain.DataTableDto; import com.easycms.framework.domain.ResultAdaptDto; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.view.json.MappingJackson2JsonView; import java.util.Hashtable; public class BaseController { /** * 返回页面 */ //public String view(String url){ // return url; //} /** * 页面跳转 */ public String redirect(String url) { return StrUtil.format("redirect:{}", url); } /** * * @author yushuo * @description //返回视图view * @date 14:15 2021/2/4 * @param * @return com.easycms.framework.web.ActionResult **/ protected ActionResult view() { return view(null); } /** * * @author yushuo * @description //返回视图view * @date 14:15 2021/2/4 * @param [viewpath] * @return com.easycms.framework.web.ActionResult **/ protected ActionResult view(String viewPath) { return view(viewPath,null); } /** * * @author yushuo * @description //返回视图view * @date 14:15 2021/2/4 * @param [model] * @return com.easycms.framework.web.ActionResult **/ protected ActionResult view(Object model) { return view(null, model); } /** * * @author yushuo * @description //返回视图view * @date 14:15 2021/2/4 * @param [viewpath, model] * @return com.easycms.framework.web.ActionResult **/ protected ActionResult view(String viewpath, Object model) { ActionResult r = new ActionResult(); r.setViewName(viewpath); r.addObject("model", model); return r; } /** * * @author yushuo * @description //返回json * @date 14:15 2021/2/4 * @param [Hashtable<String,Object> data] * @return org.springframework.web.servlet.ModelAndView **/ protected ActionResult json(Hashtable<String,Object> data) { ActionResult modelAndView = new ActionResult(JacksonConstants.mappingJackson2JsonView); modelAndView.addObject("message", null); modelAndView.addObject("code",0); modelAndView.addObject("status",true); modelAndView.addObject("data", data); return modelAndView; } /** * * @author yushuo * @description //返回json * @date 14:15 2021/2/4 * @param [ResultAdaptDto data] * @return org.springframework.web.servlet.ModelAndView **/ protected ActionResult json(ResultAdaptDto data) { ActionResult modelAndView = new ActionResult(JacksonConstants.mappingJackson2JsonView); // modelAndView.addObject(data); modelAndView.addObject("message", null); modelAndView.addObject("code",0); modelAndView.addObject("status",true); modelAndView.addObject("data", data.getData()); return modelAndView; } /** * * @author yushuo * @description //返回json * @date 14:15 2021/2/4 * @param [DataTableDto data] * @return org.springframework.web.servlet.ModelAndView **/ protected ActionResult json(DataTableDto data) { ActionResult modelAndView = new ActionResult(JacksonConstants.mappingJackson2JsonView); modelAndView.addObject(data); return modelAndView; } /** * * @author yushuo * @description //请求失败 * @date 14:20 2021/2/4 * @param [message] * @return com.easycms.framework.web.ActionResult **/ protected ActionResult error(String message){ ActionResult modelAndView = new ActionResult(JacksonConstants.mappingJackson2JsonView); modelAndView.addObject("message", message); modelAndView.addObject("code",0); modelAndView.addObject("status",false); return modelAndView; } /** * * @author yushuo * @description //请求失败 * @date 14:20 2021/2/4 * @param * @return com.easycms.framework.web.ActionResult **/ protected ActionResult error(){ ActionResult modelAndView = new ActionResult(JacksonConstants.mappingJackson2JsonView); modelAndView.addObject("message", "请求失败"); modelAndView.addObject("code",0); modelAndView.addObject("status",false); return modelAndView; } /** * * @author yushuo * @description //请求失败 * @date 14:20 2021/2/4 * @param [message] * @return com.easycms.framework.web.ActionResult **/ protected ActionResult ok(String message){ ActionResult modelAndView = new ActionResult(JacksonConstants.mappingJackson2JsonView); modelAndView.addObject("message", message); modelAndView.addObject("code",0); modelAndView.addObject("status",true); return modelAndView; } /** * * @author yushuo * @description //请求成功 * @date 14:20 2021/2/4 * @param * @return com.easycms.framework.web.ActionResult **/ protected ActionResult ok(){ ActionResult modelAndView = new ActionResult(JacksonConstants.mappingJackson2JsonView); modelAndView.addObject("message", "操作成功"); modelAndView.addObject("code",0); modelAndView.addObject("status",true); return modelAndView; } }
3,BaseController中用到的JacksonConstants
package com.easycms.constant; import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.servlet.view.json.MappingJackson2JsonView; import java.text.SimpleDateFormat; import java.util.TimeZone; /** * @author yushuo * @className * @descripton TODO * @date 2021/2/5 13:47 **/ public class JacksonConstants { /** * @author yushuo * @description //jackson ObjectMapper * @date 13:52 2021/2/5 * @param * @return **/ public static ObjectMapper objectMapper; /** * @author yushuo * @description //jackson MappingJackson2HttpMessageConverter * @date 13:52 2021/2/5 * @param * @return **/ public static MappingJackson2HttpMessageConverter jackson2HttpMessageConverter; /** * @author yushuo * @description //jackson MappingJackson2JsonView * @date 13:52 2021/2/5 * @param * @return **/ public static MappingJackson2JsonView mappingJackson2JsonView; static { objectMapper=objectMapper(); jackson2HttpMessageConverter=jackson2HttpMessageConverter(); mappingJackson2JsonView=mappingJackson2JsonView(); } /** * * @author yushuo * @description //jackson配置jackson2HttpMessageConverter * @date 13:49 2021/2/5 * @param [] * @return org.springframework.http.converter.json.MappingJackson2HttpMessageConverter **/ private static MappingJackson2HttpMessageConverter jackson2HttpMessageConverter(){ return new MappingJackson2HttpMessageConverter(objectMapper()); } /** * * @author yushuo * @description //jackson配置 objectMapper * @date 13:51 2021/2/5 * @param [] * @return com.fasterxml.jackson.databind.ObjectMapper **/ private static ObjectMapper objectMapper(){ final Jackson2ObjectMapperBuilder builder=new Jackson2ObjectMapperBuilder(); final ObjectMapper objectMapper=builder.build(); SimpleModule simpleModule=new SimpleModule(); simpleModule.addSerializer(Long.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.TYPE,ToStringSerializer.instance); objectMapper.registerModule(simpleModule); objectMapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER,true); objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8")); objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); return objectMapper; } /** * * @author yushuo * @description //jackson配置 * @date 13:49 2021/2/5 * @param [] * @return org.springframework.http.converter.json.MappingJackson2HttpMessageConverter **/ private static MappingJackson2JsonView mappingJackson2JsonView(){ return new MappingJackson2JsonView(objectMapper()); } }
4,实际使用
返回视图
@GetMapping("/login") public ActionResult login(){ return view("/home/login"); } //或者 @GetMapping("/login") public ActionResult login(){ return view(); } //或者 @GetMapping("/login") public ActionResult login(){ ModelMap model=new ModelMap(); model.put("author","yushuo"); return view(model); }
返回json
@GetMapping("/getJson") public ActionResult getJson(String id){ Hashtable<String,Object> data=new Hashtable<>(); data.put("id",id); return json(result); }
这样是不是就比原始的控制器开发简化多了呢
可以使用统一ActionResult来返回视图view或者json,整体代码风格看起来也更统一