zoukankan      html  css  js  c++  java
  • 无侵入式 统一返回JSON格式接口开发demo

    参考
    https://github.com/galaxy-sea/galaxy-blogs/tree/master/code/responseResult

    自己copy了一份发现使用eureka或者直接引入如下依赖,接口浏览器访问返回xml格式结果

    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
    </dependency>
    

    如图:
    百度一下,Eureka依赖自动引入的

    所以只需要在eureka依赖中使用 排除该依赖就行。

     <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>com.fasterxml.jackson.dataformat</groupId>
                    <artifactId>jackson-dataformat-xml</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    

    具体统一json代码实现如下:

    ==========================================
    ResponseResultBody.java

    package com.wwy.newapi.result;
    
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE, ElementType.METHOD})
    @Documented
    @ResponseBody
    public @interface ResponseResultBody {
    
    }
    

    ==========================================
    ResponseResultBodyAdvice.java

    package com.wwy.newapi.result;
    
    import java.lang.annotation.Annotation;
    
    import org.springframework.core.MethodParameter;
    import org.springframework.core.annotation.AnnotatedElementUtils;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    import org.springframework.http.converter.HttpMessageConverter;
    import org.springframework.http.server.ServerHttpRequest;
    import org.springframework.http.server.ServerHttpResponse;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RestControllerAdvice;
    import org.springframework.web.context.request.WebRequest;
    import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
    import org.springframework.web.util.WebUtils;
    
    import com.wwy.newapi.result.exception.ResultException;
    
    import lombok.extern.slf4j.Slf4j;
    
    /**
     * 使用这个注解就可以返回统一的json格式,  用于类和方法上
     * @author wangwenying
     *
     */
    @Slf4j
    @RestControllerAdvice
    public class ResponseResultBodyAdvice implements ResponseBodyAdvice<Object> {
    
        private static final Class<? extends Annotation> ANNOTATION_TYPE = ResponseResultBody.class;
    
        /** 判断类或者方法是否使用了 @ResponseResultBody */
        @Override
        public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
            return AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ANNOTATION_TYPE) || returnType.hasMethodAnnotation(ANNOTATION_TYPE);
        }
    
        /** 当类或者方法使用了 @ResponseResultBody 就会调用这个方法 */
        @Override
        public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
            if (body instanceof Result) {
                return body;
            }
            return Result.success(body);
        }
    
    
        /**
         * 提供对标准Spring MVC异常的处理
         *
         * @param ex      the target exception
         * @param request the current request
         */
        @ExceptionHandler(Exception.class)
        public final ResponseEntity<Result<?>> exceptionHandler(Exception ex, WebRequest request) {
            HttpHeaders headers = new HttpHeaders();
            if (ex instanceof ResultException) {
                return this.handleResultException((ResultException) ex, headers, request);
            }
            // TODO: 2019/10/05 galaxy 这里可以自定义其他的异常拦截
            return this.handleException(ex, headers, request);
        }
    
        /** 对ResultException类返回返回结果的处理 */
        protected ResponseEntity<Result<?>> handleResultException(ResultException ex, HttpHeaders headers, WebRequest request) {
            Result<?> body = Result.failure(ex.getResultStatus());
            HttpStatus status = ex.getResultStatus().getHttpStatus();
            return this.handleExceptionInternal(ex, body, headers, status, request);
        }
    
        /** 异常类的统一处理 */
        protected ResponseEntity<Result<?>> handleException(Exception ex, HttpHeaders headers, WebRequest request) {
            Result<?> body = Result.failure();
            HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
            return this.handleExceptionInternal(ex, body, headers, status, request);
        }
    
        /**
         * org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler#handleExceptionInternal(java.lang.Exception, java.lang.Object, org.springframework.http.HttpHeaders, org.springframework.http.HttpStatus, org.springframework.web.context.request.WebRequest)
         * <p>
         * A single place to customize the response body of all exception types.
         * <p>The default implementation sets the {@link WebUtils#ERROR_EXCEPTION_ATTRIBUTE}
         * request attribute and creates a {@link ResponseEntity} from the given
         * body, headers, and status.
         */
        protected ResponseEntity<Result<?>> handleExceptionInternal(
                Exception ex, Result<?> body, HttpHeaders headers, HttpStatus status, WebRequest request) {
    
            if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
                request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, ex, WebRequest.SCOPE_REQUEST);
            }
            return new ResponseEntity<>(body, headers, status);
        }
    }
    

    ==========================================
    Result.java

    package com.wwy.newapi.result;
    
    /**
     * 后端返回给前端的json格式
     *  todo 返回格式参考 org.springframework.boot.web.servlet.error.DefaultErrorAttributes
     *
     * @author galaxy
     * @date 2019/10/05 16:19
     */
    public class Result<T> {
        public Integer getCode() {
    		return code;
    	}
    
    	public void setCode(Integer code) {
    		this.code = code;
    	}
    
    	public String getMessage() {
    		return message;
    	}
    
    	public void setMessage(String message) {
    		this.message = message;
    	}
    
    	public T getData() {
    		return data;
    	}
    
    	public void setData(T data) {
    		this.data = data;
    	}
    
    	/** 业务错误码 */
        private Integer code;
        /** 信息描述 */
        private String message;
        /** 返回参数 */
        private T data;
    
        private Result(ResultStatus resultStatus, T data) {
            this.code = resultStatus.getCode();
            this.message = resultStatus.getMessage();
            this.data = data;
        }
    
        /** 业务成功返回业务代码和描述信息 */
        public static Result<Void> success() {
            return new Result<Void>(ResultStatus.SUCCESS, null);
        }
    
        /** 业务成功返回业务代码,描述和返回的参数 */
        public static <T> Result<T> success(T data) {
            return new Result<T>(ResultStatus.SUCCESS, data);
        }
    
        /** 业务成功返回业务代码,描述和返回的参数 */
        public static <T> Result<T> success(ResultStatus resultStatus, T data) {
            if (resultStatus == null) {
                return success(data);
            }
            return new Result<T>(resultStatus, data);
        }
    
        /** 业务异常返回业务代码和描述信息 */
        public static <T> Result<T> failure() {
            return new Result<T>(ResultStatus.INTERNAL_SERVER_ERROR, null);
        }
    
        /** 业务异常返回业务代码,描述和返回的参数 */
        public static <T> Result<T> failure(ResultStatus resultStatus) {
            return failure(resultStatus, null);
        }
    
        /** 业务异常返回业务代码,描述和返回的参数 */
        public static <T> Result<T> failure(ResultStatus resultStatus, T data) {
            if (resultStatus == null) {
                return new Result<T>(ResultStatus.INTERNAL_SERVER_ERROR, null);
            }
            return new Result<T>(resultStatus, data);
        }
    }
    

    ==========================================
    ResultStatus.java

    package com.wwy.newapi.result;
    
    import org.springframework.http.HttpStatus;
    
    public enum ResultStatus {
    
        SUCCESS(HttpStatus.OK, 200, "OK"),
        BAD_REQUEST(HttpStatus.BAD_REQUEST, 400, "Bad Request"),
        INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 500, "Internal Server Error"),
        ;
    
        /** 返回的HTTP状态码,  符合http请求 */
        private HttpStatus httpStatus;
        /** 业务异常码 */
        private Integer code;
        /** 业务异常信息描述 */
        private String message;
    
        ResultStatus(HttpStatus httpStatus, Integer code, String message) {
            this.httpStatus = httpStatus;
            this.code = code;
            this.message = message;
        }
    
    	public HttpStatus getHttpStatus() {
    		return httpStatus;
    	}
    
    	public void setHttpStatus(HttpStatus httpStatus) {
    		this.httpStatus = httpStatus;
    	}
    
    	public Integer getCode() {
    		return code;
    	}
    
    	public void setCode(Integer code) {
    		this.code = code;
    	}
    
    	public String getMessage() {
    		return message;
    	}
    
    	public void setMessage(String message) {
    		this.message = message;
    	}
    }
    

    ==========================================
    WebMvcConfiguration.java

    package com.wwy.newapi.result;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.converter.HttpMessageConverter;
    import org.springframework.http.converter.StringHttpMessageConverter;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    import java.util.List;
    
    /**
     * @author changjinwei
     * @date 2020/11/10
     */
    @Configuration
    public class WebMvcConfiguration implements WebMvcConfigurer {
    
    
        /**
         * // 这里是修复 com.galaxy.controller.HelloResultController.testString 方法, 解决方案有两个
         * // 1。 重写 org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(T, org.springframework.core.MethodParameter, org.springframework.http.server.ServletServerHttpRequest, org.springframework.http.server.ServletServerHttpResponse)
         * // 2。 实现WebMvcConfigurer或者继承WebMvcConfigurationSupport 重写 #extendMessageConverters(java.util.List)方法,
         * // 第二个方法实现如下
         */
        @Override
        public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
            converters.removeIf(converter -> converter instanceof StringHttpMessageConverter);
        }
    }
    

    ==========================================
    ResultException.java

    package com.wwy.newapi.result.exception;
    
    import com.wwy.newapi.result.ResultStatus;
    
    /**
     * 业务异常类
     *
     * @author galaxy
     * @date 2019/10/05 16:19
     */
    
    @SuppressWarnings("serial")
    public class ResultException extends Exception {
    
        /**
         * 业务异常信息信息
         */
        ResultStatus resultStatus;
    
        public ResultException() {
            this(ResultStatus.INTERNAL_SERVER_ERROR);
        }
    
        public ResultStatus getResultStatus() {
    		return resultStatus;
    	}
    
    	public void setResultStatus(ResultStatus resultStatus) {
    		this.resultStatus = resultStatus;
    	}
    
    	public ResultException(ResultStatus resultStatus) {
            super(resultStatus.getMessage());
            this.resultStatus = resultStatus;
        }
    }
    

    ==========================================
    HelloResultController.java

    package com.wwy.newapi.controller;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.wwy.newapi.result.ResponseResultBody;
    import com.wwy.newapi.result.Result;
    import com.wwy.newapi.result.exception.ResultException;
    
    /**
     * @author galaxy
     * @date 2019/10/05 16:19
     */
    
    @RestController
    @RequestMapping("/helloResult")
    @ResponseResultBody
    public class HelloResultController {
    
        private static final HashMap<String, Object> INFO;
    
        static {
            INFO = new HashMap<String, Object>();
            INFO.put("name", "galaxy");
            INFO.put("age", "70");
        }
    
        @GetMapping("hello")
        public HashMap<String, Object> hello() {
            return INFO;
        }
    
        @GetMapping("result")
        public Result<Map<String, Object>> helloResult() {
            return Result.success(INFO);
        }
    
        @GetMapping("helloError")
        public HashMap<String, Object> helloError() throws Exception {
            throw new Exception("helloError");
        }
    
        @GetMapping("helloMyError")
        public HashMap<String, Object> helloMyError() throws Exception {
            throw new ResultException();
        }
    
        @GetMapping(value = "testString")
        public String testString() {
            return "helloString";
        }
    
        @GetMapping(value = "testInt")
        public Integer testInt() {
            return 123;
        }
    }
    

    ==========================================
    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.0.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.galaxy</groupId>
        <artifactId>response-result</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>response-result</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.10</version>
                <scope>provided</scope>
            </dependency>
    
    
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    结果如下:

  • 相关阅读:
    C#网络编程TCP通信实例程序简单设计
    C#网络编程TCP通信实例程序简单设计
    2329: 密码破解【数组】
    纸牌游戏小猫钓鱼
    认识栈
    认识队列
    2754: C++习题快速排序
    3047: 快速排序算法
    Problem A: C语言习题 链表建立,插入,删除,输出
    Problem C: 动态规划基础题目之数字三角形
  • 原文地址:https://www.cnblogs.com/stubborn-dude/p/14277260.html
Copyright © 2011-2022 走看看