JavaWeb基础











Servlet 是在服务器上运行的小程序。这个词是在 Java applet的环境中创造的,Java applet 是一种当作单独文件跟网页一起发送的小程序,它通常用于在客户端运行,结果得到为用户进行运算或者根据用户互作用定位图形等服务。
服务器上需要一些程序,常常是根据用户输入访问数据库的程序。这些通常是使用公共网关接口(Common Gateway Interface,CGI)应用程序完成的。然而,在服务器上运行 Java,这种程序可使用 Java 编程语言实现。在通信量大的服务器上,JavaServlet 的优点在于它们的执行速度更快于 CGI 程序。各个用户请求被激活成单个程序中的一个线程,而无需创建单独的进程,这意味着服务器端处理请求的系统开销将明显降低。
实现过程
最早支持 Servlet 技术的是 JavaSoft 的 Java Web Server。此后,一些其它的基于 Java 的 Web Server 开始支持标准的 Servlet API。Servlet 的主要功能在于交互式地浏览和修改数据,生成动态 Web 内容。这个过程为:
客户端发送请求至服务器端;
服务器将请求信息发送至 Servlet;
Servlet 生成响应内容并将其传给服务器。响应内容动态生成,通常取决于客户端的请求;
服务器将响应返回给客户端。
Servlet 看起来像是通常的 Java 程序。Servlet 导入特定的属于 Java Servlet API 的包。因为是对象字节码,可动态地从网络加载,可以说 Servlet 对 Server 就如同 Applet对 Client 一样,但是,由于 Servlet 运行于 Server 中,它们并不需要一个图形用户界面。从这个角度讲,Servlet 也被称为 FacelessObject。
一个 Servlet 就是 Java 编程语言中的一个类,它被用来扩展服务器的性能,服务器上驻留着可以通过“请求-响应”编程模型来访问的应用程序。虽然 Servlet 可以对任何类型的请求产生响应,但通常只用来扩展 Web 服务器的应用程序。Servlet根据请求,动态的去生成要返回的html,并不是早就准备好的html文档。

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求。实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。
诀窍是,当配置正确时,Apache 为HTML页面服务,而Tomcat 实际上运行JSP 页面和Servlet。另外,Tomcat和IIS等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Apache服务器

这里注意两个问题:
tomcat启动乱码问题

tomcat的启动成功的判断方法

修改端口和调整乱码问题
定位到服务配置文件中

定位到日志文件中



过程简述:
1.首先从浏览器输入网址发出请求,请求发送到tomcat
2.tomcat根据映射假名匹配,匹配到后找到真名
3.根据真名再匹配servlet的具体路径
4.找到后Servlet处理请求,并且返回响应到浏览器
5.浏览器加载响应。



放在webapp目录中的WEB-INF中的sub文件不能随便被外部访问,里面放html,是访问不到的。

这样就可以访问了,一般推荐采用绝对路径,不采用相对路径。




注意上下文问题:就是servlet的映射的根路径的控制www.localhost:8080/xxxxx/url-pattern
一般都设置为忽略不常用。



String[] specs = request.getParameterValues("spec");PrintWriter out=response.getWriter();for(String spec:specs){out.println("<h2>spec:"+spec+"</h2>");}


以下是两种请求的处理方式。
@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String name = req.getParameter("name");String mobile = req.getParameter("mobile");PrintWriter out = resp.getWriter();out.println("GET");out.println("<h1>"+name+"</h1>");out.println("<h1>"+mobile+"</h1>");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String name = req.getParameter("name");String mobile = req.getParameter("mobile");PrintWriter out = resp.getWriter();out.println("POST");out.println("<h1>"+name+"</h1>");out.println("<h1>"+mobile+"</h1>");}
public class FirstServlet extends HttpServlet {//第一阶段装载,读取xml文件,加载配置信息,并未创建//第一次访问(地址栏输入)的时候才会创建servlet实体对象public FirstServlet() {System.out.println("正在创建...");}//创建之后初始化@Overridepublic void init() throws ServletException {System.out.println("正在初始化");}@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("正在处理。。");}//在tomcat关闭前会自动的关闭销毁@Overridepublic void destroy() {System.out.println("正在销毁");}
// 注意全局有且仅有一个servlet对象实例,有多个请求时,单例多线程。
}
在类上注解写上不用配置web.xml了
@WebServlet("/anno")
public class AnnotationServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().println("im annotation servlet!");}
}

Uniform Resource Locator
Uniform Resource Identifier

HTTP 协议的 Header 是一块数据区域,分为请求头和响应头两种类型,客户端向服务区发送请求时带的是请求头,而服务器响应客户端数据时带的是响应头。
请求头里主要是客户端的一些基础信息,UA(user-agent)就是其中的一部分,而响应头里是响应数据的一些信息,以及服务器要求客户端如何处理这些响应数据的指令。请求头里面的关键信息如下:
1) accept
表示当前浏览器可以接受的文件类型,假设这里有 image/webp,表示当前浏览器可以支持 webp 格式的图片,那么当服务器给当前浏览器下发 webp 的图片时,可以更省流量。
2) accept-encoding
表示当前浏览器可以接受的数据编码,如果服务器吐出的数据不是浏览器可接受的编码,就会产生乱码。
3) accept-language
表示当前使用的浏览语言。
4) Cookie
很多和用户相关的信息都存在 Cookie 里,用户在向服务器发送请求数据时会带上。例如,用户在一个网站上登录了一次之后,下次访问时就不用再登录了,就是因为登录成功的 token 放在了 Cookie 中,而且随着每次请求发送给服务器,服务器就知道当前用户已登录。
5) user-agent
表示浏览器的版本信息。当服务器收到浏览器的这个请求后,会经过一系列处理,返回一个数据包给浏览器,而响应头里就会描述这个数据包的基本信息。
响应头里的关键信息有:
1) content-encoding
表示返回内容的压缩编码类型,如“Content-Encoding :gzip”表示这次回包是以 gzip 格式压缩编码的,这种压缩格式可以减少流量的消耗。
2) content-length
表示这次回包的数据大小,如果数据大小不匹配,要当作异常处理。
3) content-type
表示数据的格式,它是一个 HTML 页面,同时页面的编码格式是 UTF-8,按照这些信息,可以正常地解析出内容。content-type 为不同的值时,浏览器会做不同的操作,如果 content-type 是 application/octet-stream,表示数据是一个二进制流,此时浏览器会走下载文件的逻辑,而不是打开一个页面。
4) set-cookie
服务器通知浏览器设置一个 Cookie;通过 HTTP 的 Header,可以识别出用户的一些详细信息,方便做更定制化的需求,如果大家想探索自己发出的请求中头里面有些什么,可以这样做:打开 Chrome 浏览器并按“F12”键,唤起 Chrome 开发者工具,选择 network 这个 Tab,浏览器发出的每个请求的详情都会在这里显示。

根据请求头进行判断是哪一种设备,就返回哪种设备的页面。

通过请求头判断处理方式,这里有一句话要注意,设置编码方式,否则中文字符串会乱码?号。
@WebServlet("/ua")
public class UserAgentServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String ua = req.getHeader("User-Agent");String output = "";if(ua.toLowerCase().indexOf("window nt")!=-1){output = "<h1>这是PC页面</h1>";}else {output = "<h1>这是移动端页面";}resp.setContentType("text/html;charset=utf-8");PrintWriter out=resp.getWriter();out.println(output);}
}

401代表没有登陆,403代表没有权限

@WebServlet("/ua")
public class UserAgentServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String ua = req.getHeader("User-Agents");String output = "";if(ua==null){resp.getWriter().println("请求头不存在");return;}if(ua.toLowerCase().indexOf("window nt")!=-1){output = "<h1>这是PC页面</h1>";}else {output = "<h1>这是移动端页面";}resp.setContentType("text/html;charset=utf-8");PrintWriter out=resp.getWriter();out.println(output);}
}
@WebServlet("/ct")
public class ContentTypeServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String output = "<h1><a href='http://www.baidu.com'><span>百度</span>";response.setContentType("aplication/x-msdownload;charset=utf-8");response.getWriter().println(output);}
}
@WebServlet("/index")
public class IndexServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");response.getWriter().println("我是主页");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req,resp);}
}
@WebServlet("/login")
public class CheckLoginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");String password = request.getParameter("password");if(username.equals("admin")&&password.equals("123456")){System.out.println("登录成功");//请求转发//request.getRequestDispatcher("/index").forward(request,response);//响应重定向response.sendRedirect("/index");}else {System.out.println("用户登录失败");}}
}<body><form action="/login" method="post"><input name="username"><input name="password" type="password"><input type="submit"></form>
</body>方式一请求转发的形式

方式二响应重定向的方式



两者的区别:
请求转发:一个是一次即可请求完成,紧密相关,因为由一个tomcat管理,只能在应用的内部进行转发
响应重定向:不是紧密相连的对象,默认get方式,因为两次响应,可以跳到其他服务器管理站点如百度

登录后主页面显示账号名称实例:
@WebServlet("/login")
public class CheckLoginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");String password = request.getParameter("password");if(username.equals("admin")&&password.equals("123456")){System.out.println("登录成功");request.setAttribute("username",username);request.setAttribute("password",password);
// 请求转发,总体一个请求,可以设置和获取属性request.getRequestDispatcher("/index").forward(request,response);
// //响应重定向,一共两个请求,会出现Null的情况
// response.sendRedirect("/index");}else {System.out.println("用户登录失败");}}
}@WebServlet("/index")
public class IndexServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");String username = (String)request.getAttribute("username");response.getWriter().println("我是主页"+username);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req,resp);}
}Cookie





@WebServlet("/cookie/random")
public class RandomServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {Integer random = new Random().nextInt(10000);Cookie cookie = new Cookie("random" , String.valueOf(random));cookie.setMaxAge(60*60*24);response.addCookie(cookie);response.setContentType("text/html;charset=utf-8");response.getWriter().println("<h2>随机数" + random+ "已生成</h2>");}
}@WebServlet("/cookie/show")
public class CookieServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {Cookie[] cookies = request.getCookies();Integer random=-1;if(cookies==null){response.getWriter().println("无cookie");return;}for(Cookie c:cookies){if (c.getName().equals("random")) {random=Integer.parseInt(c.getValue());}}response.setContentType("text/html;charset=utf-8");response.getWriter().println(random);}
}


为什么说session是和浏览器窗口绑定的?
因为当我把窗口关闭,cookie默认消除,此时向tomcat发送请求的时候,因为cookie没了,所以此时会创建一个新的session,原来的30min会自动销掉。
public class CheckLoginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");String password = request.getParameter("password");if(username.equals("admin")&&password.equals("123456")){System.out.println("登录成功");//为请求开辟一片内存空间,并设置属性及值,设置同时设置cookie的sessionidHttpSession session = request.getSession();session.setAttribute("username",username);//响应设置好cookie的sessionid,响应重定向到indexresponse.sendRedirect("/index");}else {System.out.println("用户登录失败");}}
}@WebServlet("/index")
public class IndexServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");//根据cookie来查找session空间,并获取属性HttpSession session = request.getSession();String username=(String) session.getAttribute("username");response.getWriter().println("我是主页"+username);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req,resp);}
}
@WebServlet("/servletcontext/init")
public class ServletContextInitServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ServletContext servletContext = req.getServletContext();servletContext.setAttribute("copyright","xxxx");resp.setContentType("text/html;charset=utf-8");resp.getWriter().println("ServletContext已初始化");}
}@WebServlet("/servletcontext/indx")
public class IndexServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf-8");ServletContext context = req.getServletContext();String copyright = (String)context.getAttribute("copyright");resp.getWriter().println(copyright);}
}



相关文章:
JavaWeb基础
Servlet 是在服务器上运行的小程序。这个词是在 Java applet的环境中创造的,Java applet 是一种当作单独文件跟网页一起发送的小程序,它通常用于在客户端运行,结果得到为用户进行运算或者根据用户互作用定位图形等服务。服务器上需要一些程序…...
C++基础了解-03-C++变量类型
C变量类型 一、变量类型 变量其实只不过是程序可操作的存储区的名称。C 中每个变量都有指定的类型,类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上。 变量的名称可以由字母、数字和下划线字符组成。…...
树莓派4b——通过mjpg-streamer使用摄像头
参考博文:(51条消息) 树莓派4b如何打开摄像头_树莓派打开摄像头_会飞的小东的博客-CSDN博客(51条消息) 树莓派4B (系统版本11,bullseye)更换清华源_树莓派更换清华源_ASSSSHION的博客-CSDN博客这个坑踩了我一星期,找各…...
MySQL运维篇之读写分离
04、读写分离 4.1、介绍 读写分离,简单地说是把对数据库的读和写操作分开,以对应不同的数据库服务器。主数据库提供写操作,从数据库提供读操作,这样能有效地减轻单台数据库的压力。 通过Mycat即可轻易实现上述功能,…...
windows程序最小化到托盘并显示提示信息
windows程序最小化到托盘并显示提示信息背景干货直接上代码解析控制窗口显示初始化托盘添加第一条消息更新界面结束啦背景 有些时候需要程序在最小化的时候可以看到程序进度,甚至需要完全关闭界面,只留下托盘显示,这篇文章就是在这个背景下诞…...
使字符串平衡的最少删除次数(简单动态规划)
给你一个字符串 s ,它仅包含字符 a 和 b 。 你可以删除 s 中任意数目的字符,使得 s 平衡 。当不存在下标对 (i,j) 满足 i < j ,且 s[i] b 的同时 s[j] a,此时认为 s 是 平衡 的。 请你返回使 s 平衡 的 最少 删除次…...
linux网络广播使用
广播使用的特殊的IP地址: 最后一位是255时的IP地址是给广播预留的IP地址, 如:192.168.1.255 UDP服务器在广播数据时,数据报使用的地址不是UDP服务器地址,而是广播地址 如:UDP服务器地址是:192.168.1.110 UDP服务器广播数据时使用地址是:192.168.1.255 UDP数据包发送给交换机…...
Kubernetes源码学习
kubernetes源码剖析 1.下载和编译源码 go 1.18.3 kubernetes 1.24.2 centos 7.9 进入目录$GOPATH/src/k8s.io/kubernetes,执行以下命令即可全量构建,并且构建结果只包含linux平台的: KUBE_BUILD_PLATFORMSlinux/amd64 make all GOFLAGS…...
筑基九层 —— 指针详解
目录 前言: 指针详解 前言: 1.CSDN由于我的排版不怎么好看,我的有道云笔记比较美观,请移步有道云笔记 2.修炼必备 1)入门必备:VS2019社区版,下载地址:Visual Studio 较旧的下载 -…...
内存清理、动画制作、CPU检测等五款实用软件推荐
人类与99%的动物之间最大差别在于是否会运用工具,借助好的工具,能提升几倍的工作效率。 1.内存清理软件——MemReduct MemReduct是一款内存清理软件,现在越来越多的软件由于硬件的普遍发展,对内存的使用都开始肆无忌惮起来&…...
RocketMQ 5.0 学习笔记
1. 需求 背景:业务需要,平台将使用rocketMQ来实现消息的发送与消费,替代redis的消息功能。 需要在搭建好rocketMQ平台后,进行研究和验证。 技术:Springboot RocketMQ5.0 使用场景:签到活动,…...
796.子矩阵的和
输入一个 n行 m列的整数矩阵,再输入 q个询问,每个询问包含四个整数 x1,y1,x2,y2,表示一个子矩阵的左上角坐标和右下角坐标。 对于每个询问输出子矩阵中所有数的和。 输入格式 第一行包含三个整数 n,m,q。 接下来 n…...
【PySide6】信号(signal)和槽函数(slot),以及事件过滤器
说明 在PYQT中,父控件可以通过两种方式响应子控件的事件: 通过信号(signal)和槽函数(slot)机制连接子控件和父控件父控件可以通过设置eventFilter()方法来监听响应子控件的事件 一、信号(signal)和槽函数(slot) 示例 在PYQT中,每个组件都…...
canal admin管理端配置(二)
下载安装 下载地址: 下载解压即可 配置 修改canal.admin-1.1.5\conf\application.yml server:port: 8089 #端口根据是否冲突修改 spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT8spring.datasource:address: 192.0.16.12:3306#数据库ip和端口…...
Servlet 生命周期
Servlet的生命周期有四个阶段:加载并实例化、初始化、请求处理、销毁。主要涉及到的方法有init、service、doGet、doPost、destory等 加载并实例化 Servlet容器负责加载和实例化Servelt。当Servlet容器启动时,或者在容器检测到需要这个Servlet来响应第一…...
redis集群模式登陆
总结redis单机模式时,登陆redis的命令格式: ./redis-cli -h 地址 -p 端口redis集群模式时,登陆redis的命令格式: ./redis-cli -h 地址 -p 端口 -c举例1:redis单机模式下登陆rootubuntu:/usr/local/redis/redis-7.0.0/b…...
04-useMemo 、React.memo、useCallback
useMemo 、React.memo、useCallback 一、useMemo 基本用法 缓存数据,模拟 Vue 中的计算属性。 同样useMemo跟vue中component一样,也是有缓存的,会将结果缓存下来 import React, { useMemo, useState } from react;export default functio…...
windows下安装emqx Unable to load emulator DLL@if ===/ SET data_dir=“
1.报错内容 I:\0-software\02-emqx\emqx-5.0.19-windows-amd64\bin>emqx start Unable to load emulator DLL (I:\0-software\02-emqx\emqx-5.0.19-windows-amd64\erts-12.3.2.9\bin\beam.smp.dll) 此时不应有 SET。 I:\0-software\02-emqx\emqx-5.0.19-windows-amd64\bin&…...
Redis常见问题(未完待续)
Redis常见问题Redis为什么快 ?Redis为什么快 ? 根据官方数据,Redis 的 QPS 可以达到约 100000(每秒请求数); 基于内存 对于磁盘数据库来说,首先要将数据通过 IO 操作读取到内存里再读取&#x…...
2024秋招BAT核心算法 | 详解图论
图论入门与最短路径算法 图的基本概念 由节点和边组成的集合 图的一些概念: ①有向边(有向图),无向边(无向图),权值 ②节点(度),对应无向图,…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)
cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...
