返回顶部
首页 > 资讯 > 精选 >如何使用后端的Long型参数
  • 937
分享到

如何使用后端的Long型参数

2023-06-16 06:06:16 937人浏览 独家记忆
摘要

本篇内容介绍了“如何使用后端的Long型参数”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、问题描述最近在改造内部管理系统的时候, 发现了

本篇内容介绍了“如何使用后端的Long型参数”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一、问题描述

最近在改造内部管理系统的时候, 发现了一个巨坑,就是前端 js 在获取后端 Long 型参数时,出现精度丢失!

起初,用 postman 模拟接口请求,都很正常,但是用浏览器请求的时候,就出现问题了!

问题复现:

@RequestMapping("/queryUser") public List<User> queryUser(){     List<User> resultList = new ArrayList<>();     User user = new User();     //赋予一个long型用户ID     user.setId(123456789012345678L);     resultList.add(user);     return resultList; }

打开浏览器,请求接口,结果如下!

如何使用后端的Long型参数

用 postman 模拟接口请求,结果如下!

如何使用后端的Long型参数

刚开始的时候,还真没发现这个坑,结果当进行测试的时候,才发现前端传给后端的ID,与数据库中存的ID不一致,才发现 javascript  还有这个天坑!

由于 JavaScript 中 Number 类型的自身原因,并不能完全表示 Long 型的数字,在 Long  长度大于17位时会出现精度丢失的问题。

当我们把上面的用户 ID 改成 19 位的时候,我们再来看看浏览器请求返回的结果。

//设置用户ID,位数为19位 user.setId(1234567890123456789l);

浏览器请求结果!

如何使用后端的Long型参数

当返回的结果超过17位的时候,后面的全部变成0!

二、解决办法

遇到这种情况,应该怎么办呢?

  • 第一种办法:在后台把 long 型改为String类型,但是代价有点大,只要涉及到的地方都需要改

  • 第二种办法:使用工具进行转化把 long 型改为String类型,这种方法可以实现全局转化(推荐)

  • 第三种办法:前端进行处理(目前没有很好的办法,不推荐)

因为项目涉及到的代码非常多,所以不可能把 long 型改为 String 类型,而且使用 Long  类型的方法非常多,改起来风险非常大,所以不推荐使用!

最理想的方法,就是使用aop代理拦截所有的方法,对返回参数进行统一处理,使用工具进行转化,过程如下!

1. Jackson 工具序列化对象

我们可以使用Jackson工具包来实现对象序列化。

首先在 Maven 中添加必须的依赖:

<!--jackson依赖--> <dependency>     <groupId>com.fasterxml.jackson.core</groupId>     <artifactId>jackson-core</artifactId>     <version>2.9.8</version> </dependency> <dependency>     <groupId>com.fasterxml.jackson.core</groupId>     <artifactId>jackson-annotations</artifactId>     <version>2.9.8</version> </dependency> <dependency>     <groupId>com.fasterxml.jackson.core</groupId>     <artifactId>jackson-databind</artifactId>     <version>2.9.8</version> </dependency>

编写一个转化工具类JSONUtil:

public class JsonUtil {      private static final Logger log = LoggerFactory.getLogger(JsonUtil.class);      private static ObjectMapper objectMapper = new ObjectMapper();     private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";      static {         // 对象的所有字段全部列入         objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);         // 取消默认转换timestamps形式         objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);         // 忽略空bean转json的错误         objectMapper.configure(SerializationFeature.FaiL_ON_EMPTY_BEANS, false);         //设置为东八区         objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));         // 统一日期格式         objectMapper.setDateFormat(new SimpleDateFormat(DATE_FORMAT));         // 反序列化时,忽略在json字符串中存在, 但在java对象中不存在对应属性的情况, 防止错误         objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);         // 序列换成json时,将所有的long变成string         objectMapper.reGISterModule(new SimpleModule().addSerializer(Long.class, ToStringSerializer.instance).addSerializer(Long.TYPE, ToStringSerializer.instance));     }           public static <T> String objToStr(T obj) {         if (null == obj) {             return null;         }          try {             return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);         } catch (Exception e) {             log.warn("objToStr error: ", e);             return null;         }     }           public static <T> T strToObj(String str, Class<T> clazz) {         if (StringUtils.isBlank(str) || null == clazz) {             return null;         }          try {             return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);         } catch (Exception e) {             log.warn("strToObj error: ", e);             return null;         }     }           public static <T> T strToObj(String str, TypeReference<T> typeReference) {         if (StringUtils.isBlank(str) || null == typeReference) {             return null;         }          try {             return (T) (typeReference.getType().equals(String.class) ? str : objectMapper.readValue(str, typeReference));         } catch (Exception e) {             log.warn("strToObj error", e);             return null;         }     } }

紧接着,编写一个实体类Person,用于测试:

@Data public class Person implements Serializable {      private static final long serialVersionUID = 1L;      private Integer id;      //Long型参数     private Long uid;     private String name;     private String address;     private String mobile;      private Date createTime; }

最后,我们编写一个测试类测试一下效果:

public static void main(String[] args) {     Person person = new Person();     person.setId(1);     person.setUid(1111L);     person.setName("hello");     person.setAddress("");     System.out.println(JsonUtil.objToStr(person)); }

输出结果如下:

如何使用后端的Long型参数

其中最关键一行代码,是注册了这个转换类,从而实现将所有的 long 变成 string。

// 序列换成json时,将所有的long变成string SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(Long.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); objectMapper.registerModule(simpleModule);

如果想对某个日期进行格式化,可以全局设置。

//全局统一日期格式 objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

也可以,单独对某个属性进行设置,例如对createTime属性格式化为yyyy-MM-dd,只需要加上如下注解即可。

@JsonFormat(pattern="yyyy-MM-dd", timezone="GMT+8") private Date createTime;

工具转化类写好之后,就非常简单了,只需要对 aop 拦截的方法返回的参数,进行序列化就可以自动实现将所有的 long 变成 string。

2. SpringMVC 配置

如果是 springMVC 项目,操作也很简单。

自定义一个实现类,继承自ObjectMapper:

package com.example.util;   public class CustomObjectMapper extends ObjectMapper {      public CustomObjectMapper() {         super();         SimpleModule simpleModule = new SimpleModule();         simpleModule.addSerializer(Long.class, ToStringSerializer.instance);         simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);         registerModule(simpleModule);     } }

springmvc 的配置文件中加上如下配置:

<mvc:annotation-driven >     <mvc:message-converters>         <bean class="org.springframework.Http.converter.StringHttpMessageConverter">             <constructor-arg index="0" value="utf-8" />             <property name="supportedMediaTypes">                 <list>                     <value>application/json;charset=UTF-8</value>                     <value>text/plain;charset=UTF-8</value>                 </list>             </property>         </bean>                   <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">             <property name="objectMapper">                 <bean class="com.example.util.CustomObjectMapper">                     <property name="dateFormat">                         <-对日期进行统一转化->                         <bean class="java.text.SimpleDateFormat">                             <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />                         </bean>                     </property>                 </bean>             </property>         </bean>     </mvc:message-converters> </mvc:annotation-driven>

3. SpringBoot 配置

如果是 SpringBoot 项目,操作也类似。

编写一个WEBConfig配置类,并实现自WebMvcConfigurer,重写configureMessageConverters方法:

 @Configuration @Slf4j @EnableWebMvc public class WebConfig implements WebMvcConfigurer {           @Override     public void configureMessageConverters(List<HttpMessageConverter<?>> list) {         MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();         ObjectMapper objectMapper = jsonConverter.getObjectMapper();         //序列换成json时,将所有的long变成string         SimpleModule simpleModule = new SimpleModule();         simpleModule.addSerializer(Long.class, ToStringSerializer.instance);         simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);         objectMapper.registerModule(simpleModule);         list.add(jsonConverter);     } }

“如何使用后端的Long型参数”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 如何使用后端的Long型参数

本文链接: https://lsjlt.com/news/282548.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何使用后端的Long型参数
    本篇内容介绍了“如何使用后端的Long型参数”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、问题描述最近在改造内部管理系统的时候, 发现了...
    99+
    2023-06-16
  • vue前端如何向后端传递参数
    目录前端向后端传递参数get方法传参post方法传参vue前后端传参问题前端向后端传递参数 get方法传参 get方法传参,我们只需要把要传递的参数拼接到要发送的路径地址后面。 实例...
    99+
    2024-04-02
  • long数据类型如何在Java项目中使用
    这篇文章将为大家详细讲解有关long数据类型如何在Java项目中使用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。在Java编程中经常遇到一些整数类型的使用问题,下面我们来看看长整形数据使用...
    99+
    2023-05-31
    java long ava
  • Required Long parameter ‘xx‘ is not present,请求的Long类型参数不存在
    目录 第一次测试第二次测试第三次测试第四次测试第五次尝试第六 直接看这里,没有废话本次涉及到的两个注解@RequestParam和@RequestBody 关于前后端交互中传参的问题 起因...
    99+
    2023-08-31
    java json spring
  • PHP 函数参数的类型注解如何使用?
    php函数参数类型注解可用于指定函数参数的预期数据类型。好处包括:1.提高代码可读性;2.增强可维护性;3.提升安全性。 PHP 函数参数类型注解 类型注解是一种在 PHP 函数参数中...
    99+
    2024-04-10
    php 类型注解 代码可读性
  • 前端传递对象参数,以及后端接受参数 @PathVariable @RequestParam @RequestBody 注解的使用
    太久没写前后端传递参数了,总是格式对不上号 前端传递对象参数,以及后端接受参数 一、接收参数注解 @PathVariable二、接收参数注解 @RequestParam2.1 get 请...
    99+
    2023-09-07
    java javascript
  • 使用String类型小数值转换为Long类型
    目录String类型小数值转为Long类型解决方案如下String类型转int,转long转int转longString类型小数值转为Long类型 数值分为小数和整数,当传入的类型为...
    99+
    2024-04-02
  • java中有界类型参数如何使用
    java中有界类型参数如何使用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。java有界类型参数的使用为了声明一个有界类型参数,列出类型参数的名称,然后是extends关键...
    99+
    2023-06-20
  • java中如何使用有界类型参数
    这篇文章给大家介绍java中如何使用有界类型参数,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1、为了声明一个有界类型参数,列出类型参数的名称,然后是extends关键字,最后是它的上界。public cla...
    99+
    2023-06-20
  • 如何使用反射提取类型参数
    问题内容 上下文:我正在编写一个通用自动映射器,它采用两种类型的结构,检查所述结构的每个字段是否有给定的标签,然后将值从源结构复制到目标结构,假设它们具有匹配的标签和类型。每当结构字段...
    99+
    2024-02-12
    overflow
  • 如何使用AJAX获取Django后端数据
    这篇文章主要介绍“如何使用AJAX获取Django后端数据”,在日常操作中,相信很多人在如何使用AJAX获取Django后端数据问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”...
    99+
    2024-04-02
  • java关于后端怎么去接收Date、LocalDateTime类型的参数
    1、接收date类型的参数 Date类型后端入参的格式默认为2019/01/18 11:11:11 1.1、Get方式传参 Get方式传参 是 没有时区的影响的 @JsonFormat的作用: 返回给前端的时间是经过@JsonFormat格...
    99+
    2023-08-17
    java
  • Argument list too long参数列表过长如何解决
    今天小编给大家分享一下Argument list too long参数列表过长如何解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章...
    99+
    2023-07-05
  • 如何使用泛型 Go 实例化类型参数的非零指针?
    php小编西瓜将为您介绍如何在Go语言中使用泛型实例化类型参数的非零指针。在Go语言中,泛型是一种强大的特性,可以增加代码的灵活性和重用性。当我们需要在泛型函数或方法中实例化一个非零指...
    99+
    2024-02-11
    go语言 排列
  • 如何使用 PHP 函数的参数?
    函数参数允许向函数传递数据,有两种传递方式:按值传递:原始变量不受函数修改影响。按引用传递(以 &amp;amp; 符号开头):函数修改会影响原始变量。实战案例:表单验证中,按值...
    99+
    2024-04-15
    参数 php
  • MySQL参数如何使用
    这篇文章将为大家详细讲解有关MySQL参数如何使用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。  MySQL参数怎么使用  createtable的时候,...
    99+
    2024-04-02
  • 如何使用ADO.NET参数
    这篇文章将为大家详细讲解有关如何使用ADO.NET参数,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。在数据驱动的应用程序中,存储过程具有许多优势。通过利用存储过程,数据库操作可以封装在单个命令中,为获取*...
    99+
    2023-06-17
  • ThreadPoolExecutor参数如何使用
    本篇内容主要讲解“ThreadPoolExecutor参数如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ThreadPoolExecutor参数如何使用”吧!ThreadPoolExec...
    99+
    2023-07-05
  • 使用springmvc参数接收boolean类型参数的问题
    目录springmvc参数接收boolean类型参数如何接收以is开头的boolean类型的参数开发环境问题小结一下springmvc参数接收boolean类型参数 在开发项目过程中...
    99+
    2024-04-02
  • 如何使用 C++ 函数模板实现参数化类型?
    使用 c++++ 函数模板实现参数化类型简介函数模板可以处理不同类型的通用函数。参数化类型使函数模板更进一步,可以接受不同类型的参数。代码示例: 1. 定义函数模板 print_pai...
    99+
    2024-04-15
    函数模板 参数化类型 c++
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作