前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Rest API: Json参数格式错误时显示Json原文

Rest API: Json参数格式错误时显示Json原文

作者头像
十毛
发布于 2019-03-27 07:18:22
发布于 2019-03-27 07:18:22
2.2K00
代码可运行
举报
运行总次数:0
代码可运行

后台提供API给前端调用,一般使用HttpMessageConverterJson字符串转换成对象,如果存在格式问题则会抛出异常HttpMessageNotReadableException。但是后台拿不到原始的Json字符串,不方便定位到确切的格式错误。 本文介绍一个简易方法,可以在出错时,展示Json原文信息。

一开始想寻找其他方式,当抛出异常的时候,就从HttpServletRequest读取body内容。但是做不到,因为在做Json读取的时候,InputStream已经被读取了,无法再次获取到body内容。所以只能通过自定义MessageConverter的方式。

其实也可以,把request中inpustream读取出来保存,再提供一个getInputStream,参见 How to read request.getInputStream() multiple times

自定义MessageConverter

代码语言:javascript
代码运行次数:0
运行
复制
import com.google.common.io.CharStreams;

public class HttpMessageConverter extends GsonHttpMessageConverter {

    @Override
    public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        TypeToken<?> token = getTypeToken(type);
        return readTypeToken(token, inputMessage);
    }

    private Object readTypeToken(TypeToken<?> token, HttpInputMessage inputMessage) throws IOException {
        Reader json = new InputStreamReader(inputMessage.getBody(), getCharset(inputMessage.getHeaders()));
        //先获取Json原始字符串
        final String jsonBody = CharStreams.toString(json);
        try {
            return this.getGson().fromJson(jsonBody, token.getType());
        } catch (JsonParseException ex) {
            //解析失败,则在异常中输出Json原始字符串
            throw new HttpMessageNotReadableException(String.format("JSON parse error: %s%n%s", ex.getMessage(), jsonBody), ex);
        }
    }

    private Charset getCharset(HttpHeaders headers) {
        if (headers == null || headers.getContentType() == null || headers.getContentType().getCharset() == null) {
            return DEFAULT_CHARSET;
        }
        return headers.getContentType().getCharset();
    }
}

配置自定义MessageConverter

spring-mvc.xml

代码语言:javascript
代码运行次数:0
运行
复制
<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="com.tenmao.HttpMessageConverter" />
    </mvc:message-converters>
</mvc:annotation-driven>

结果

假设参数对象如下:

代码语言:javascript
代码运行次数:0
运行
复制
@Data
public class Person {
    private String name;
    private Integer age;
    private Boolean gender;
    private List<String> hobbies;
}

如果收到错误格式的Json消息,则会抛出异常(hobbies应该是一个数组,参数中是字符串basketball)

代码语言:javascript
代码运行次数:0
运行
复制
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 5 column 14 path $.hobbies
{
    "name": "tenmao",
    "gender": true,
    "age": 28,
    "hobbies": "basketball"
}; nested exception is com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 5 column 14 path $.hobbies

参考

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.01.09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Spring Boot 如何热加载jar实现动态插件?
动态插件化编程是一件很酷的事情,能实现业务功能的 「解耦」 便于维护,另外也可以提升 「可扩展性」 随时可以在不停服务器的情况下扩展功能,也具有非常好的 「开放性」 除了自己的研发人员可以开发功能之外,也能接纳第三方开发商按照规范开发的插件。
陶陶技术笔记
2021/10/20
6.2K0
JDK、Dubbo、Spring 三种 SPI 机制,谁更好?
公众号运营至今,离不开小伙伴们的支持。为了给小伙伴们提供一个互相交流的平台,特地开通了官方交流群。关注公众号「Java后端技术全栈」回复「进群」即可。
田维常
2021/05/11
7150
源码级深度理解 Java SPI
SPI 是一种用于动态加载服务的机制。它的核心思想就是解耦,属于典型的微内核架构模式。SPI 在 Java 世界应用非常广泛,如:Dubbo、Spring Boot 等框架。本文从源码入手分析,深入探讨 Java SPI 的特性、原理,以及在一些比较经典领域的应用。
2020labs小助手
2022/11/07
8860
温习 SPI 机制 (Java SPI 、Spring SPI、Dubbo SPI)
SPI 全称为 Service Provider Interface,是一种服务发现机制。
勇哥java实战
2024/10/29
4150
温习 SPI 机制 (Java SPI 、Spring SPI、Dubbo SPI)
3W 字的 Spring Boot 超详细总结
在过去两三年的 Spring 生态圈,最让人兴奋的莫过于 Spring Boot 框架。或许从命名上就能看出这个框架的设计初衷:快速的启动 Spring 应用。因而 Spring Boot 应用本质上就是一个基于 Spring 框架的应用,它是 Spring 对“约定优先于配置”理念的最佳实践产物,它能够帮助开发者更快速高效地构建基于 Spring 生态圈的应用。
麦洛
2021/08/23
4920
3W 字的 Spring Boot 超详细总结
Spring Boot 之 spring.factories
SPI的全名为Service Provider Interface.大多数开发人员可能不熟悉,因为这个是针对厂商或者插件的。在java.util.ServiceLoader的文档里有比较详细的介绍。简单的总结下java SPI机制的思想。我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块的方案,xml解析模块、jdbc模块的方案等。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。java SPI就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。
黑洞代码
2021/07/14
7580
Spring Boot 之 spring.factories
Spring.Factories配置文件的工厂模式
在SpringBoot的各个依赖包下,我们经常看到 META-INF/spring.factories这个文件。spring.factories 文件的内容基本上都是这样的格式:
技术从心
2021/02/03
8260
SpringFactories
是Spring框架中的一个工厂类加载机制,它通过在META-INF/spring.factories文件中定义实现特定接口的类的全限定名,使得能够动态地将这些类加载到应用程序中。下面我们将结合Jvm类的加载机制进行详细解释和代码示例。
疯狂的KK
2023/04/03
3720
【Java——SPI机制详解】
SPI(Service Provider Interface),是JDK内置的一种服务提供发现机制,可以用来启用框架扩展和替换组件,主要是被框架的开发人员使用,比如java.sql.Driver接口,其他不同厂商可以针对同一接口做出不同的实现,MySQL和PostgreSQL都有不同的实现提供给用户,而Java的SPI机制可以为某个接口寻找服务实现。Java中SPI机制主要思想是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,其核心思想就是 解耦。
奥耶可乐冰
2024/05/31
2.1K0
基于spring-plugin做插件化开发
一、什么是插件化开发二、如何实现插件化开发三、spring-plugin实现原理四、总结与思考五、参考
叔牙
2023/08/09
5.5K0
基于spring-plugin做插件化开发
spring的spi
SPI(service provider interface)机制是JDK内置的一种服务发现机制,可以动态的发现服务,即服务提供商,它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类。目前这种大部分都利用SPI的机制进行服务提供,比如:dubbo、spring、JDBC、等;
逍遥壮士
2020/09/18
9960
spring的spi
Spring高手之路14——深入浅出:SPI机制在JDK与Spring Boot中的应用
SPI (Service Provider Interface) 是一种服务发现机制,它允许第三方提供者为核心库或主框架提供实现或扩展。这种设计允许核心库/框架在不修改自身代码的情况下,通过第三方实现来增强功能。
砖业洋__
2023/09/13
4K1
Spring高手之路14——深入浅出:SPI机制在JDK与Spring Boot中的应用
JDK/Dubbo/Spring 三种 SPI 机制,谁更好?
举个栗子,现在我们设计了一款全新的日志框架:super-logger 。默认以XML文件作为我们这款日志的配置文件,并设计了一个配置文件解析的接口:
芋道源码
2021/05/10
5020
JDK/Dubbo/Spring 三种 SPI 机制,谁更好?
SPI的简单应用
在查看java.sql.DriverManager源码时,发现有这么一个静态方法叫做loadInitialDrivers()。在这个方法里,我发现在项目启动中驱动管理器会从系统变量jdbc.drivers中获取具体的驱动实现并注册,其次会使用SPI注册驱动。这些我在 再谈驱动注册 中已经讲过了,那么什么是SPI?怎么用?
zhangheng
2020/04/28
6570
Spring Boot 自动配置的 “魔法” 是如何实现的?
Spring Boot是Spring旗下众多的子项目之一,其理念是约定优于配置,它通过实现了自动配置(大多数用户平时习惯设置的配置作为默认配置)的功能来为用户快速构建出标准化的应用。Spring Boot的特点可以概述为如下几点:
用户1257393
2018/07/30
7320
Spring Boot 自动配置的 “魔法” 是如何实现的?
谈谈一个框架的扩展加载
在 SpringBoot 启动类上都会标注@SpringBootApplication这个注解,其中的最重要的组成是@EnableAutoConfiguration, 再进入会发现是 @Import (AutoConfigurationImportSelector.class)这个注解在起作用。
leobhao
2022/06/28
5430
一文读懂什么是SPI机制
A service is a well-known set of interfaces and (usually abstract) classes. A service provider is a specific implementation of a service.
凯哥的Java技术活
2022/07/08
6080
一文读懂什么是SPI机制
深入剖析 Spring Boot 的 SPI 机制
SPI(Service Provider Interface)是JDK内置的一种服务提供发现机制,可以用来启用框架扩展和替换组件,主要用于框架中开发,例如Dubbo、Spring、Common-Logging,JDBC等采用采用SPI机制,针对同一接口采用不同的实现提供给不同的用户,从而提高了框架的扩展性。
码猿技术专栏
2023/05/01
9310
深入剖析 Spring Boot 的 SPI 机制
聊聊 SPI 机制
短信平台是通过 SPI 机制加载三方渠道插件,所以这篇文章,我们有必要温习 SPI 机制。
勇哥java实战
2023/11/25
3570
Spring Boot - 自动配置实现原理
Spring Boot 中的配置体系是一套强大而复杂的体系,其中最基础、最核心的要数自动配置(AutoConfiguration)机制了。
小小工匠
2021/08/17
4500
Spring Boot - 自动配置实现原理
相关推荐
Spring Boot 如何热加载jar实现动态插件?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档