面对“古老”的项目,延续其生命并发挥最大价值,是件很苦逼的事儿。如何在JS中使用JSP标签?如何使ES6模板字符串 含有 JSP标签、EL表达式、JS变量 正常识别?如何解决JSP的EL表达式和 ES6模板字符串 语法冲突?本文将遇到的几处难点做梳理、并结合实际案例深入剖析。
目录
运行环境:
- Windows-7-Ultimate-x64、Windows-10-BusinessEditions-21h2-x64、CentOS-7.9.2009-x64
- OracleJDK-1.8_u201
- IntelliJ IDEA Community Edition 2022.2.2
- Maven-3.6.3
1、简述
本案例为Java项目,基础架构Spring MVC,使用到的技术点有:JSP EL表达式、ES6模板字符串、JSP标签等。
1.1、JSP EL表达式
EL(Expression Language)在JSP中访问模型对象是通过EL表达式的语法来表达。
变量:${
变量名 }
运算:${
not empty 变量名 ? 变量名 : "默认值" }
1.2、JavaScript ES6模板字符串
传统的 JavaScript 语言,输出模板通常是 字符串 与 变量 拼接而成,可能涉及到转义,写法相当繁琐不便,而使用 ES6 模板字符串 (反单引号 ` )完美解决这个问题。如下:
let unitPrice = 1.68;
// 传统写法
alert('<div>单价:<em>' + unitPrice + '</em> 元</div>');
// 模板字符串,换行、空格、缩进均会保留
alert(`<div>单价:<em>${unitPrice}</em> 元</div>`);
2、案例剖析
如何在JavaScript中使用JSP标签,以下将进行详细剖析。
2.1、JavaScript脚本命名
通常,JavaScript脚本文件命名为 XXX.js,而要使 JSP引擎 也能解析JS中的JSP代码,首先需将文件后缀名改为 XXX.jsp。
本案例 客制化JS脚本 为跟 标准的 JSP文件 区分,特命名为 XXX.js.jsp,如: 含有JSP标签的JS脚本.js.jsp。
2.2、配置文件后缀名映射
为使JSP引擎正常解释JS脚本的JSP标签,需要在项目根目录的 《xxx-gateway/src/main/webapp/WEB-INF/web.xml》中配置servlet-mapping,对包含JSP代码的 JS脚本文件做映射(注:允许使用通配符进行模糊匹配)。如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
version="3.1" >
<display-name>Admin Web</display-name>
<!-- WebAppRootKey -->
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>admin-gateway</param-value>
</context-param>
<context-param>
<param-name>isLog4jAutoInitializationDisabled</param-name>
<param-value>true</param-value>
</context-param>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<!-- JavaScript文件中使用的 JSP标签 由服务端来解释 -->
<url-pattern>/static/js/含有JSP标签的JS脚本.js.jsp</url-pattern>
</servlet-mapping>
<!-- Error page -->
<!--
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/WEB-INF/views/error/500.jsp</location>
</error-page>
-->
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/views/error/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/views/error/404.jsp</location>
</error-page>
</web-app>
2.3、JS脚本中使用JSP标签
主要包含以下技术点:
- JSP渲染前,需要先进行字符集声明,避免出现中文乱码;
- JS脚本中,导入JSP自定义标签库;
- JS脚本中 ES6模板字符串 含有 JSP标签、EL表达式、JS变量 混合嵌套时,将JS变量作为参数传入 JSP标签 内部调用,需要用 ${ '${ JS变量名}'} 格式;
《含有JSP标签的JS脚本.js.jsp》脚本文件内容如下:
<%-- 指定页面字符集:解决 JavaScript 文件中使用 ES6模板字符串 渲染页面时乱码 --%>
<%@ page contentType="text/javascript;charset=UTF-8" %>
<%-- 导入JSP自定义标签库:解决 JavaScript 文件中使用 ES6模板字符串 无法解析JSP标签 --%>
<%@ include file="/WEB-INF/views/include/taglib.jsp" %>
// TODO 此处省略1万字
// ES6模板字符串 含有 JSP标签、EL表达式、JS变量
let userNo = '123456';
console.log(`<sys:user id="${'${userNo}'}">`);
// TODO 此处省略1万字
注意:
1、在 JSP文件中使用 ${} 会被优先当作 EL表达式,而不是 JS ES6模板字符串;
2、JSP标签中如果含 HTML字符串值拼接,需要使用 单引号 ' 替代,否则 ES6模板字符串 解析后,会报字符串拼接异常;
2.4、JSP中引入自定义JS脚本
用户访问的JSP页面文件内容,如下:
<html>
<head>
<title>JS脚本中插入JSP标签Demo</title>
<script src="/static/js/含有JSP标签的JS脚本.js.jsp"></script>
<script type="text/javascript">
// TODO
</script>
</head>
<body>
正文
</body>
</html>
3、实践总结
本案例中遇到的技术点,最终是由逆向倒推法一步步的处理,费了不少工夫。如下:
- JSP引擎解析 JS脚本
- 解析后的 JS 脚本乱码
- 如何让 JS 正常识别 JSP标签
- ES6 模板字符串 插入 JS变量
- JSP EL表达式 和 JS ES6模板字符串 语法冲突解决
附录:
- JSP EL表达式 和 ES6模板字符串 语法冲突解决
- 在 JavaScript 中使用 JSP 代码
- 模板字符串 - ECMAScript 6 - 百度百科
- 变量 - EL表达式 - 百度百科
- JSTL - 百度百科
希望能帮助到码友们,如遇到其他问题,欢迎留言、讨论……