long型长整数字在前端页面显示异常及其解决方法

本文探讨了解决EL表达式获取长整型数值时出现的尾数丢失问题,通过三次试验最终找到解决方案:在EL表达式两侧添加引号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.引子

       在做项目中,发现了一个诡异的事情,后台的long型数字不能正确地在前端页面显示。经过我的反复排查问题,总算是找到了问题原因所在,希望能帮助到大家,让大家少走弯路。

2.解决问题

(1)初试EL表达式取long型数值

       后台java代码设置属性

        BlogDetail currentBlog = pageModel.getDataArray().get(0);
        //request中设置属性,以供前端页面获取
        request.setAttribute("curBlog", currentBlog);
        int categoryId = currentBlog.getCategoryId();
        //打印博客的long型id
        Long blogId = currentBlog.getId();
        System.out.println("单篇博客id"+blogId);

       前端页面的html及js脚本

	<button type="button" style="margin-left: 100px"
					onclick="deleteBlog(${curBlog.id})"
				class="layui-btn layui-btn-primary layui-btn-sm">
						<i class="layui-icon"></i> 	</button>
<script type="text/javascript">
	function deleteBlog(id) {
	alert(id);
	return;
	/**
	if (!confirm("确定要删除这篇博客吗?")) {
		return;
	}
	$.ajax({
		type: "POST",
		url: "<%=basePath%>blogDetailServlet?action=delete",
		data: { "id": id },
		success: function (result) {
			if (result == 1) {
				alert("当前博客删除成功");

				if ($("#currPage").val() == 1){
					location.href = "<%=basePath%>blogDetailServlet?action=showOne";
				} else {
					location.href = "<%=basePath%>blogDetailServlet?action=showOne&currentPage=${pager.currentPage-1}";
				}
			} else {
				alert("当前博客删除失败");
			}
		}
	}); */
}
</script>

       控制台打印出的博客id
在这里插入图片描述
       前端页面弹出的提示窗口的博客id
在这里插入图片描述
       可以明显看出两者的值不一样,后台实际设置的值是156231237764100358 ,而前端页面获取到的值是156231237764100350,前端将后台传过来的长整型数值的最后一位数视为’0’ 。

(2)再探EL表达式取字符串格式long型数值

       起初我以为是long型数字太长不能在页面中显示,后来我又用字符串型的数字来测试,然而结果仍然很失望。
后台java代码设置字符串格式的长整数字的属性

		BlogDetail currentBlog = pageModel.getDataArray().get(0);
        request.setAttribute("curBlog", currentBlog);
        int categoryId = currentBlog.getCategoryId();
        //打印博客的long型id
        Long blogId = currentBlog.getId();
        System.out.println("单篇博客id"+blogId);
        //在requeset中设置字符串格式的长整数字
        request.setAttribute("blogId",blogId+"" );

        jsp页面代码

<button type="button"	onclick="javascript:alert(${blogId})"	   		    class="layui-btn layui-btn-primary" > 
<i class="layui-icon">长整数测试</i>
	</button>

        新的弹窗
在这里插入图片描述
        从前端页面的提示窗口来看,使用字符串形式的长整数字仍不能正常显示。如果前端一直不能正常显示长整型的数字,这将是一个巨的灾难,毕竟谁也不能保证一直不在前端使用大数字。

(3)最后一试—给EL表达式加引号

        后来看到在超链接中同样使用EL表达式却能跳转到正确的页面。这引起了我的兴趣,我估计是用因为在超链接中用了引号的原因。在超链接的href属性的内容必须用引号包裹起来,而整个超链接使用了双引号,那么href 属性的内容(即链接地址)则只能用单引号了。而以上示例中调用Javascript脚本方法时,其中却只有一个外部的双引号,而无单引号。
在这里插入图片描述
在这里插入图片描述
        准备尝试在EL表达式两侧加上单引号

<!--onclick事件的脚本方法,对EL表达式两侧加上单引号-->
<button type="button"	onclick="javascript:alert('${blogId}')"	   		    class="layui-btn layui-btn-primary" > 
<i class="layui-icon">长整数测试</i>
	</button>

        前端页面显示出正确的long型数字
在这里插入图片描述

3.总结

       EL表达式很好用,但有的时候也得注意一些小细节。在获取比较小的数字或位数较短的数字时,可以不用引号将EL表达式包含起来,但在获取位数较长的long型数字时,要注意一定得使用引号(" "或’ ')将EL表达进包裹起来,防止获得尾数充零的的错误值。

<think>好的,用户问的是接口返回的long数字ID在前端数值改变的问题。首先,我需要确定这个问题的背景。通常前端接收到的是JSON数据,而JavaScript处理大数时可能会有精度丢失的问题,因为JS的Number类是双精度浮点数,只能安全表示到2^53-1。如果后端返回的long超过这个范围,前端解析时就会出错,比如后几位变成0。 接下来,我要考虑用户可能的场景。比如,用户可能遇到了ID值被篡改的情况,或者数据显示不正确。这时候需要解释为什么会发生这种情况。首先,JSON本身没有类定义,数字会被解析为JS的Number,大数就会出问题。然后,可以提出解决方案,比如后端返回字符串,前端用库如json-bigint处理,或者使用字符串类代替数字。 还要考虑用户可能不知道具体的解决方案,需要详细说明每种方法的步骤。例如,修改后端的序列化配置,或者在前端使用特定的JSON解析方法。另外,可能需要提醒用户检查数据库或后端生成的ID是否超过了JS的安全范围,以及如何测试和验证解决方案是否有效。 最后,要确保回答结构清晰,分点说明原因和解决方法,并且使用中文,避免专业术语过多,让用户容易理解。可能还需要举例子,比如展示前后代码对比,或者给出具体的配置示例,帮助用户实际操作。同时,注意用户可能没有提到但相关的问题,比如分布式ID生成策略是否合理,是否需要调ID的度等。</think>关于前端处理long数字ID出现数值变化的问题,这里为您详细说明原因和解决方案: 一、问题现象 当接口返回的long数字ID(如:635241059351494656)到达前端时,可能变成: 635241059351494600(后两位变为00) 或 635241059351494700(精度丢失) 二、根本原因 1. JavaScript数值精度限制 - JavaScript的Number类采用IEEE 754双精度浮点数标准 - 最大安全数:2⁵³ - 1 = 9007199254740991 - 当数值超过这个范围时会出现精度丢失 2. JSON序列化问题 - 后端生成的Long数值超过JS安全范围 - JSON默认将数字解析为Number类 三、解决方案 方案一:后端返回字符串格式 1. 修改DTO定义: ```java // 原写法 private Long id; // 修改为 @JsonFormat(shape = JsonFormat.Shape.STRING) private String id; ``` 2. 使用Jackson全局配置: ```java ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationFeature.WRITE_NUMBERS_AS_STRINGS, true); ``` 方案二:前端特殊处理 1. 使用json-bigint库处理: ```javascript import JSONbig from 'json-bigint'; const response = await fetch('/api/data'); const data = JSONbig.parse(await response.text()); ``` 2. 自定义JSON解析: ```javascript const json = `{"id": 635241059351494656}`; const obj = JSON.parse(json, (key, value) => { return typeof value === 'number' && value > 9007199254740991 ? value.toString() : value; }); ``` 方案三:数据库层优化 1. 使用更短的ID生成策略: - Snowflake算法调时间戳位数 - 改用UUID(32位字符串) - 自Redis生成递增ID 四、验证方法 1. 在浏览器控制台测试: ```javascript console.log(635241059351494656); // 输出:635241059351494600(精度丢失) ``` 2. 使用类检测: ```javascript const testId = 635241059351494656; console.log(typeof testId); // 应返回"string"而不是"number" ``` 五、注意事项 1. 数值比较:字符串类的ID需使用全等比较 ```javascript // 正确比较方式 if (obj.id === '635241059351494656') {...} ``` 2. 序列化一致性:确保个系统(数据库 -> 后端 -> 前端)使用相同处理方式 建议优先采用方案一,既能保持数据精度,又避免前端额外处理逻辑。若系统已大量使用LongID,推荐配合方案二使用json-bigint库处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值