关于Controller 层返回值的公共包装类的问题

场景:在微服务中,一般返回数据都会有个返回码返回信息返回消息体,但是每次返回时候调用或者是封装,太过麻烦,有没有什么办法不用每次都封装呢?

答案是有的。

返回值对象 ResponseData

package com.study.auth.comm;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.io.Serializable;

/**
 * @Package: com.study.auth.comm
 * @Description: <返回数据>
 * @Author: MILLA
 * @CreateDate: 2018/4/8 9:10
 * @UpdateUser: MILLA
 * @UpdateDate: 2018/4/8 9:10
 * @Version: 1.0
 */
public final class ResponseData<T> implements Serializable {
    private static final long serialVersionUID = 7824278330465676943L;

    private static final String SUCCESS_CODE = "1000";

    private static final String SUCCESS_MSG = "success";
    /**
     * 响应编码
     */
    @JSONField(serialzeFeatures = {SerializerFeature.WriteMapNullValue}, ordinal = 1)
    private String code;

    /**
     * 响应提示
     */
    @JSONField(serialzeFeatures = {SerializerFeature.WriteMapNullValue}, ordinal = 2)
    private String msg;

    /**
     * 返回的数据
     */
    @JSONField(serialzeFeatures = {SerializerFeature.WriteMapNullValue}, ordinal = 10)
    private T data;

    public static ResponseData success() {
        return initData(SUCCESS_CODE, SUCCESS_MSG, null);
    }

    public static ResponseData error(String code) {
        String msg = PropertiesReaderUtil.getProperty(code, null);
        return initData(code, msg, null);
    }

    public static ResponseData error(String code, String msg) {
        return initData(code, msg, null);
    }

    public static <T> ResponseData success(T t) {
        return initData(SUCCESS_CODE, SUCCESS_MSG, t);
    }

    public static <T> ResponseData errorData(String code, T data) {
        String msg = PropertiesReaderUtil.getProperty(code, null);
        return initData(code, msg, data);
    }

    public static <T> ResponseData errorData(String code, String msg, T data) {
        return initData(code, msg, data);
    }

    private static <T> ResponseData initData(String code, String msg, T t) {
        ResponseData data = new ResponseData(SUCCESS_CODE);
        if (!isBlank(msg)) {
            data.setMsg(msg);
        }
        if (!isBlank(code)) {
            data.setCode(code);
        }
        if (t != null) {
            data.setData(t);
        }
        return data;
    }

    private static boolean isBlank(CharSequence cs) {
        int strLen;
        if (cs != null && (strLen = cs.length()) != 0) {
            for (int i = 0; i < strLen; ++i) {
                if (!Character.isWhitespace(cs.charAt(i))) {
                    return false;
                }
            }
            return true;
        } else {
            return true;
        }
    }

    public ResponseData() {
    }

    public ResponseData(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}

如上图的包装,还是太繁琐了。

装饰者模式使用-增强类InitializingAdviceDecorator

通过实现InitializingBean和装饰者模式对Controller层的返回值进行包装,大致思路:

通过RequestMappingHandlerAdapter获取所有的返回值处理对象HandlerMethodReturnValueHandler创建一个新的集合存储上一步获取的集合(因为上一步的结果是unmodifiableList类型的)遍历该集合找到HandlerMethodReturnValueHandler对象,将这个位置的handler替换程自定义的handler将新获到的集合重新设置到RequestMappingHandlerAdapter的setReturnValueHandlers方法中

package com.study.auth.config;

import com.study.auth.comm.ResponseData;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;

import java.util.ArrayList;
import java.util.List;

/**
 * @Package: com.study.auth.config.core
 * @Description: <增强controller层返回值>
 * @Author: milla
 * @CreateDate: 2020/09/04 14:42
 * @UpdateUser: milla
 * @UpdateDate: 2020/09/04 14:42
 * @UpdateRemark: <>
 * @Version: 1.0
 */
@Configuration
public class InitializingAdviceDecorator implements InitializingBean {
    @Autowired
    private RequestMappingHandlerAdapter adapter;

    @Override
    public void afterPropertiesSet() {
        //获取所有的handler对象
        List<HandlerMethodReturnValueHandler> returnValueHandlers = adapter.getReturnValueHandlers();
        //因为上面返回的是unmodifiableList,所以需要新建list处理
        List<HandlerMethodReturnValueHandler> handlers = new ArrayList(returnValueHandlers);
        this.decorateHandlers(handlers);
        //将增强的返回值回写回去
        adapter.setReturnValueHandlers(handlers);
    }

    /**
     * 使用自定义的返回值控制类
     *
     * @param handlers
     */
    private void decorateHandlers(List<HandlerMethodReturnValueHandler> handlers) {
        for (HandlerMethodReturnValueHandler handler : handlers) {
            if (handler instanceof RequestResponseBodyMethodProcessor) {
                //找到返回值的handler并将起包装成自定义的handler
                ControllerReturnValueHandler decorator = new ControllerReturnValueHandler((RequestResponseBodyMethodProcessor) handler);
                int index = handlers.indexOf(handler);
                handlers.set(index, decorator);
                break;
            }
        }
    }

    /**
     * 自定义返回值的Handler
     * 采用装饰者模式
     */
    private class ControllerReturnValueHandler implements HandlerMethodReturnValueHandler {
        //持有一个被装饰者对象
        private HandlerMethodReturnValueHandler handler;

        ControllerReturnValueHandler(RequestResponseBodyMethodProcessor handler) {
            this.handler = handler;
        }

        @Override
        public boolean supportsReturnType(MethodParameter returnType) {
            return true;
        }

        /**
         * 增强被装饰者的功能
         *
         * @param returnValue  返回值
         * @param returnType   返回类型
         * @param mavContainer view
         * @param webRequest   请求对象
         * @throws Exception 抛出异常
         */
        @Override
        public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
            //如果已经封装了结构体就直接放行
            if (returnValue instanceof ResponseData) {
                handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
                return;
            }
            //正常返回success
            ResponseData success = ResponseData.success(returnValue);
            handler.handleReturnValue(success, returnType, mavContainer, webRequest);
        }
    }
}

配置文件读取类PropertiesReaderUtil

package com.study.auth.comm;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;

/**
 * @Package: com.milla.navicat.comm
 * @Description: <读取配置properties工具类>
 * @Author: MILLA
 * @CreateDate: 2018/8/10 10:30
 * @UpdateUser: MILLA
 * @UpdateDate: 2018/8/10 10:30
 * @UpdateRemark: <>
 * @Version: 1.0
 */
public final class PropertiesReaderUtil {
    private static final String ENCODING = "UTF-8";
    private static final Logger logger = LoggerFactory.getLogger(PropertiesReaderUtil.class);
    private static Properties propsZH;
    private static Properties propsCN;
    private static String name = null;

    static {
        //加载英文
        //loadProps(false);
        //加载中文
        loadProps(true);
    }

    /**
     * 第一种,通过类加载器进行获取properties文件流
     * 第二种,通过类进行获取properties文件流
     * in = PropertyUtil.class.getResourceAsStream("/properties/message_ZH.properties");
     * in = PropertiesReaderUtil.class.getClassLoader().getResourceAsStream("properties/message_ZH.properties");
     */
    synchronized static private void loadProps(boolean isZh) {
        logger.debug("start loading properties");
        InputStream in = null;
        if (isZh) {
            propsZH = new Properties();
            name = "properties/message_ZH.properties";
            in = PropertiesReaderUtil.class.getClassLoader().getResourceAsStream(name);
        } else {
            propsCN = new Properties();
            name = "properties/message_EN.properties";
            in = PropertiesReaderUtil.class.getClassLoader().getResourceAsStream(name);
        }
        try {
            if (isZh) {
                propsZH.load(new InputStreamReader(in, ENCODING));
            } else {
                propsCN.load(new InputStreamReader(in, ENCODING));
            }
        } catch (Exception e) {
            logger.debug("loading properties error :{}", e);
        } finally {
            try {
                if (null != in) {
                    in.close();
                }
            } catch (IOException e) {
                logger.debug("closing properties io error :{}", e);
            }
        }
    }

    public static String getProperty(String key) {
        return getPropertyZH(key);
    }

    public static String getProperty(String key, String defaultValue) {
        return getPropertyZH(key, defaultValue);
    }

    public static String getPropertyZH(String key) {
        if (null == propsZH) {
            loadProps(true);
        }
        return propsZH.getProperty(key);
    }

    public static String getPropertyZH(String key, String defaultValue) {
        if (null == propsZH) {
            loadProps(true);
        }
        return propsZH.getProperty(key, defaultValue);
    }

    public static String getPropertyCN(String key) {
        if (null == propsCN) {
            loadProps(false);
        }
        return propsCN.getProperty(key);
    }

    public static String getPropertyCN(String key, String defaultValue) {
        if (null == propsCN) {
            loadProps(false);
        }
        return propsCN.getProperty(key, defaultValue);
    }
}

配置文件message_ZH.properties

路径为:properties/message_ZH.properties

也可添加国家化英文或者是其他语言配置

1001=用户未登录
#====非业务返回码=========
1100=服务器内部错误
1101=空指针异常
1102=数据类型转换异常
1103=IO异常
1104=该方法找不到异常
1105=数组越界异常
1106=请求体缺失异常
1107=类型匹配异常
1108=请求参数缺失异常
1109=请求方法不支持异常
1110=请求头类型不支持异常
1111=参数解析异常
1112=必要参数不能为空
#=======================

统一异常捕捉类RestfulExceptionHandler

此时,基本能保证增强Controller层的返回值了,如果有需要的话,可能通过@RestControllerAdvice注解,针对抛出的异常使用返回值对象进行包装

package com.study.auth.exception;

import com.alibaba.fastjson.JSONException;
import com.study.auth.comm.PropertiesReaderUtil;
import com.study.auth.comm.ResponseData;
import com.study.auth.constant.CommonConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.TypeMismatchException;
import org.springframework.boot.json.JsonParseException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.security.auth.login.AccountException;
import java.io.IOException;
import java.sql.SQLException;

/**
 * @Package: com.study.auth.exception
 * @Description: <所有异常拦截类>
 * @Author: milla
 * @CreateDate: 2020/09/04 15:35
 * @UpdateUser: milla
 * @UpdateDate: 2020/09/04 15:35
 * @UpdateRemark: <>
 * @Version: 1.0
 */
@Slf4j
@RestControllerAdvice
public class RestfulExceptionHandler {
    private ResponseData responseData(String code, Exception e) {
        log.error("异常代码:{},异常描述:{},异常堆栈:", code, PropertiesReaderUtil.getProperty(code), e);
        return ResponseData.error(code);
    }

    private ResponseData<String> responseData(String code, String message, Exception e) {
        log.error("异常代码:{},异常描述:{},异常堆栈:", code, message, e);
        return ResponseData.error(code, message);
    }

    /**
     * 运行时异常
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(Exception.class)
    public ResponseData runtimeExceptionHandler(Exception e) {
        return responseData(CommonConstant.EX_RUN_TIME_EXCEPTION, e);
    }

    /**
     * 处理SQLSyntaxErrorException
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(SQLException.class)
    public ResponseData<String> sqlException(SQLException e) {
        return responseData(CommonConstant.EX_RUN_TIME_EXCEPTION, e.getMessage(), e);
    }

    /**
     * 处理CustomerMessageException
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(CustomMessageException.class)
    public ResponseData<String> customerMessageException(CustomMessageException e) {
        return responseData(CommonConstant.EX_RUN_TIME_EXCEPTION, e.getMessage(), e);
    }

    /**
     * 处理AccountException
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(AccountException.class)
    public ResponseData<String> accountException(AccountException e) {
        return responseData(e.getMessage(), e);
    }

    //---------------------------------------jdk/spring自带的异常----------------------------------

    /**
     * 处理IllegalArgumentException
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseData<String> illegalArgumentException(IllegalArgumentException e) {
        return responseData(CommonConstant.EX_RUN_TIME_EXCEPTION, e.getMessage(), e);
    }

    /**
     * 空指针异常
     *
     * @param e 异常
     * @return
     */
    @ResponseStatus
    @ExceptionHandler(NullPointerException.class)
    public ResponseData nullPointerExceptionHandler(NullPointerException e) {
        return responseData(CommonConstant.EX_NULL_POINTER_EXCEPTION, e);
    }

    /**
     * 类型转换异常
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(ClassCastException.class)
    public ResponseData classCastExceptionHandler(ClassCastException e) {
        return responseData(CommonConstant.EX_CLASS_CAST_EXCEPTION, e);
    }

    /**
     * IO异常
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(IOException.class)
    public ResponseData iOExceptionHandler(IOException e) {
        return responseData(CommonConstant.EX_IO_EXCEPTION, e);
    }

    /**
     * 未知方法异常
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(NoSuchMethodException.class)
    public ResponseData noSuchMethodExceptionHandler(NoSuchMethodException e) {
        return responseData(CommonConstant.EX_NO_SUCH_METHOD_EXCEPTION, e);
    }

    /**
     * 数组越界异常
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(IndexOutOfBoundsException.class)
    public ResponseData indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException e) {
        return responseData(CommonConstant.EX_INDEX_OUT_OF_BOUNDS_EXCEPTION, e);
    }

    /**
     * 请求body缺失异常
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public ResponseData requestNotReadable(HttpMessageNotReadableException e) {
        return responseData(CommonConstant.EX_HTTP_MESSAGE_NOT_READABLE_EXCEPTION, e);
    }

    /**
     * 类型匹配异常
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler({TypeMismatchException.class})
    public ResponseData requestTypeMismatch(TypeMismatchException e) {
        return responseData(CommonConstant.EX_HTTP_MESSAGE_NOT_READABLE_EXCEPTION, e);
    }

    /**
     * 方法不支持异常
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public ResponseData methodNotSupported(HttpRequestMethodNotSupportedException e) {
        return responseData(CommonConstant.EX_HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION, e);
    }

    /**
     * 请求头不支持异常
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler({HttpMediaTypeNotSupportedException.class})
    public ResponseData mediaTypeNotAcceptable(HttpMediaTypeNotSupportedException e) {
        return responseData(CommonConstant.EX_HTTP_MEDIA_TYPE_NOT_ACCEPTABLE_EXCEPTION, e);
    }

    /**
     * 参数解析异常
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(JSONException.class)
    public ResponseData runtimeExceptionHandler(JSONException e) {
        return responseData(CommonConstant.PARAMS_PARSE_EXCEPTION, e);
    }

    /**
     * 参数解析异常
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(JsonParseException.class)
    public ResponseData runtimeExceptionHandler(JsonParseException e) {
        return responseData(CommonConstant.PARAMS_PARSE_EXCEPTION, e);
    }

    /**
     * 请求参数缺失异常
     *
     * @param e 异常
     * @return
     */

    @ExceptionHandler({MissingServletRequestParameterException.class})
    public ResponseData requestMissingServletRequest(MissingServletRequestParameterException e) {
        return responseData(CommonConstant.EX_MISSING_SERVLET_REQUEST_PARAMETER_EXCEPTION, e);
    }

    /**
     * 参数不能为空
     *
     * @param e 异常
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseData exceptionHandler(MethodArgumentNotValidException e) {
        return responseData(CommonConstant.PARAMS_IS_NULL, e);
    }
}

常量类 CommonConstant

package com.study.auth.constant;

/**
 * @Package: com.study.auth.constant
 * @Description: <公共常量类>
 * @Author: milla
 * @CreateDate: 2020/09/04 15:37
 * @UpdateUser: milla
 * @UpdateDate: 2020/09/04 15:37
 * @UpdateRemark: <>
 * @Version: 1.0
 */
public final class CommonConstant {
    /**
     * 当前用户名称
     */
    public static final String C_CURRENT_ACCOUNT = "current_account";

    /**
     * 用户未登录
     */
    public static final String EX_NO_TOKEN_EXCEPTION = "1001";

    //--------------------------------非业务返回码---------------------------------------
    /**
     * 运行时异常
     */
    public static final String EX_RUN_TIME_EXCEPTION = "1100";
    /**
     * 空指针异常
     */
    public static final String EX_NULL_POINTER_EXCEPTION = "1101";
    /**
     * 数据转换异常
     */
    public static final String EX_CLASS_CAST_EXCEPTION = "1102";
    /**
     * IO异常
     */
    public static final String EX_IO_EXCEPTION = "1103";
    /**
     * 找不到该方法异常
     */
    public static final String EX_NO_SUCH_METHOD_EXCEPTION = "1104";
    /**
     * 数组越界异常
     */
    public static final String EX_INDEX_OUT_OF_BOUNDS_EXCEPTION = "1105";
    /**
     * 请求体缺失异常
     */
    public static final String EX_HTTP_MESSAGE_NOT_READABLE_EXCEPTION = "1106";
    /**
     * TYPE匹配异常
     */
    public static final String EX_TYPE_MISMATCH_EXCEPTION = "1107";
    /**
     * 请求参数丢失
     */
    public static final String EX_MISSING_SERVLET_REQUEST_PARAMETER_EXCEPTION = "1108";
    /**
     * 请求方法类型不支持异常
     */
    public static final String EX_HTTP_REQUEST_METHOD_NOT_SUPPORTED_EXCEPTION = "1109";
    /**
     * MEDIA 类型不支持异常
     */
    public static final String EX_HTTP_MEDIA_TYPE_NOT_ACCEPTABLE_EXCEPTION = "1110";
    /**
     * 参数解析异常
     */
    public static final String PARAMS_PARSE_EXCEPTION = "1111";
    /**
     * 参数不能为空
     */
    public static final String PARAMS_IS_NULL = "1112";
    //-----------------------------------------------------------------------------------
}

自定义异常类 CustomMessageException

package com.study.auth.exception;

/**
 * @Package: com.study.auth.exception
 * @Description: <自定义异常类>
 * @Author: MILLA
 * @CreateDate: 2019/8/15 18:39
 * @UpdateUser: MILLA
 * @UpdateDate: 2019/8/15 18:39
 * @UpdateRemark: <>
 * @Version: 1.0
 */
public class CustomMessageException extends RuntimeException {

    public CustomMessageException() {
        super();
    }

    public CustomMessageException(String message) {
        super(message);
    }

    public CustomMessageException(String message, Throwable cause) {
        super(message, cause);
    }

    public CustomMessageException(Throwable cause) {
        super(cause);
    }

    protected CustomMessageException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

所需依赖

因为使用了阿里的fastJson工具类还需要进入该类的依赖

<dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.58</version>
  </dependency>

至此,可以愉快的使用该返回值的增强类了,在为服务中,还以将该代码重构到comm中,供多个服务共同使用,避免重复早轮子

到此这篇关于关于Controller 层返回值的公共包装类的问题的文章就介绍到这了,更多相关Controller 层返回值包装类内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Spring MVC Controller返回值及异常的统一处理方法

    旧的设计方案 开发api的时候,需要先定义好接口的数据响应结果.如下是一个很简单直接的Controller实现方法及响应结果定义. @RestController @RequestMapping("/users") public class UserController { @Inject private UserService userService; @GetRequest("/{userId:\\d+}") public ResponseBean signin

  • 详解springmvc之json数据交互controller方法返回值为简单类型

    当controller方法的返回值为简单类型比如String时,该如何与json交互呢? 使用@RequestBody 比如代码如下: @RequestMapping(value="/ceshijson",produces="application/json;charset=UTF-8") @ResponseBody public String ceshijson(@RequestBody String channelId) throws IOException{

  • 详解利用SpringMVC拦截器控制Controller返回值

    背景:需求是在Controller中方法没有实现时,返回模拟结果.主要用于项目初期前台跟后台的交互,Web项目就是在前台发出请求然后后台响应并返回结果.本示例利用拦截器和注解实现跳过执行方法直接返回定义结构的功能. 通过定义一个StringResult注解,在访问方法的时候返回StringResult中的内容.通过Debug注解来定义方法是否要返回StringResult中的内容. Debug默认为TRUE package com.tiamaes.dep.annotation; import j

  • SpringBoot全局Controller返回值格式统一

    目录 一.返回值格式统一 1.返回值介绍 2.基础类功能 3.基础实现 二.附录说明 一.返回值格式统一 1.返回值介绍 在使用controller对外提供服务的时候,很多时候都需要统一返回值格式,例如 { "status": true, "message": null, "code": "200", "data": { "name": "json", "d

  • SpringMVC Controller 返回值的可选类型详解

    spring mvc 支持如下的返回方式:ModelAndView, Model, ModelMap, Map,View, String, void. ModelAndView @RequestMapping("/hello") public ModelAndView helloWorld() { String message = "Hello World, Spring 3.x!"; return new ModelAndView("hello"

  • 关于Controller 层返回值的公共包装类的问题

    场景:在微服务中,一般返回数据都会有个返回码.返回信息和返回消息体,但是每次返回时候调用或者是封装,太过麻烦,有没有什么办法不用每次都封装呢? 答案是有的. 返回值对象 ResponseData package com.study.auth.comm; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.serializer.

  • ssm框架controller层返回json格式数据到页面的实现

    通常前端页面发送ajax请求,我们只需要返回json格式数据就行 1.在pom.xml加入依赖 <properties> <jackson.version>2.5.4</jackson.version> </properties> <dependencies> <!-- controller返回json --> <dependency> <groupId>com.fasterxml.jackson.core&l

  • 关于springboot的接口返回值统一标准格式

    目录 一.目标 二.为什么要对springboot的接口返回值统一标准格式? 第一种格式:response为String 第二种格式:response为Objct 第三种格式:response为void 第四种格式:response为异常 三.定义response的标准格式 四.初级程序员对response代码封装 步骤1:把标准格式转换为代码 步骤2:把状态码存在枚举类里面 步骤3:加一个体验类 五.高级程序员对response代码封装 步骤1:采用ResponseBodyAdvice技术来实

  • 获取layer.open弹出层的返回值方法

    正在开发的车联网项目用到了layer API.当我在开发"新建电子围栏"的时候需要弹出地图,用户在地图中画一个区域,最后将这个弹出层的数据返回给原页面.下面是我的实现过:程: 触发弹出层的代码: layer.open({ type: 2, title: "设置围栏", shadeClose: true, shade: 0.4, area: ['90%', '90%'], content: "/ElectronicFence/Map?id=" +

  • 解析springboot包装controller返回值问题

    1.springboot项目统一包装返回值,通常返回结果包含code.message.data,结构如下 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class ResponseResult<T> { private int code; private Strin

  • 创建公共调用 jQuery Ajax 带返回值

    复制代码 代码如下: <script type="text/javascript"> /* 请求Ajax 带返回值,并弹出提示框提醒 --------------------------------------------------*/ function getAjax(url, parm, callBack) { $.ajax({ type: 'post', dataType: "text", url: url, data: parm, cache:

随机推荐