一、jsp基础语法

1、注释

显式注释语法:

<!--注释内容-->客户端可以看见

隐式注释语法:客户端不能看见

<%
//单行注释
/*多行注释*/
%> 2、
Scriptlet(脚本小程序)
  1. <%%>:主要用于定义局部变量、编写语句

  2. <%!%>:主要用于定义全局变量、方法、类,不能出现其他语句 
    尽量不要在JSP中定义类和方法

  3. <%=%>:表达式输出

<%
String info = "www.baidu.com";
%>
<h1>website=<%=info%></h1> 3、
scriptlet标签
<jsp:scriptlet> String url="www.baidu.com"; </jsp:scriptlet> <h2><%=url%></h2> 4、page常用指令

如下:

指令属性

描述

language

声明所使用的脚本语言,目前只有Java一种,所以可以不声明。

extends

指定JSP页面产生的Servlet继承的父类

import

指定所导入的包。(java.lang.*、javax.servlet.*、javax.servlet.jsp.*、和java.servlet.http.*几个包在程序编译时已经被导入,所以不需要特备声明)

session

指定JSP页面是否可以使用Session对象(默认值为session=”true”)。

buffer

指定缓冲区的大小,默认是8KB。如果为none,则表示不设置缓冲区。(此属性要和autoFlush一起使用)

autoFlush

指定输出缓冲区即将溢出时,是否强制输出缓冲区的内容。可以设置为true或false(默认为true)。

isThreadSafe

指定JSP是否支持多线程。可以设置为true或false,若为true,则表示该页面可以处理多个用户的请求;如果为false,则此JSP一次只能处理一个页面的用户请求。

info

设置JSP页面的相关信息。可以使用servlet.getServletInfo()方法获取到JSP页面中的文本信息。

ErrorPage

指定错误处理页面。当JSP出错时,会自动调用该指定所指定的错误处理页面。(此属性要和isErrorPage一起使用)

isErrorPage

指定JSP文件是否进行异常处理。可以设置为true或false,如果设置为true,则errorPage指定的页面出错时才能跳转到此页面进行错误处理。

contentType

指定JSP页面的编码方式和JSP页面响应的MIME类型(默认的MIME类型为text/html,默认的字符集类型为charset=ISO-8859-1)。例如:contentType=“text/html;charset=GBK”

pageEncoding

指定页面的编码方式。默认值为pageEncoding=“iso-8859-1”,若设为中文编码可以是pageEncoding=“GBK”。

isELIgnored

指定JSP文件是否支持EL表达式。

注释:对于以上属性,只有import属性可以多次出现,其他属性均只能出现一次。

contentType设置MIME

MIME表示打开文件的应用程序类型, 
page指令中,contentType可以指定文件的显示方式 
例如:


<%@ page language="java" contentType="text/html;charset=GBK"%>
<%@ page language="java" contentType="application/word;charset=GBK"%>
pageEncoding设置文件编码 charset是指服务器发送给客户端的内容编码,pageEncoding指的是JSP文件本身的编码。如果pageEncoding存在,那么JSP编码由pageEncoding决定,否则由charset决定,如果两个属性都不存在,则默认为ISO-8859-1 

例如:

<%@ page language="java" contengType="text/html;pageEncoding=GBK"%>

一般一个JSP页面只需要按照网页显示(text/html),则使用pageEncoding设置编码即可。

errorPage错误页的设置

错误页设置两步骤: 
1. errorPage属性指定错误出现时的跳转页; 
2. isErrorPage属性指定错误页标识

例如: 
错误页中:

<%@ page language="java" contengType="text/html;pageEncoding=GBK"%>
<%@page errorPage="error.jsp"%><!--一出现错误即跳转到错误处理页-->

错误处理页中:


<%@ page language="java" contengType="text/html;pageEncoding=GBK"%>
<%@ page isErrorPage="true"%><!--表示该页面用于处理错误-->

错误页跳转输入服务器端跳转


可以修改Web.xml文件,实现在虚拟目录指定全局的错误处理


<error-page>
<error-code>500</error-code>
<location>/ch05/error.jsp</location>
</error-page>

依然服务器端跳转

5、数据库操作

 <%@ page contentType="text/html" pageEncoding="GBK"%>
<%@ page import="java.sql.*"%>
<html>
<head><title>www.bruce.com</title></head>
<body>
<%!
//定义数据库驱动程序
public static final String DBDRIVER = "org.gjt.mm.mysql.Driver";
public static final String DBURL = "jdbc:mysql://localhost:3306/mldn";
public static final String DBUSER = "root";
public static final String DBPASS = "mysqladmin";
%>
<%
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
%>
<%
try{
Class.forName(DBDRIVER);
conn = DriverManager.getConnection(DBURL,DBUSER,DBPASS);
String sql = "SELECT empno,ename,job,sal,hiredate FROM emp";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
%>
<center>
<table border="1" width="80%">
<tr>
<td>雇员编号</td>
<td>雇员姓名</td>
<td>雇员工作</td>
<td>雇员工资</td>
<td>雇员日期</td>
</tr>
<%
while(rs.next()){
int empno = rs.getInt(1);
String ename = rs.getString(2);
String job = rs.getString(3);
float sal = rs.getFloat(4);
java.util.Date date = rs.getDate(5);
%>
<tr>
<td><%=empno%></td>
<td><%=ename%></td>
<td><%=job%></td>
<td><%=sal%></td>
<td><%=date%></td>
</tr>
<%
}
%>
</table>
</center>
<%
}catch(Exception e){
e.printStack();
}finally{
rs.close();
pstmt.close();
conn.close();
}
%>
</body>
</html>

6、包含指令

静态包含

语法:<%@ include file = "要包含的文件路径"%>

包含的文件可以是JSP,HTML,文本,或者是一段Java程序。包含操作实际上是将被导入的文件内容导入,一起进行编译,最后再将一份整体的内容展现给用户 
例如:

<body>

<%@include file="info.html"%>

</body>
动态包含

语法: 
1. 不传递参数: 
<jsp:include page="{要包含的文件路径\<%=表达式%>}" flush="true\false"/>

  1. 传递参数:
<jsp:include page="{要包含的文件路径\<%=表达式%>}" flush="true\false">
<jsp:param name="参数名" value="参数内容"/>
//可以传递多个参数
</jsp:include>

例如: 
包含页:include_demo.jsp

<jsp:include page="receive_param.jsp">
<jsp:param name="name" value="<%=username>">
<jsp:param name="info" value="Bruce">
</jsp:include>

被包含页:receive_param.jsp

<%@ page contentType="text/html" pageEncoding="GBK"%>
<h1>参数1:<%=request.getParameter("name")%></h1>
<h1>参数2:<%=request.getParameter("info")%></h1>

false表示完全被读进来再输出,true表示buffer满了就输出,一般都设置为true,默认为true 
动态包含是先处理再输出

7、跳转指令

语法: 
1. 不传递参数: 
<jsp:forward page="{要包含的文件路径\<%=表达式%>}"/> 
2. 传递参数:


<jsp:forward page="{要包含的文件路径\<%=表达式%>}">
<jsp:param name="" value=""/>
//可以传递多个参数
</jsp:forward>

上述跳转属于服务器端跳转

8、jsp九大内置对象

内置对象 类型 描述
pageContext javax.servlet.jsp.PageContext 页面容器
request javax.servlet.HttpServletRequest 请求
response javax.servlet.HttpServletResponse 回应
session javax.servlet.HttpSession 保存
application javax.servlet.ServletContext 共享信息
config javax.servlet.ServletConfig 服务器配置,可以取得初始化参数
out javax.servlet.jspWriter 页面输出
page java.lang.Object  
exception java.lang.Throwable

四种属性

属性名 属性范围
page 只在一个页面中保存属性
request 一次请求中保存属性,服务器跳转后仍有效
session 一次会话范围中保存,任何跳转都有效,重新打开浏览器无效
application 整个服务器保存,所有用户都可以使用

4个内置对象都支持以下操作方法:

public void setAttribute(String name,Object o)
public Object getAttribute(String name)
public void removeAttribute(String name)

request对象

request对象主要作用是接收客户端发送来的请求,是javax.servlet.http.HttpServletRequest接口的实例化对象

常用方法 描述
public String getParameter(String name) 接收请求参数
public String[] getParameterValues(String name) 接收一组请求参数
public Enumeration getParameterNames() 取得请求参数名
public String getRemoteAddr() 取得客户端IP地址
void setCharacterEncoding(String env)throws UnsupportedEncodingException 设置统一的请求编码
public boolean isUserInRole(String role) 用户身份认证
public Httpsession getSession() 取得当前的session对象
pubic StringBuffer getRequestURL() 返回正在请求的路径
pubic Enumeration getHeaderNames() 取得全部头信息的名称
pubic Enumeration getHeader(String name) 根据名称取得头信息的内容
public String getMethod() 取得用户的提交方式(get/post)
public String getServletPath() 取得访问的路径
public String getContextPath() 取得上下文资源路径
 

解决乱码

例如:

<body>
<%
request.setCharacterEncoding("GBK");
%>
</body> 例如:接收表单全部内容 
定义表单页:request_form.html
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>request_form.html</title>
</head> <body>
<form action="request_demo.jsp" method="post"><!-- 用post,否则乱码 -->>
姓名:<input type="text" name="uname"><br /> 兴趣:<input
type="checkbox" name="**inst" value="唱歌">唱歌<input
type="checkbox" name="**inst" value="跳舞">跳舞<input
type="checkbox" name="**inst" value="游泳">游泳<br /> 自我介绍:
<textarea cols="30" rows="3" name="note"></textarea>
<input type="hidden" name="uid" value="1"> <input
type="submit" value="提交"> <input type="reset" value="重置">
<br />
</form>
</body>
</html>

定义读取页:request_demo.jsp

 <%@ page language="java" import="java.util.*" pageEncoding="GBK"%>

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'request_demo.jsp' starting page</title>
</head> <body>
<%
request.setCharacterEncoding("GBK");//不能少,否则容易乱码
%>
<table border="1">
<tr>
<th>参数名称</th>
<th>参数内容</th>
</tr>
<%
Enumeration enu = request.getParameterNames();
while (enu.hasMoreElements()) {
String paramName = (String) enu.nextElement();
%>
<tr>
<td><%=paramName%></td>
<td>
<%
if (paramName.startsWith("**")) {
String paramValue[] = request
.getParameterValues(paramName);
for (int i = 0; i < paramValue.length; i++) {
%> <%=paramValue[i]%>、
<%
}
} else {
String paramValue = request.getParameter(paramName);
%>
<%=paramValue%>
<%
}
%>
</td>
</tr>
<%
}
%> </table>
</body>
</html>

显示全部头信息

<%@ page contextType="text/html" pageEncoding="GBK"%>
<%@ page import="java.util.*"%>
<html>
<head><title>取得头信息的名称和内容</title></head>
<body>
<%
Enumeration enu = request.getHeaderNames();
while(enu.hasMoreElements()){
String headerName = (String)enu.nextElement();
String headerValue = request.getHeader(headerName);
%>
<h5><%=headerName%>--><%=headerValue%></h5>
<%
}
%>
</body>
</html>

角色验证

增加新用户需要修改conf/tomcat-user.xml文件。

<user username="10202357" password="Tu86511620" roles="admin" />

配置完之后还需要配置web.xml文件,在web.xml文件中加入对某一资源的验证操作

角色验证即在JSP页面中调用request.isUserInRole(“”)

response对象

response对象的主要作用是对客户端请求的响应,是javax.servlet.http.HttpServletResponse接口的实例

常用方法 描述
public void addCookie(Cookie cookie) 给客户端增加Cookie
public void setHeader(String name,String value) 设置回应的头信息
public void sendRedirect(String location)throws IOException 页面跳转

设置头信息

例如: 
设置自动刷新:

<% reponse.setHeader("refresh","2") %>

定时跳转:

<% reponse.setHeader("refresh","2";URL="hello.html") %>

定时跳转(JSP response\HTML方式)都属于客户端跳转

例子
<html>
<head>
<title>测试html页面的跳转</title>
<META HTTP-EQUIV="refresh" CONTENT="3;URL=hello.html">
</head>
<body>
<h3>
3秒后跳转到hello.html页面,如果没有跳转请按<a href="hello.html">这里</a>!
</h3>
</body>
</html>

当一个页面中没有JSP代码又想执行定时跳转的时候才使用HTML形式的设置跳转头信息

页面跳转

<% response.sendRedirect("01.html"); %>

<jsp:forward>不同,response属于客户端跳转,要在整个页面执行完以后才执行跳转。 
<jsp:forward>可以方便地进行参数传递,而且服务器端跳转要比客户端跳转更常用

操作cookie

Cookie的常用方法 描述
public Cookie(String name,String value)  
public String getName()  
public String getValue()  
public void setMaxAge(int expiry) 设置Cookie的保存时间,以秒为单位

Cookie是服务器给客户端增加的,所以使用reponse对象

例子

<%

Cookie c1 = new Cookie("Tu","Bruce");//第一个参数是属性名,第二个参数是属性值

c1.setMaxAge(60);//Cookie保存60秒

    response.addCoolie(c1);//向客户端增加Cookie

%>

例如:取出Cookie
<%
Cookie c[] = request.getCookies();
for(int x = 0; x < c.length; x++){
%>
<h3><%=c[x].getName()%>--><%=c[x].getValue()%></h3>
<%
}
%>

session对象

在开发中session对象最主要的用处是完成用户的登录、注销等常见功能。

常用方法 描述
public String getId() 取得Session Id
public long getCreationTime() 取得Session的创建时间
public long getLastAccessedTime() 取得Session的最后一次操作时间
public boolean isNew() 判断是否是新的Session
public void invalidate() 让Session失效
public Enumeration getAttributeNames() 得到全部属性的名称

登录与注销

实例: 
编写表单并进行验证login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<html>
<head>
<title>登录注销</title>
</head> <body>
<form action="login.jsp">
用户名:<input type="text" name="uname" /></br> 密&nbsp;&nbsp;码:<input
type="password" name="upass"> <input type="submit" value="登录">
<input type="reset" value="重置">
</form>
<%
String name = request.getParameter("uname");
String password = request.getParameter("upass");
if (!(name == null || "".equals(name) || password == null || ""
.equals(password))) {
if ("Bruce".equals(name) && "2222".equals(password)) {
response.setHeader("refresh", "2,URL=welcome.jsp");
session.setAttribute("userid", name);
%>
<h3>用户登录成功,两秒后跳转到欢迎页!</h3>
<h3>
如果没有跳转,请点击<a href="welcome.jsp">这里</a>
</h3>
<%
} else {
%>
<h3>错误的用户名和密码</h3>
<%
} }
%>
</body>
</html>

登录成功欢迎页welcome.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<html>
<head>
<title>'welcome.jsp'</title>
</head> <body>
<%
if (session.getAttribute("userid") != null) {
%>
<h3>
欢迎<%=session.getAttribute("userid")%>光临本系统,<a href="logout.jsp">注销</a>
</h3>
<%
} else {
%>
<h3>
请先进行系统的<a href="login.jsp">登录</a>
</h3>
<%
}
%>
</body>
</html>

登录注销logout.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<html>
<head>
<title>'logout.jsp'</title>
</head> <body>
<%
response.setHeader("refresh", "2;login.jsp");
session.invalidate();
%>
<h3>你已经成功注销,两面后自动跳转回首页</h3>
<h3>
如果没有跳转,请点击<a href="login.jsp">这里</a>
</h3>
</body>
</html>

判断新用户

<% session.isNew(); %>

取得用户的操作时间

<%

long start = session.getCreationTime();

long end = session.getLastAccessedTime();

long time = (end-start)/1000;//得出操作的秒

%>

application对象

常用方法 描述
String getRealPath(String path) 得到虚拟目录对应的绝对路径
public Enumeration getAttributeNames() 得到所有属性的名称
public String getContextPath() 取得当前的虚拟路径名称

取得虚拟目录对应的绝对路径

<%

String path1 = application.getRealPath("/");

String path2 = this.getServletContext().getRealPath("/");//两个方法的结果一样

%>

例如:保存表单内容在Web项目的根目录中的note文件夹中
表单递交页面form.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>form.html</title>
</head> <body>
<form action="input.jsp">
输入文件名称:<input type="text" name="filename"> 输入文件内容:
<textarea name="filecontent" cols="30" rows="3"></textarea>
<input type="submit" value="保存"> <input type="reset"
value="重置">
</form>
</body>
</html>
处理页面input.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%@ page import="java.io.*"%>
<%@ page import="java.util.*"%>
<html>
<head>
<title>My JSP 'input.jsp' starting page</title>
</head> <body>
<%
String realPath = this.getServletContext().getRealPath("/");
%>
<h3><%=realPath%></h3>
<%
String name = request.getParameter("filename");
String content = request.getParameter("filecontent");
String fileName = this.getServletContext().getRealPath("/")
+ "note" + File.separator + name;
File file = new File(fileName);
if (!(file.getParentFile().exists())) {
file.getParentFile().mkdir();
}
PrintStream ps = new PrintStream(new FileOutputStream(file));
ps.println(content);
ps.close();
%>
</body>
</html>
类似用FileOutputStream也可以完成创建文件并写入,body体改为
<body>
<%
String realPath = this.getServletContext().getRealPath("/");
%>
<h3><%=realPath%></h3>
<%
String name = request.getParameter("filename");
String content = request.getParameter("filecontent");
String fileName = this.getServletContext().getRealPath("/")
+ "note" + File.separator + name + ".txt";
File file = new File(fileName);
if (!(file.getParentFile().exists())) {
file.getParentFile().mkdir();
}
FileOutputStream fo = new FileOutputStream(file);
byte b[] = content.getBytes();
fo.write(b);
fo.close();
%>
</body>
结果一样。

网站计数器

<%@page import="java.io.*"%>
<%@page import="java.math.*"%>
<%@page import="java.util.*"%>
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'Count.jsp' starting page</title>
</head> <body>
<%!BigInteger count = null;%>
<%!//为了方便,方法直接定义放在在JSP文件中
public BigInteger load(File file) {
BigInteger count = null;
try {
if (file.exists()) {
Scanner scan = new Scanner(new FileInputStream(file));
if (scan.hasNext()) {
count = new BigInteger(scan.next());
scan.close();
}
}else {
count = new BigInteger("0");
save(file, count);
}
} catch (Exception e) {
e.printStackTrace();
}
return count;
} public void save(File file, BigInteger count) {
try {
PrintStream ps = null;
ps = new PrintStream(new FileOutputStream(file));
ps.println(count);
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}%>
<%
String filename = this.getServletContext().getRealPath("/")
+ "count.txt";
File file = new File(filename);
if (session.isNew()) {
synchronized (this) {
count = load(file);
count = count.add(new BigInteger("1"));
save(file, count);
}
}
%>
<h2>
您是第<%=count%>位访客!
</h2>
</body>
</html>
												

jsp学习笔记day2的更多相关文章

  1. JSP学习笔记

    JSP学习笔记 Jsp网页主要分为Elements与Template Data两部分. Template Data:JSP Container不处理的部分,例如HTML内容 Elements:必须经由 ...

  2. JSP学习笔记(三):简单的Tomcat Web服务器

    注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...

  3. java web jsp学习笔记--概述-常用语法,指令,动作元素,隐式对象,域对象

     JSP学习笔记 1.什么是jsp JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.JSP/Servlet规范.JS ...

  4. JSP 学习笔记1

    JSP 学习笔记   JSP是Servlet的一种特殊形式,每个JSP页面就是一个Servlet实例--JSP页面有系统编译成Servlet,Servlet再负责响应用户请求. 1.JSP注释 < ...

  5. jsp学习笔记:mvc开发模式

    jsp学习笔记:mvc开发模式2017-10-12 22:17:33 model(javabe)与view层交互 view(视图层,html.jsp) controller(控制层,处理用户提交的信息 ...

  6. JSP学习笔记2

    <JAVA遇见HTML——JSP篇>学习笔记(下) 1.Javabean Javabeans就是符合某种规范的java类,使用Javabeans的好处是[解决代码的重复编写],减少代码冗余 ...

  7. (转) jsp学习笔记

    fromhttp://www.cnblogs.com/tao975/p/4445070.html 什么是JSP JSP的优势 JSP的劣势 JSP与PHP的比较 JSP工作原理 JSP的九大内置对象 ...

  8. 《从零开始学Swift》学习笔记(Day2)——使用Web网站编写Swift代码

    Swift 2.0学习笔记——使用Web网站编写Swift代码 原创文章,欢迎转载.转载请注明:关东升的博客 Swift程序不能在Windows其他平台编译和运行,有人提供了一个网站swiftstub ...

  9. 重温JSP学习笔记--三大指令九大内置对象

    最近在温习javaweb的相关基础知识,鉴于我弄丢了记满了整整一本的笔记,决定以后把笔记和一些学习上的心得以及碰到的一些问题统统都放在网上,今天看了一下jsp的相关基础,以下是笔记: JSP三大指令: ...

随机推荐

  1. C++ 迷宫寻路问题

    迷宫寻路应该是栈结构的一个非常经典的应用了, 最近看数据结构算法应用时看到了这个问题, 想起来在校求学时参加算法竞赛有遇到过相关问题, 感觉十分亲切, 在此求解并分享过程, 如有疏漏, 欢迎指正 问题 ...

  2. 绕过Referer和Host检查

    1.我们在尝试抓取其他网站的数据接口时,某些接口需要经过请求头中的Host和Referer的检查,不是指定的host或referer将不予返回数据,且前端无法绕过这种检查 此时通过后端代理解决 在vu ...

  3. 基于sklearn的metrics库的常用有监督模型评估指标学习

    一.分类评估指标 准确率(最直白的指标)缺点:受采样影响极大,比如100个样本中有99个为正例,所以即使模型很无脑地预测全部样本为正例,依然有99%的正确率适用范围:二分类(准确率):二分类.多分类( ...

  4. VUE四 axios详解

    axios的中文文档写的已经很详细 https://www.kancloud.cn/yunye/axios/234845

  5. form里面文件上传并预览

    其实form里面是不能嵌套form的,如果form里面有图片上传和其他input框,我们希望上传图片并预览图片,然后将其他input框填写完毕,再提交整个表单的话,有两种方式! 方式一:点击上传按钮的 ...

  6. win下安装virtualenv和创建django项目

    一.由于一直在Linux环境下开发,想了解一下winPython开发环境: 1.打开cmd,pip install virtualenv 2.virtualenv test 由于这样需要进入到目录下才 ...

  7. 用Navicat Premium 连接mysql数据库时报错 -- 1130 Host xxxx is not allowed to connect to this MySQL server

    用Navicat Premium 连接mysql数据库时报错 报错原因:此时的MySQL默认不能远程连接. 解决方案:修改MySQL配置 具体步骤: 1.登陆服务器,进入数据库 mysql -uroo ...

  8. flink RPC(akka)

    flink中的rpc框架使用的akka.在本节并不详细讲述akka,而是就flink中rpc来讲述akka的部分内容.本节,我从AkkaRpcActor.handleRpcInvocation方法讲起 ...

  9. 结题报告--洛谷P3915

    题目:点此. 我处理这种多组数据的方法被我叫做“mains法”,就是先假设只有一组数据,写一个代码,然后把那个main函数改成mains,最后写一个真正的main函数. 这个“真正的”main函数一般 ...

  10. 编译Zookeeper3.4.6源代码并通过Intellij IDEA运行(2020年)

    一.问题背景 生产环境Windows机器上用的Zookeeper 3.4.6,最近经常报如下异常: 经过搜索,看到一篇帖子可以解决:https://www.jianshu.com/p/73eec030 ...