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

相关文章
|
27天前
|
JSON Java Apache
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
104 3
|
13天前
|
前端开发 Java Spring
Spring MVC核心:深入理解@RequestMapping注解
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的核心,它将HTTP请求映射到控制器的处理方法上。本文将深入探讨`@RequestMapping`注解的各个方面,包括其注解的使用方法、如何与Spring MVC的其他组件协同工作,以及在实际开发中的应用案例。
28 4
|
13天前
|
前端开发 Java 开发者
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
38 2
|
13天前
|
前端开发 Java Spring
探索Spring MVC:@Controller注解的全面解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序的基石之一。它不仅简化了控制器的定义,还提供了一种优雅的方式来处理HTTP请求。本文将全面解析`@Controller`注解,包括其定义、用法、以及在Spring MVC中的作用。
31 2
|
13天前
|
前端开发 Java 开发者
Spring MVC中的控制器:@Controller注解全解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序控制层的核心。它不仅简化了控制器的定义,还提供了灵活的请求映射和处理机制。本文将深入探讨`@Controller`注解的用法、特点以及在实际开发中的应用。
30 0
|
2月前
|
JSON 前端开发 Java
SSM:SpringMVC
本文介绍了SpringMVC的依赖配置、请求参数处理、注解开发、JSON处理、拦截器、文件上传下载以及相关注意事项。首先,需要在`pom.xml`中添加必要的依赖,包括Servlet、JSTL、Spring Web MVC等。接着,在`web.xml`中配置DispatcherServlet,并设置Spring MVC的相关配置,如组件扫描、默认Servlet处理器等。然后,通过`@RequestMapping`等注解处理请求参数,使用`@ResponseBody`返回JSON数据。此外,还介绍了如何创建和配置拦截器、文件上传下载的功能,并强调了JSP文件的放置位置,避免404错误。
|
2月前
|
JSON Java fastjson
Java Http 接口对接太繁琐?试试 UniHttp 框架吧
UniHttp 是一个声明式的 HTTP 接口对接框架,旨在简化第三方 HTTP 接口的调用过程。通过注解配置,开发者可以像调用本地方法一样发起 HTTP 请求,无需关注请求的构建和响应处理细节。框架支持多种请求方式和参数类型,提供灵活的生命周期钩子以满足复杂的对接需求,适用于企业级项目的快速开发和维护。GitHub 地址:[UniAPI](https://github.com/burukeYou/UniAPI)。
|
2月前
|
前端开发 Java 应用服务中间件
【Spring】Spring MVC的项目准备和连接建立
【Spring】Spring MVC的项目准备和连接建立
60 2
|
3月前
|
缓存 前端开发 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版)
|
2月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
161 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习