springboot中擴充套件ModelAndView實現asp.net core mvc的ActionResult效果

發表於2021-02-06

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

相關文章