最近在寫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,整體程式碼風格看起來也更統一