学习笔记输出来源:拉勾教育Java就业急训营
修改时间:2021年1月28日
作者:pp_x
邮箱:[email protected]
文章目录
基本概念
C/S架构
C/S架构的概念
- C/S架构(Client/Server,客户端/服务器模式),是一种比较早的软件体系结构,也是生活中很常见的结构。这种结构将需要处理的业务合理地分配到客户端和服务器端,客户端通常负责完成与用户的交互任务,服务器通常负责数据的管理。
C/S架构的优缺点
- 优点:
- 客户端的界面和功能可以很丰富。
- 应用服务器的负荷较轻。
- 相应速度较快
- 缺点:
- 适用面窄、用户群固定
- 维护和升级成本高
B/S架构
B/S架构的概念
- B/S架构(Browser/Server,浏览器/服务器模式),是互联网兴起后的软件体系结构,该结构将系统功能实现的主要业务逻辑集中到服务器端,极少数业务逻辑在浏览器实现,浏览器通常负责完成与用户的交互任务,服务器通常负责数据的管理。
B/S架构的优缺点
- 优点:
- 无需安装客户端,只要有浏览器即可
- 适用面广,用户群不固定
- 通过权限控制实现多客户访问的目的,交互性较强
- 维护和升级的成本低,无需更新所有客户端版本
- 缺点:
- 应用服务器的负荷较重
- 浏览器的界面和功能想要达到客户端的丰富程度需要花费大量的成本
- 在跨浏览器上不尽如人意,适配比较麻烦
JavaWeb概念
- Web本意为网页的含义,这里表示互联网上供外界访问的资源
- 资源共分为两种
- 静态资源:要指Web页面中供人们浏览的数据始终是不变(HTML、CSS、JS)
- 动态资源:指Web页面中供人们浏览的数据由程序产生,不同时间点访问页面看到的内容各不相同。(Servlet、JSP)
- JavaWeb主要指使用Java语言进行动态Web资源开发技术的统称,是解决相关Web互联网领域的技术总和。
HTTP协议
HTTP的基本概念
- HTTP协议(HyperText Transfer Protocol,超文本传输协议)是由W3C(万维网联盟)组织制定的一种应用层协议,是用来规范浏览器与Web服务器之间如何通讯的数据格式,主要涉及浏览器的发请求格式和服务器的响应格式
- HTTP协议通常承载于TCP协议之上,而承载于TLS或SSL协议之上的协议就是常说的HTTPS协议。
HTTP默认端口号 80
HTTPS默认端口号443
HTTP请求格式
- 客户端发送一个HTTP请求到服务器的请求消息主要包括:请求行、请求头、空白行和请求体
- 请求行用来说明请求类型和要访问的资源以及所使用的HTTP版本
- 格式如下:
- 请求类型 请求的路径 协议的版本(1.1)
- 格式如下:
- 请求头是紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加信息
- 格式 (key:value)如下:
- 主机 请求长度 请求的浏览器相关信息
- 格式 (key:value)如下:
- 空白行就是请求头部的空行,即使后面的请求数据为空则必须有空行
- 请求体也叫请求数据,可以添加任意的其他数据。(get没有请求体)
- 请求行用来说明请求类型和要访问的资源以及所使用的HTTP版本
HTTP响应格式
- 服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息,主要包括:响应行、响应头、空白行和响应体。
- 响应行用来说明HTTP协议版本号和状态码以及状态消息
- 格式如下:
- 协议的版本(1.0 1.1) 状态码 (200 成功 404 路径错误 500 服务错误) 状态信息
- 格式如下:
- 响应头用来说明客户端要使用的一些附加信息
- 格式(key:value)
- 空白行就是响应头部的空行,即使后面的请求数据为空则必须有空行
- 响应体用来服务器返回给客户端的文本信息。
- 响应行用来说明HTTP协议版本号和状态码以及状态消息
Tomcat服务器
基本概念
- Tomcat本意为公猫的含义,最初是由Sun公司的软件架构师詹姆斯·邓肯·戴维森开发的,后来他帮助将其变为开源项目并由Sun公司贡献给Apache软件基金会。
- Tomcat 服务器是一个开源的轻量级Web应用服务器,在中小型系统和并发量小的场合下被普遍使用,是开发和调试Servlet、JSP 程序的首选
目录结构
配置文件
server.xml
文件是服务器的主配置文件,可以设置端口号、设置域名或IP、默认加载的项目、请求编码等。tomcat-users.xml
文件用来配置管理Tomcat服务器的用户与权限 。- 单实例多线程
Servlet的概念和使用
基本概念
- Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,是Java语言编写的服务器端程序,换句话说,Servlet就是运行在服务器上的Java类
- Servlet用来完成B/S架构下客户端请求的响应处理,也就是交互式地浏览和生成数据,生成动态Web内容
Servlet的编程步骤
- 建立一个Java Web Servlet项目并配置Tomcat服务器
- 自定义类实现Servlet接口或者继承HttpServlet、GenericServlet类并重写Service方法
- 将自定义的类的信息配置到web.xml文件中
- 配置方法如下:
<!-- 进行Servlet的配置 -->
<servlet>
<!-- 对Servlet起别名 习惯上就使用类名 -->
<servlet-name>HelloServlet3</servlet-name>
<!-- 指定上述别名所对应的Servlet类 -->
<servlet-class>com.lagou.demo02.HelloServlet3</servlet-class>
</servlet>
<!-- 进行Servlet的映射配置 -->
<servlet-mapping>
<servlet-name>HelloServlet3</servlet-name>
<!-- 配置浏览器的访问地址 -->
<url-pattern>/hello3</url-pattern>
</servlet-mapping>
- 浏览器访问方式
http://localhost:8080/工程路径/url-pattern的内容
Servlet接口
javax.servlet.Servlet
接口用于定义所有servlet必须实现的方法。- 常用方法
void init(ServletConfig config)
:由servlet容器调用,以向servlet指示servlet正在被放入服务中void service(ServletRequest req, ServletResponse res)
:由servlet容器调用,以允许servlet响应请求ServletConfig getServletConfig()
:返回ServletConfig对象,该对象包含此servlet的初始化和启动参数String getServletInfo()
:返回有关servlet的信息,如作者、版本和版权void destroy()
:由servlet容器调用,以向servlet指示该servlet正在退出服务
public class HelloServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("接收到了浏览器的请求并做出了响应!");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
GenericServlet类
- 基本概念:
javax.servlet.GenericServlet
类主要用于定义一个通用的、与协议无关的servlet,该类实现了Servlet接口。 - 若编写通用servlet,只需重写service抽象方法即可
- 常用的方法:
abstract void service(ServletRequest req, ServletResponse res)
:由servlet容器调用允许servlet响应请求
public class HelloServlet2 extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("继承GenericServlet类的方式来创建Servlet");
}
}
HttpServlet类(推荐使用)
javax.servlet.http.HttpServlet
类是个抽象类并继承了GenericServlet类。- 用于创建适用于网站的HTTP Servlet,该类的子类必须至少重写一个方法
- 常用的方法:
void doGet(HttpServletRequest req, HttpServletResponse resp)
:处理客户端的get请求void doPost(HttpServletRequest req, HttpServletResponse resp)
:处理客户端的post请求void init()
:进行初始化操作void service(HttpServletRequest req, HttpServletResponse resp)
:根据请求决定调用doget还是dopostvoid destroy()
:删除实例时释放资源
public class HelloServlet3 extends HttpServlet {
public HelloServlet3() {
System.out.println("构造方法调用了");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("这是采用继承HttpServlet类的方式创建,以后的开发中推荐该方式!");
}
@Override
public void destroy() {
System.out.println("销毁操作开始喽...");
}
@Override
public void init() throws ServletException {
System.out.println("初始化操作开始喽...");
}
}
Servlet的生命周期
- 注意:
- 构造方法只被调用一次,当第一次请求Servlet时调用构造方法来创建Servlet的实例。
- init方法只被调用一次,当创建好Servlet实例后立即调用该方法实现Servlet的初始化
- service方法被多次调用,每当有请求时都会调用service方法来用于请求的响应
- destroy方法只被调用一次,当该Servlet实例所在的Web应用被卸载前调用该方法来释放当前占用的资源。
POST和GET请求
GET请求
- 发出GET请求的主要方式:
- 在浏览器输入URL按回车
- 点击
<a>
超链接 - 点击submit按钮,提交
<form method=“get”>
表单
- GET请求特点: 会将请求数据添加到请求URL地址的后面,只能提交少量的数据、不安全
POST请求
- 发出POST请求的方法如下:
- 点击submit按钮,提交 表单
- POST请求的特点: 请求数据添加到HTTP协议体中,可提交大量数据、安全性好
- 使用注解创建Servlet对象
@WebServlet(name = "HelloServlet4", urlPatterns = "/hello4")
public class HelloServlet4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Post请求方式...");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Get请求方式...");
this.doPost(request, response);
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("原来使用注解可以如此潇洒...");
String method = req.getMethod();
System.out.println("获取到的请求方式为:" + method);
if ("get".equalsIgnoreCase(method)) {
doGet(req, resp);
}
if ("post".equalsIgnoreCase(method)) {
doPost(req, resp);
}
}
}
ServletRequest接口
javax.servlet.ServletRequest
接口主要用于向servlet提供客户端请求信息,可以从中获取到任何请求信息。- Servlet容器创建一个ServletRequest对象,并将其作为参数传递给Servlet的service方法
- 常用的方法:
String getParameter(String name)
:以字符串形式返回请求参数的值,如果该参数不存在,则返回值String[] getParameterValues( String name)
:返回一个字符串对象数组,其中包含给定请求参数所具有的所有值,如果该参数不存在,则返回空值Enumeration getParameterNames()
:返回包含此请求中包含的参数名称的字符串对象(类似迭代器对象)。如果请求没有参数,则方法返回空Map<String, String[]> getParameterMap()
:返回请求参数的键值对,一个键可以对应多个值String getRemoteAddr()
:返回发送请求的客户端或最后一个代理的IP地址int getRemotePort()
:返回发送请求的客户端或最后一个代理的端口号
// 1.获取指定参数名称对应的参数值并打印
String name = request.getParameter("name");
System.out.println("获取到的姓名为:" + name);//name
String[] hobbies = request.getParameterValues("hobby");
System.out.print("获取到的爱好有:");//java c
for (String ts : hobbies) {
System.out.print(ts + " ");
}
System.out.println();
System.out.println("-------------------------------------------------------");
// 2.获取所有参数的名称
Enumeration<String> parameterNames = request.getParameterNames();
System.out.print("获取到的所有参数名称为:");//name age hobby
while (parameterNames.hasMoreElements()) {
System.out.print(parameterNames.nextElement() + " ");
}
System.out.println();
System.out.println("-------------------------------------------------------");
// 3.获取请求参数名和对应值的第二种方式
Map<String, String[]> parameterMap = request.getParameterMap();
// 使用Map集合中所有的键值对组成Set集合
Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
// 遍历Set集合
for (Map.Entry<String, String[]> me : entries) {
System.out.print(me.getKey() + "对应的数值有:");
for (String ts : me.getValue()) {
System.out.print(ts + " ");//name对应的数值有:name age对应的数值有:11 hobby对应的数值有:Java C
}
System.out.println();
}
System.out.println("-------------------------------------------------------");
// 4.获取客户端请求的其它信息
System.out.println("发送请求的客户端IP地址为:" + request.getRemoteAddr());//0:0:0:0:0:0:0:1
System.out.println("发送请求的客户端端口号为:" + request.getRemotePort());//56801
HttpServletRequest接口
javax.servlet.http.HttpServletRequest
接口是ServletRequest接口的子接口,主要用于提供HTTP请求信息的功能。- 不同于表单数据,在发送HTTP请求时,HTTP请求头直接由浏览器设置。
- 可直接通过
HttpServletRequest
对象提供的一系列get方法获取请求头数据。 - 常用的方法:
String getRequestURI()
:返回此请求的资源路径信息StringBuffer getRequestURL()
:返回此请求的完整路径信息String getMethod()
:返回发出此请求的HTTP方法的名称,例如GET、POSTString getQueryString()
:返回路径后面请求中附带的参数String getServletPath()
:返回此请求中调用servlet的路径部分
System.out.println("请求资源的路径为:" + request.getRequestURI());///task01_demo02/parameter
System.out.println("请求资源的完整路径为:" + request.getRequestURL());//:http://localhost:8080/task01_demo02/parameter
System.out.println("请求方式为:" + request.getMethod());//POST
System.out.println("请求的附带参数为:" + request.getQueryString());//null get才有
System.out.println("请求的Servlet路径为:" + request.getServletPath());/// parameter
ServletResponse接口
javax.servlet.ServletResponse
接口用于定义一个对象来帮助Servlet向客户端发送响应。- Servlet容器创建ServletResponse对象,并将其作为参数传递给servlet的service方法。
- 常用方法:
PrintWriter getWriter()
:返回可向客户端发送字符文本的PrintWriter对象String getCharacterEncoding()
:获取响应内容的编码方式void setContentType(String type)
:如果尚未提交响应,则设置发送到客户端响应的内容类型。内容类型可以包括字符编码规范,例如text/html;charset=UTF-8
request.setCharacterEncoding("utf-8");
String characterEncoding = response.getCharacterEncoding();
System.out.println("服务器响应数据的默认编码方式为:" + characterEncoding); // ISO-8859-1
// 设置服务器和浏览器的编码方式以及文本类型
response.setContentType("text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
//writer.write("I Received!");
//writer.write("我接收到了!");
LocalDateTime date = LocalDateTime.now();
writer.write("<h1>" + date + "</h1>");
System.out.println("服务器发送数据成功!");
writer.close();
HttpServletResponse接口
javax.servlet.http.HttpServletResponse
接口继承ServletResponse接口,以便在发送响应时提供
特定于HTTP的功能- 常用方法:
void sendRedirect(String location)
:使用指定的重定向位置URL向客户端发送临时重定向响应
Servlet接收中文乱码
接收乱码原因
- 浏览器在提交表单时,会对中文参数值进行自动编码。当Tomcat服务器接收到浏览器请求后自动解码,当编码与解码方式不一致时,就会导致乱码。
解决POST接受乱码
- 接收之前设置编码方式:
request.setCharacterEncoding(“utf-8”)
- 必须在调用
request.getParameter(“name”)
之前设置
解决GET接收乱码
将接收到的中文乱码重新编码:
// 接收到get请求的中文字符串
String name = request.getParameter("name");
// 将中文字符重新编码,默认编码为ISO-8859-1
String userName = new String(name.getBytes(“ISO-8859-1”),“utf-8")
ServletConfig接口
javax.servlet.ServletConfig
接口用于描述Servlet本身的相关配置信息,在初始化期间用于将信息传递给Servlet配置对象。
配置方式
<servlet>
<servlet-name>ConfigServlet</servlet-name>
<servlet-class>com.lagou.demo02.ConfigServlet</servlet-class>
<!-- 实现初始化参数的配置 -->
<init-param>
<!-- 初始化参数的名称 -->
<param-name>userName</param-name>
<!-- 初始化参数的数值 -->
<param-value>admin</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123456</param-value>
</init-param>
</servlet>
常用方法
String getServletName()
:返回Servlet的别名String getInitParameter(String name)
:返回包含初始化参数name值的字符串,若不存在返回空Enumeration getInitParameterNames()
:返回Servlet初始化参数名字的对象,类似迭代器遍历ServletContext getServletContext()
:返回对调用方正在其中执行的ServletContext的引用
public class ConfigServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("初始化操作执行了...");
System.out.println("Servlet的别名是:" + servletConfig.getServletName()); // ConfigServlet
System.out.println("-----------------------------------------------");
// 获取配置文件中的初始化参数信息
String userName = servletConfig.getInitParameter("userName");
System.out.println("获取到的初始化用户名为:" + userName);
// 获取所有配置参数的名称
Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
while (initParameterNames.hasMoreElements()) {
System.out.println("初始化参数名为:" + initParameterNames.nextElement());
}
System.out.println("-----------------------------------------------");
// 获取ServletContext接口的引用
ServletContext servletContext = servletConfig.getServletContext();
System.out.println("获取到的ServletContext引用为:" + servletContext);
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
ServletContext接口
javax.servlet.ServletContext
接口主要用于定义一组方法,Servlet使用这些方法与它的Servlet容器通信。- 服务器容器在启动时会为每个项目创建唯一的一个ServletContext对象,用于实现多个Servlet之间的信息共享和通信。
- 在Servlet中通过
this.getServletContext()
方法可以获得ServletContext对象。
,或者通过getServletConfig.getServletContext()
方法获取
配置方式
<!-- 对于ServletContext对象的参数进行配置 -->
<context-param>
<param-name>param1</param-name>
<param-value>value1</param-value>
</context-param>
<context-param>
<param-name>param2</param-name>
<param-value>value2</param-value>
</context-param>
常用的方法
String getInitParameter(String name)
:返回初始化参数name的值的字符串,如果么有返回空Enumeration getInitParameterNames()
:将servlet的初始化参数的名称作为字符串对象返回,如果servlet没有初始化参数,则返回空;String getRealPath(String path)
:返回包含给定虚拟路径的实际路径的字符串String getContextPath()
:返回与此上下文关联的主路径InputStream getResourceAsStream(String path)
:将位于指定路径的资源作为InputStream对象返回void setAttribute(String name, Object object)
:将指定的属性名和属性值绑定到当前对象Object getAttribute(String name)
:根据执行的属性名获取属性值void removeAttribute(String name)
:删除指定的属性名信息
public class ContextServlet1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("配置参数的获取--------------------------");
//1、配置参数的获取
//ServletContext获取方式一
ServletContext servletContext = getServletConfig().getServletContext();
//ServletContext获取方式二
// ServletContext servletContext1 = this.getServletContext();
Enumeration<String> initParameterNames = servletContext.getInitParameterNames();
while(initParameterNames.hasMoreElements()){
String s = initParameterNames.nextElement();
System.out.println(s + "对应的值为:"+servletContext.getInitParameter(s));
}
//2、相关路径的获取
System.out.println("相关路径的获取-------------------");
//本质上就是获取工程路径 对应 /工程名
String contextPath = servletContext.getContextPath();
System.out.println("获取上下文关联的路径信息为:"+contextPath);
// '/'在服务器被解析为: http://ip地址:端口号/工程名 获取实际路径信息
//获取的是部署工程的路径信息 对应 当前工程的web目录
String realPath = servletContext.getRealPath("/");
System.out.println("获取到的实际路径信息是"+ realPath);
//3、设置和获取属性信息
System.out.println("---------------相关路径的获取-------------------------");
servletContext.setAttribute("key","value");
Object key = servletContext.getAttribute("key");
System.out.println("获取到param1的值为"+key);
servletContext.removeAttribute("key");
key = servletContext.getAttribute("key");
System.out.println("根据参数指定的属性名获取到的属性值为:" + key); // null
}
}