SpringMVC利用注解 规范http接口返回值

简介: SpringMVC利用注解 规范http接口返回值一般在项目构建时,会选择定义基础接口返回值规范实体,并直接规定返回实体,但在控制器上对实体的进行的实例化会产生多余代码,为了减少这一部门的冗余代码,部分项目会采用注解的方式或者直接全局使用切面来处理返回值。

SpringMVC利用注解 规范http接口返回值

一般在项目构建时,会选择定义基础接口返回值规范实体,并直接规定返回实体,但在控制器上对实体的进行的实例化会产生多余代码,为了减少这一部门的冗余代码,部分项目会采用注解的方式或者直接全局使用切面来处理返回值。以下我将介绍一下我的处理方案。

实现代码:

注解代码:

import java.lang.annotation.*;

/**
 * 如果该注解的方法出现异常,则会反馈标准的异常结果【ResponseMsg.java】给前端或者服务调用方
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyResponse {
}

返回值实体用于测试,具体的web应用,可以具体使用项目的规范,以下只是测试时使用的实体规范,具体应用时可以根据具体需要来拼装数据

import lombok.Data;

/**
 * 接口默认返回参数
 * lombok.Data 可以改成直接写入封装方法
 */
@Data
public class ResponseMsg {
    /**
     * 代码
     */
    private int code;
    /**
     * 消息
     */
    private String msg;
    /**
     * 是否成功
     */
    private boolean success;
    /**
     * 数据
     */
    private Object data;
}

自定义异常,用于测试,同理可根据具体项目需求改变

import lombok.Data;

@Data
public class MyException extends RuntimeException{
    private int code;
    /**
     * 构造
     */
    public MyException(int code, String msg) {
        super(msg);
        this.code = code;
    }
}

关键代码,返回值切面,JSON,Slf4j类根据具体项目依赖处理,此处为了减少代码增加了这个类。

实际就是利用切面获取返回值并拼装,处理Object及void类型,并通过捕捉切点的异常封装返回值。

建议将切面位置提前,保证其他切面的异常不影响返回值的规范。

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import self.aop.anno.MyResponse;
import self.aop.model.ResponseMsg;
import self.exception.MyException;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 使用AOP拦截出现异常的Controller的方法,并反馈标准的异常描述
 * 
 * @Slf4j可以去掉,换成手动的log
 */
@Order(1)
@Aspect
@Component
@Slf4j
public class ResponseAspect {

    private static final String VOID = "void";

    private static final int ERR_CODE = 500;

    @Around(value = "@annotation(catchErr)")
    public Object doAudit(ProceedingJoinPoint point, MyResponse catchErr) throws Throwable {
        Object returnVal;
        ResponseMsg resultMsg;
        try {
            returnVal = point.proceed();
        } catch (MyException ex) {
            resultMsg = new ResponseMsg();
            resultMsg.setCode(ex.getCode());
            resultMsg.setMsg(ex.getMessage());
            resultMsg.setSuccess(false);
            writeResultMessage2Writer(point, resultMsg);
            log.info("{}", ex);
            return resultMsg;
        } catch (Exception ex) {
            resultMsg = new ResponseMsg();
            resultMsg.setCode(ERR_CODE);
            resultMsg.setMsg(ex.getMessage());
            resultMsg.setSuccess(false);
            writeResultMessage2Writer(point, resultMsg);
            log.error("{}", ex);
            return resultMsg;
        }
        resultMsg = new ResponseMsg();
        resultMsg.setCode(200);
        resultMsg.setMsg("成功");
        resultMsg.setSuccess(true);
        Class returnType = ((MethodSignature) point.getSignature()).getReturnType();
        if (StringUtils.equals(returnType.getName(), VOID)) {
            writeResultMessage2Writer(point, resultMsg);
        }
        resultMsg.setData(returnVal);
        return resultMsg;
    }

    /**
     * 返回void情况下单独做response处理防止无法输出
     * @param point 切点
     * @param resultMsg 消息实体
     * @throws IOException io异常
     */
    private void writeResultMessage2Writer(ProceedingJoinPoint point, ResponseMsg resultMsg) throws IOException {
        Class returnType = ((MethodSignature) point.getSignature()).getReturnType();
        if (!StringUtils.equals(returnType.getName(), VOID)) {
            return;
        }
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();

        response.setCharacterEncoding("UTF-8");
        response.setHeader("content-type", "application/json;charset=UTF-8");
        response.getWriter().write(JSON.toJSONString(resultMsg, SerializerFeature.PrettyFormat));
    }
}

以下是测试使用的web控制器

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import self.aop.anno.MyResponse;
import self.exception.MyException;

/**
 * 返回值规范测试控制器
 */
@Controller
@RequestMapping("response/msg")
public class ResponseMsgController {
    @PostMapping("/object")
    @MyResponse
    @ResponseBody
    public Object objectFunction(){
        return "data";
    }

    @PostMapping("/void")
    @MyResponse
    @ResponseBody
    public void voidFunction(){}

    @PostMapping("/my/exception")
    @MyResponse
    @ResponseBody
    public void myExceptionFunction(){
        throw new MyException(501,"手动抛自定义异常");
    }

    @PostMapping("/exception")
    @MyResponse
    @ResponseBody
    public void exceptionFunction(){
        throw new RuntimeException("手动抛其他异常");
    }
}

Object类型返回值

image

void类型返回值

image

自定义异常返回值

image

其他异常返回值

image

相关文章
|
28天前
|
JSON 前端开发 Java
SSM:SpringMVC
本文介绍了SpringMVC的依赖配置、请求参数处理、注解开发、JSON处理、拦截器、文件上传下载以及相关注意事项。首先,需要在`pom.xml`中添加必要的依赖,包括Servlet、JSTL、Spring Web MVC等。接着,在`web.xml`中配置DispatcherServlet,并设置Spring MVC的相关配置,如组件扫描、默认Servlet处理器等。然后,通过`@RequestMapping`等注解处理请求参数,使用`@ResponseBody`返回JSON数据。此外,还介绍了如何创建和配置拦截器、文件上传下载的功能,并强调了JSP文件的放置位置,避免404错误。
|
29天前
|
JSON Java fastjson
Java Http 接口对接太繁琐?试试 UniHttp 框架吧
UniHttp 是一个声明式的 HTTP 接口对接框架,旨在简化第三方 HTTP 接口的调用过程。通过注解配置,开发者可以像调用本地方法一样发起 HTTP 请求,无需关注请求的构建和响应处理细节。框架支持多种请求方式和参数类型,提供灵活的生命周期钩子以满足复杂的对接需求,适用于企业级项目的快速开发和维护。GitHub 地址:[UniAPI](https://github.com/burukeYou/UniAPI)。
|
1月前
|
前端开发 Java 应用服务中间件
【Spring】Spring MVC的项目准备和连接建立
【Spring】Spring MVC的项目准备和连接建立
52 2
|
2月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
1月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
98 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
2月前
|
JSON 移动开发 监控
快速上手|HTTP 接口功能自动化测试
HTTP接口功能测试对于确保Web应用和H5应用的数据正确性至关重要。这类测试主要针对后台HTTP接口,通过构造不同参数输入值并获取JSON格式的输出结果来进行验证。HTTP协议基于TCP连接,包括请求与响应模式。请求由请求行、消息报头和请求正文组成,响应则包含状态行、消息报头及响应正文。常用的请求方法有GET、POST等,而响应状态码如2xx代表成功。测试过程使用Python语言和pycurl模块调用接口,并通过断言机制比对实际与预期结果,确保功能正确性。
233 3
快速上手|HTTP 接口功能自动化测试
|
26天前
|
Java 数据处理 开发者
Java Http 接口对接太繁琐?试试 UniHttp 框架~
【10月更文挑战第10天】在企业级项目开发中,HTTP接口对接是一项常见且重要的任务。传统的编程式HTTP客户端(如HttpClient、Okhttp)虽然功能强大,但往往需要编写大量冗长且复杂的代码,这对于项目的可维护性和可读性都是一个挑战。幸运的是,UniHttp框架的出现为这一问题提供了优雅的解决方案。
57 0
|
2月前
|
XML 缓存 前端开发
springMVC02,restful风格,请求转发和重定向
文章介绍了RESTful风格的基本概念和特点,并展示了如何使用SpringMVC实现RESTful风格的请求处理。同时,文章还讨论了SpringMVC中的请求转发和重定向的实现方式,并通过具体代码示例进行了说明。
springMVC02,restful风格,请求转发和重定向
|
3月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
3月前
|
XML JSON 数据库
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
这篇文章详细介绍了RESTful的概念、实现方式,以及如何在SpringMVC中使用HiddenHttpMethodFilter来处理PUT和DELETE请求,并通过具体代码案例分析了RESTful的使用。
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
下一篇
无影云桌面