EL表达式详解

EL表达式详解一、EL表达式简介EL全名为ExpressionLanguage。EL主要作用:1、获取数据EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域中检索java对象、获取数

大家好,又见面了,我是你们的朋友全栈君。

一、EL表达式简介

EL 全名为Expression Language。EL主要作用:

1、获取数据

EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象、获取数据。(某个web域 中的对象,访问javabean的属性、访问list集合、访问map集合、访问数组)

2、执行运算

利用EL表达式可以在JSP页面中执行一些基本的关系运算、逻辑运算和算术运算,以在JSP页面中完成一些简单的逻辑运算。${user==null}

3、获取web开发常用对象

EL 表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松获得对web常用对象的引用,从而获得这些对象中的数据。

4、调用Java方法

EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法。

 

二、EL表达式的功能

1、获取数据

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  5 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  6 <html>  7 <head>  8 <title>el表达式获取数据</title>  9 </head> 10 11 <body> 12 13 <br/>----------------获取域中存的数据-------------------------<br/> 14 <% 15 String data = "abcd"; 16  request.setAttribute("data",data); 17 %> 18 ${data }  <%--pageContext.findAttribute("data") ""--%> 19 20 21 <br/>----------------获取域中存的javabean的数据-------------------------<br/> 22 <% 23  Person p = new Person(); 24  p.setName("aaaa"); 25 26  request.setAttribute("person",p); 27 %> 28  ${person.name } 29 30 31 <br/>----------------获取域中存的javabean中的javabean的数据-------------------------<br/> 32 <% 33  Person p1 = new Person(); 34  Address a = new Address(); 35  a.setCity("上海"); 36  p1.setAddress(a); 37  request.setAttribute("p1",p1); 38 %> 39  ${p1.address.city } 40 41 42 <br/>----------------获取域中存的list集合中的数据-------------------------<br/> 43 44 <% 45  List list = new ArrayList(); 46  list.add(new Person("aaa")); 47  list.add(new Person("bbb")); 48  request.setAttribute("list",list); 49 %> 50 ${list['1'].name } 51 52 53 <br/>----------------获取域中map集合中的数据-------------------------<br/> 54 <% 55  Map map = new HashMap(); 56  map.put("aa",new Person("aaaaa")); 57  map.put("bb",new Person("bbbbb")); 58  map.put("cc",new Person("ccccc")); 59  map.put("dd",new Person("ddddd")); 60  map.put("111",new Person("eeeee")); 61  request.setAttribute("map111",map); 62 %> 63 ${map111.cc.name } 64 65 66 67 <br/>----------------其它几个常用的el表达式-------------------------<br/> 68 ${pageContext.request.contextPath } 69 <a href="${pageContext.request.contextPath }/index.jsp">点点</a> 70 71 72 </body> 73 </html>

EL表达式语句在执行时,会调用pageContext.findAttribute方法,用标识符为关键字,分别从page、request、session、application四个域中查找相应的对象,找到则返回相应对象,找不到则返回”” (注意,不是null,而是空字符串)。

2、执行运算

语法:${运算表达式}EL表达式支持如下运算符:

<span role="heading" aria-level="2">EL表达式详解

<span role="heading" aria-level="2">EL表达式详解

empty运算符:检查对象是否为null或“空”

二元表达式:${user!=null?user.name : “”}

[ ] 和 . 号运算符

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  2  3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  4 <html>  5 <head>  6 <title>运算符示例</title>  7 </head>  8  9 <body> 10 11 <% 12  request.setAttribute("username","aaa"); 13  request.setAttribute("password","124"); 14 %> 15 16  ${username=='aaa' && password=='123' } 17 18 <br/>----------------empty运算符-------------------------<br/> 19 20 <% 21 //request.setAttribute("list",null); 22  request.setAttribute("list",new ArrayList()); 23 %> 24 ${empty(list) } 25 26 <br/>----------------二元运算符-------------------------<br/> 27 ${user!=null ? user.username : '' } 28  29 30 <br/>----------------二元运算符(数据回显)-------------------------<br/> 31 32 <% 33  request.setAttribute("gender","male"); 34 %> 35 36 <input type="radio" name="gender" value="male" ${gender=='male'?'checked':'' }>男 37 <input type="radio" name="gender" vlaue="female" ${gender=='female'?'checked':'' }>女 49 </body> 50 </html>

 3、获取web开发常用对象

EL表达式语言中定义了11个隐含对象,使用这些隐含对象可以很方便地获取web开发中的一些常见对象,并读取这些对象的数据。

语法:${隐式对象名称}  :获得对象的引用。

<span role="heading" aria-level="2">EL表达式详解

<span role="heading" aria-level="2">EL表达式详解

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  2  3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  4 <html>  5 <head>  6 <title>隐式对象</title>  7 </head>  8  9 <body> 10 11  ${pageContext} 12 15 <br/>----------------使用el隐式对象访问指定的域-------------------------<br/> 16 <% 17  pageContext.setAttribute("aa","123"); 18 %> 19  ${aa } 20  ${pageScope.aa } <!--在域里面参数都是保存在一个map集合中--> 21 22  ${sessionScope.user!=null } 23 24 25 26 <br/>----------------获取保存了所有请求参数的Map对象-------------------------<br/> 27 ${param.name } 28 29 ${paramValues.name[0] }<!--参数同名--> 30 ${paramValues.name[1] } 31 32 33 34 <br/>----------------获取请求头-------------------------<br/> 35  ${header['Accept-Language'] }<span role="heading" aria-level="2">EL表达式详解

 

36 37 <br/>---------------获取cookie-------------------------<br/> 38 ${cookie.JSESSIONID.name }<br/> 39  ${cookie.JSESSIONID.value } 40 41 42  ${initParam.xx } 43 </body> 44 </html>

 重要应用:

可以从指定的域中直接取数据,提高查找效率

param隐含对象用于数据回显,之前的做法是把表单提交的数据封装到javabean,在服务端进行校验,如果校验失败就把bean存到request域中,再从页面中从request取出来回显 

 

三、使用EL调用java方法

EL表达式语法允许开发人员开发自定义函数,以调用Java类的方法。

示例:${prefix:method(params)}

在EL表达式中调用的只能是Java类的静态方法

这个Java类的静态方法需要在TLD文件中描述,才可以被EL表达式调用。

EL自定义函数用于扩展EL表达式的功能,可以让EL表达式完成普通Java程序代码所能完成的功能

1、EL Function开发步骤

一般来说, EL自定义函数开发与应用包括以下三个步骤:

编写一个Java类的静态方法

编写标签库描述符(tld)文件,在tld文件中描述自定义函数。

在JSP页面中导入和使用自定义函数

 

实例:开发对html标签进行转义的EL函数

java类的静态方法:

 1 public class MyEL {  2 //进行html标签转义  3 public static String filter(String message) {  4  5 if (message == null)  6 return (null);  7  8 char content[] = new char[message.length()];  9 message.getChars(0, message.length(), content, 0); 10 StringBuffer result = new StringBuffer(content.length + 50); 11 for (int i = 0; i < content.length; i++) { 12 switch (content[i]) { 13 case '<': 14 result.append("&lt;"); 15 break; 16 case '>': 17 result.append("&gt;"); 18 break; 19 case '&': 20 result.append("&amp;"); 21 break; 22 case '"': 23 result.append("&quot;"); 24 break; 25 default: 26  result.append(content[i]); 27  } 28  } 29 return (result.toString()); 30 31  } 32 33 //进行两个字符串连接 34 public static String add(String s1,String s2){ 35 return s1 + s2; 36  } 37 }

 

标签库描述文件:

 1 <?xml version="1.0" encoding="UTF-8" ?>  2 <!--  3  Licensed to the Apache Software Foundation (ASF) under one or more  4  contributor license agreements. See the NOTICE file distributed with  5  this work for additional information regarding copyright ownership.  6  The ASF licenses this file to You under the Apache License, Version 2.0  7  (the "License"); you may not use this file except in compliance with  8  the License. You may obtain a copy of the License at  9 10  http://www.apache.org/licenses/LICENSE-2.0 11 12  Unless required by applicable law or agreed to in writing, software 13  distributed under the License is distributed on an "AS IS" BASIS, 14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15  See the License for the specific language governing permissions and 16  limitations under the License. 17 --> 18 19 <taglib xmlns="http://java.sun.com/xml/ns/j2ee" 20  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 21  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" 22  version="2.0"> 23 <description>A tag library exercising SimpleTag handlers.</description> 24 <tlib-version>1.0</tlib-version> 25 <short-name>SimpleTagLibrary</short-name> 26 <uri>/my</uri> 27 28 <function> 29 <name>filter</name> 30 <function-class>cn.itcast.demo.MyEL</function-class> 31 <function-signature>java.lang.String filter( java.lang.String )</function-signature> 32 </function> 33 34 <function> 35 <name>add</name> 36 <function-class>cn.itcast.demo.MyEL</function-class> 37 <function-signature>java.lang.String add( java.lang.String,java.lang.String )</function-signature> 38 </function> 39 </taglib>

 

 使用EL函数:

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  2 <%@taglib uri="/my" prefix="my" %>  3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  4 <html>  5 <head>  6 <title>My JSP '4.jsp' starting page</title>  7 </head>  8  9 <body> 10  ${my:filter("<a href=''>点点</a>") } 11 </body> 12 </html>

 

 

2、开发EL函数注意事项

  • 编写完标签库描述文件后,需要将它放置到<web应用>\WEB-INF目录中或WEB-INF目录下的除了classes和lib目录之外的任意子目录中。

  • TLD文件中的<uri> 元素用指定该TLD文件的URI,在JSP文件中需要通过这个URI来引入该标签库描述文件。

  • <function>元素用于描述一个EL自定义函数,其中:

    <name>子元素用于指定EL自定义函数的名称。

    <function-class>子元素用于指定完整的Java类名

    <function-signature>子元素用于指定Java类中的静态方法的签名,方法签名必须指明方法的返回值类型及各个参数的类型,各个参数之间用逗号分隔。

  • EL表达式保留关键字

<span role="heading" aria-level="2">EL表达式详解

所谓保留字的意思是指变量在命名时,应该避开上述的名字,以免程序编译时发生错误。

 

 

 

四、sun公司的el函数库

1、el函数库所有标签描述

 1 <?xml version="1.0" encoding="UTF-8" ?>  2  3 <taglib xmlns="http://java.sun.com/xml/ns/j2ee"  4  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  5  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"  6  version="2.0">  7  8 <description>JSTL 1.1 functions library</description>  9 <display-name>JSTL functions</display-name>  10 <tlib-version>1.1</tlib-version>  11 <short-name>fn</short-name>  12 <uri>http://java.sun.com/jsp/jstl/functions</uri>  13  14 <function>  15 <description>  16  Tests if an input string contains the specified substring.  17 </description>  18 <name>contains</name>  19 <function-class>org.apache.taglibs.standard.functions.Functions</function-class>  20 <function-signature>boolean contains(java.lang.String, java.lang.String)</function-signature>  21 <example>  22 &lt;c:if test="${fn:contains(name, searchString)}">  23 </example>  24 </function>  25  26 <function>  27 <description>  28  Tests if an input string contains the specified substring in a case insensitive way.  29 </description>  30 <name>containsIgnoreCase</name>  31 <function-class>org.apache.taglibs.standard.functions.Functions</function-class>  32 <function-signature>boolean containsIgnoreCase(java.lang.String, java.lang.String)</function-signature>  33 <example>  34 &lt;c:if test="${fn:containsIgnoreCase(name, searchString)}">  35 </example>  36 </function>  37  38 <function>  39 <description>  40  Tests if an input string ends with the specified suffix.  41 </description>  42 <name>endsWith</name>  43 <function-class>org.apache.taglibs.standard.functions.Functions</function-class>  44 <function-signature>boolean endsWith(java.lang.String, java.lang.String)</function-signature>  45 <example>  46 &lt;c:if test="${fn:endsWith(filename, ".txt")}">  47 </example>  48 </function>  49  50 <function>  51 <description>  52  Escapes characters that could be interpreted as XML markup.  53 </description>  54 <name>escapeXml</name>  55 <function-class>org.apache.taglibs.standard.functions.Functions</function-class>  56 <function-signature>java.lang.String escapeXml(java.lang.String)</function-signature>  57 <example>  58  ${fn:escapeXml(param:info)}  59 </example>  60 </function>  61  62 <function>  63 <description>  64  Returns the index withing a string of the first occurrence of a specified substring.  65 </description>  66 <name>indexOf</name>  67 <function-class>org.apache.taglibs.standard.functions.Functions</function-class>  68 <function-signature>int indexOf(java.lang.String, java.lang.String)</function-signature>  69 <example>  70  ${fn:indexOf(name, "-")}  71 </example>  72 </function>  73  74 <function>  75 <description>  76  Joins all elements of an array into a string.  77 </description>  78 <name>join</name>  79 <function-class>org.apache.taglibs.standard.functions.Functions</function-class>  80 <function-signature>java.lang.String join(java.lang.String[], java.lang.String)</function-signature>  81 <example>  82  ${fn:join(array, ";")}  83 </example>  84 </function>  85  86 <function>  87 <description>  88  Returns the number of items in a collection, or the number of characters in a string.  89 </description>  90 <name>length</name>  91 <function-class>org.apache.taglibs.standard.functions.Functions</function-class>  92 <function-signature>int length(java.lang.Object)</function-signature>  93 <example>  94  You have ${fn:length(shoppingCart.products)} in your shopping cart.  95 </example>  96 </function>  97  98 <function>  99 <description> 100  Returns a string resulting from replacing in an input string all occurrences 101  of a "before" string into an "after" substring. 102 </description> 103 <name>replace</name> 104 <function-class>org.apache.taglibs.standard.functions.Functions</function-class> 105 <function-signature>java.lang.String replace(java.lang.String, java.lang.String, java.lang.String)</function-signature> 106 <example> 107 ${fn:replace(text, "-", "&#149;")} 108 </example> 109 </function> 110 111 <function> 112 <description> 113  Splits a string into an array of substrings. 114 </description> 115 <name>split</name> 116 <function-class>org.apache.taglibs.standard.functions.Functions</function-class> 117 <function-signature>java.lang.String[] split(java.lang.String, java.lang.String)</function-signature> 118 <example> 119  ${fn:split(customerNames, ";")} 120 </example> 121 </function> 122 123 <function> 124 <description> 125  Tests if an input string starts with the specified prefix. 126 </description> 127 <name>startsWith</name> 128 <function-class>org.apache.taglibs.standard.functions.Functions</function-class> 129 <function-signature>boolean startsWith(java.lang.String, java.lang.String)</function-signature> 130 <example> 131 &lt;c:if test="${fn:startsWith(product.id, "100-")}"> 132 </example> 133 </function> 134 135 <function> 136 <description> 137  Returns a subset of a string. 138 </description> 139 <name>substring</name> 140 <function-class>org.apache.taglibs.standard.functions.Functions</function-class> 141 <function-signature>java.lang.String substring(java.lang.String, int, int)</function-signature> 142 <example> 143  P.O. Box: ${fn:substring(zip, 6, -1)} 144 </example> 145 </function> 146 147 <function> 148 <description> 149  Returns a subset of a string following a specific substring. 150 </description> 151 <name>substringAfter</name> 152 <function-class>org.apache.taglibs.standard.functions.Functions</function-class> 153 <function-signature>java.lang.String substringAfter(java.lang.String, java.lang.String)</function-signature> 154 <example> 155  P.O. Box: ${fn:substringAfter(zip, "-")} 156 </example> 157 </function> 158 159 <function> 160 <description> 161  Returns a subset of a string before a specific substring. 162 </description> 163 <name>substringBefore</name> 164 <function-class>org.apache.taglibs.standard.functions.Functions</function-class> 165 <function-signature>java.lang.String substringBefore(java.lang.String, java.lang.String)</function-signature> 166 <example> 167  Zip (without P.O. Box): ${fn:substringBefore(zip, "-")} 168 </example> 169 </function> 170 171 <function> 172 <description> 173  Converts all of the characters of a string to lower case. 174 </description> 175 <name>toLowerCase</name> 176 <function-class>org.apache.taglibs.standard.functions.Functions</function-class> 177 <function-signature>java.lang.String toLowerCase(java.lang.String)</function-signature> 178 <example> 179  Product name: ${fn.toLowerCase(product.name)} 180 </example> 181 </function> 182 183 <function> 184 <description> 185  Converts all of the characters of a string to upper case. 186 </description> 187 <name>toUpperCase</name> 188 <function-class>org.apache.taglibs.standard.functions.Functions</function-class> 189 <function-signature>java.lang.String toUpperCase(java.lang.String)</function-signature> 190 <example> 191  Product name: ${fn.UpperCase(product.name)} 192 </example> 193 </function> 194 195 <function> 196 <description> 197  Removes white spaces from both ends of a string. 198 </description> 199 <name>trim</name> 200 <function-class>org.apache.taglibs.standard.functions.Functions</function-class> 201 <function-signature>java.lang.String trim(java.lang.String)</function-signature> 202 <example> 203  Name: ${fn.trim(name)} 204 </example> 205 </function> 206 207 </taglib>

 

 

 

2、el函数库使用

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  2 <%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> 3 <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  4  5  6 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  7 <html>  8 <head>  9 <title>My JSP '5.jsp' starting page</title> 10 </head> 11 12 <body> 13 14  ${fn:toLowerCase("AAAA") } 15 16 <% 17  request.setAttribute("arr",new String[5]); 18 %> 19 20  ${fn:length(arr) } 21 22 23 <% 24  List list = new ArrayList(); 25  list.add("aa"); 26  list.add("bb"); 27  request.setAttribute("list",list); 28 %> 29 <c:forEach var="i" begin="0" end="${fn:length(list)}"> 30 ${list[i] } 31 </c:forEach> 32 33 34  ${fn:join(fn:split("www,itcast,cn",","),".") } 35 36  ${fn:contains("aaaabbbcc","ab") } 37 38 39 ${fn:escapeXml("<a href=''>点点</a>")} 40 41 42  <br/>---------------取出用户填写的爱好回显------------------------<br/> 43 <% 44  request.setAttribute("likes",new String[]{"football","sing"}); 45 %> 46 47 <input type="checkbox" name="likes" value="sing" ${fn:contains(fn:join(likes,","),"sing")?'checked':'' }>唱歌 48 <input type="checkbox" name="likes" value="dance" ${fn:contains(fn:join(likes,","),"dance")?'checked':'' }>跳舞 49 <input type="checkbox" name="likes" value="basketball" ${fn:contains(fn:join(likes,","),"basketball")?'checked':'' }>蓝球 50 <input type="checkbox" name="likes" value="football" ${fn:contains(fn:join(likes,","),"football")?'checked':'' }>足球 51 </body> 52 </html>

 

 

注意:el表达式不支持两个字符串的连接,如:

 1 <body>  2  3 <%  4  User user = new User();  5  user.setUsername("aaaa");  6 //session.setAttribute("user",user);  7 %>  8  9  ${user!=null?"欢迎您"+user.name:""} 10 11 </body>

 

 要想进行两个字符串连接可以开发el函数实现,如:

 

1 //进行两个字符串连接 2 public static String add(String s1,String s2){ 3 return s1 + s2; 4 }

 

 

 

在tld文件描述后再使用

 

 1 <body>  2  3 <%  4  User user = new User();  5  user.setUsername("aaaa");  6 //session.setAttribute("user",user);  7 %>  8  9 ${user!=null?my:add("欢迎您:",user.username):''} 10 11 </body>

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/155095.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 国内十大正规现货交易平台排名(2022最新榜单)「建议收藏」

    国内十大正规现货交易平台排名(2022最新榜单)「建议收藏」如今,越来越多的人投资于黄金,因为这些投资项目更适合当今年轻人的需求,但为了通过黄金投资获得理想的回报,我们首先需要选择一个可靠的国内黄金交易平台,由于市场上的各种平台都很复杂,有些平台可能不是很正规。如果你选择这样的一个平台投资,收获可能会并不理想,但选择好的平台事实上并不像预期的那么困难。香港作为全球的金融中心之一,其金银业贸易场的黄金投资业务已经很成熟,投资者的利益能够得到有效的保障。鉴于很多新手对国内现货黄金平台不太了解,下面小编为大家介绍“国内十大正规现货交易平台排名(2022最新

  • 功能测试用例编写_接口测试用例设计思路

    功能测试用例编写_接口测试用例设计思路编写测试用例HttpRunnerv3.x支持三种测试用例格式pytest,YAML和JSON。官方强烈建议以pytest格式而不是以前的YAML/JSON格式编写和维护测试用例格式关系如下图所示

  • Altium Designer初学教程(一)[通俗易懂]

    Altium Designer初学教程(一)[通俗易懂]安装说明及如何激活并申请添加license安装说明及如何激活并申请添加license我们提供的安装光盘可以在每台电脑上安装AltiumDesigner软件。我们为每个单位或公司产生一个用户号,我们为每台电脑产生一个激活码,用户在软件的license界面里输入用户号和激活码,软件将自动产生本机的一个二进制信息文件,用这个信息文件通过电子邮件到我们的服务器上换取本机的licens…

  • Apifox(2)快速上手apifox

    Apifox(2)快速上手apifox快速上手使用场景Apifox是接口管理、开发、测试全流程集成工具,使用受众为整个研发技术团队,主要使用者为前端开发、后端开发和测试人员。前端开发接口文档管理接口数据Mock接口调试前

  • python decode函数的用法_decode函数的用法

    python decode函数的用法_decode函数的用法DECODE函数是ORACLEPL/SQL是功能强大的函数之一,目前还只有ORACLE公司的SQL提供了此函数,其他数据库厂商的SQL实现还没有此功能。DECODE有什么用途呢?先构造一个例子,假设我们想给智星职员加工资,其标准是:工资在8000元以下的将加20%;工资在8000元以上的加15%,通常的做法是,先选出记录中的工资字段值?selectsalaryintovar-salar…

  • mysql学习之mysql集群

    mysql学习之mysql集群本片博文是笔者学习《高性能mysql》一书的第一篇学习笔记,对应书籍章节为第10章。主要介绍了mysql集群部署方案主从集群部署。集群方案、主从同步原理、复制类型、docker安装mysql集群示例。

    2022年10月23日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号