当前位置:首页 > 物理机 > 正文

jsp购物车代码findbugs规则报错如何修复,是什么原因

改造后: ```jsp <c:forEach var="item" items="${cart.items}"> <c:set var="itemTotal" value="${item.price item.quantity}" /> <c:set var="total" value="${total + itemTotal}" /> </c:forEach> <p>总价:<fmt:formatNumber value="${total}" type="currency" /></p>

这个改造还有一个额外收益:购物车页面里不再有<%%>脚本,找前端同事改样式时不用再战战兢兢怕碰坏Java代码。

通过注解抑制特定规则

如果购物车页面里确实有无法避免的脚本片段,但你能确认是安全的,可以用edu.umd.cs.findbugs.annotations.SuppressFBWarnings注解抑制。

<%@ page import="edu.umd.cs.findbugs.annotations.SuppressFBWarnings" %> <% @SuppressFBWarnings("NP_NULL_ON_SOME_PATH") Cart cart = (Cart) session.getAttribute("cart"); cart.addItem(productId); %>

这里注意,@SuppressFBWarnings要写在变量或方法声明上,不能单独放在语句前,写在一行里能过编译,但FindBugs识别不到。

用FindBugs的优先级过滤

jsp购物车代码findbugs规则报错如何修复,是什么原因 第1张

如果购物车项目很老,短期不想动代码,可以在findbugs-exclude.xml里按priority过滤:

<Match> <Priority value="2" /> <Class name=".jsp" /> </Match>

这样只过滤掉JSP类的中等优先级告警,淘宝、支付宝的开源项目中这类场景也用了同样的做法,高优先级的问题比如SQL载入、硬编码密码,依然保留在报告里供人工核对。

购物车代码改造前后对比

以一个典型的纯JSP购物车结算页面为例,改造前FindBugs报告通常包含十几条到几十条不等的告警,改造后能压到个位数甚至清零。

jsp购物车代码findbugs规则报错如何修复,是什么原因 第2张

告警类型 纯JSP脚本片段 JSTL+EL重构
SQL载入 高概率触发 不触发(SQL移到DAO层)
空指针 多处触发 极少触发
浮点精度 计算总价时触发 不触发(用BigDecimal)

默认编码

写导出文件时触发 不触发(指定UTF-8)
数组暴露 返回商品数组时触发 不触发(封装成List)

这套改造思路在Java社区很成熟,业内专家指出,JSP页面的职责就是展示数据,把业务逻辑剥出去不仅为了过FindBugs,更是为了让代码可维护

jsp购物车代码findbugs规则报错如何修复,是什么原因 第3张

常见问题解答

FindBugs扫描JSP文件报错,需要全部修复吗?

不需要,先看告警的类别,凡是JSP脚本片段转型、session作用域判断、隐式对象相关的告警,大多数是误报,优先处理SQL载入、硬编码密钥、反射调用这类确实有安全风险的告警,其他告警按照上面的findbugs-exclude.xml过滤规则处理即可。

用findbugs扫描jsp文件报错,和项目用的Spring版本有关系吗?

没有直接关系,FindBugs只认字节码,不认框架,但Spring MVC项目里JSP页面通常已经用了<c:forEach>和EL表达式了,所以Spring项目的JSP告警普遍比裸Servlet的项目少,如果你的Spring项目里还在JSP里写<% %>

,那告警数量跟框架无关,纯粹是代码风格问题。

购物车页面的FindBugs告警,跟PMD有什么不同?

FindBugs和PMD的检测层次不同,FindBugs分析编译后的字节码,PMD分析源代码,PMD能读JSP源码(通过JspParser),FindBugs只能扫编译后的Servlet类,所以JSP代码的告警,PMD往往比FindBugs更精准一些——PMD能看到JSP标签结构,FindBugs只能看到一堆方法里的局部变量操作,项目里可以两个工具都配上,JSP相关的规则以PMD结果为准。

回到JSP购物车代码扫描报错这个问题本身,根子在于工具选型和代码风格不匹配,FindBugs天生为检测Java字节码设计,对JSP这种混合型文件有心无力,把业务逻辑从JSP里剥离出去,用JSTL做展示层,再从构建配置里排除遗留的JSP编译类,两招下去扫描报告基本就干净了,如果团队里还在纠结具体某个规则要不要过滤,建议先跑一次不带过滤的完整扫描,把JSP相关的告警单独导出一份,跟纯Java代码的告警分开评估,这样既不放过真问题,也不用在误报上浪费时间。

0