@[TOC](前端进阶学习 – 第一章 – JavaWeb核心/Servlet核心技术(上))
博客说明
文章内容输出来源:拉勾教育Java就业急训营
基本概念(常识)
C/S架构的概念
- C/S架构(Client/Server,客户端/服务器模式),是一种比较早的软件体系结构,也是生活中很常
见的结构。这种结构将需要处理的业务合理地分配到客户端和服务器端,客户端通常负责完成与用
户的交互任务,服务器通常负责数据的管理。 - C/S架构的主要优点如下:
客户端的界面和功能可以很丰富。
应用服务器的负荷较轻。 - 响应速度较快。
- C/S架构的主要缺点如下:
适用面窄,用户群固定。
维护和升级的成本高,所有的客户端都需要更新版本。
B/S架构的概念
- B/S架构(Browser/Server,浏览器/服务器模式),是互联网兴起后的软件体系结构,该结构将
系统功能实现的主要业务逻辑集中到服务器端,极少数业务逻辑在浏览器实现,浏览器通常负责完
成与用户的交互任务,服务器通常负责数据的管理。 - B/S架构的主要优点如下:
无需安装客户端,只要有浏览器即可。
适用面广,用户群不固定。
通过权限控制实现多客户访问的目的,交互性较强。
维护和升级的成本低,无需更新所有客户端版本。 - B/S架构的主要缺点如下:
应用服务器的负荷较重。
浏览器的界面和功能想要达到客户端的丰富程度需要花费大量的成本。
在跨浏览器上不尽如人意,适配比较麻烦。
JavaWeb的概念
- Web本意为网页的含义,这里表示互联网上供外界访问的资源。
- 互联网上供外界访问的资源主要分为以下两种:
静态资源:主要指Web页面中供人们浏览的数据始终是不变。
动态资源:主要指Web页面中供人们浏览的数据由程序产生,不同时间点访问页面看到的内
容各不相同。 - JavaWeb主要指使用Java语言进行动态Web资源开发技术的统称,是解决相关Web互联网领域的技
术总和。
早期的B/S架构
后来的B/S架构
HTTP协议(熟悉)
HTTP协议的概念
- HTTP协议(HyperText Transfer Protocol,超文本传输协议)是由W3C(万维网联盟)组织制定
的一种应用层协议,是用来规范浏览器与Web服务器之间如何通讯的数据格式,主要涉及浏览器
的发请求格式和服务器的响应格式。 - HTTP协议通常承载于TCP协议之上,而承载于TLS或SSL协议层之上的协议就是常说的HTTPS协
议。 - HTTP默认的端口号为80,HTTPS默认的端口号为443。
HTTP请求格式
客户端发送一个HTTP请求到服务器的请求消息主要包括:请求行、请求头、空白行和请求体。
HTTP响应格式
通常情况下服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息,主要包括:响
应行、响应头、空白行和响应体。
Tomcat服务器(重点)
基本概念
- Tomcat本意为公猫的含义,最初是由Sun公司的软件架构师詹姆斯·邓肯·戴维森开发的,后来他帮
助将其变为开源项目并由Sun公司贡献给Apache软件基金会。 - Tomcat 服务器是一个开源的轻量级Web应用服务器,在中小型系统和并发量小的场合下被普遍使
用,是开发和调试Servlet、JSP 程序的首选。
安装方式
下载地址:http://tomcat.apache.org/
目录结构
- bin :主要存放二进制可执行文件和脚本。
- conf:主要存放各种配置文件。
- lib :主要用来存放Tomcat运行需要加载的jar包。
- logs :主要存放Tomcat在运行过程中产生的日志文件。
- temp :主要存放Tomcat在运行过程中产生的临时文件。
- webapps :主要存放应用程序,当Tomcat启动时会去加载该目录下的应用程序。
- work :主要存放tomcat在运行时的编译后文件,例如JSP编译后的文件。
启动和关闭
- 启动方式
使用bin目录下的批处理文件startup.bat来启动Tomcat服务器,若出现一个毫秒数说明启动成
功。 - 关闭方式
使用bin目录下的批处理文件shutdown.bat来关闭Tomcat服务器。 - 注意事项
启动之前首先安装JDK并配置环境变量JAVA_HOME,若希望Tomcat服务器可以在任意路径启动,
则需要配置环境变量CATALINA_HOME。
启动信息乱码的处理方式:logging.properties文件修改为
java.util.logging.ConsoleHandler.encoding = GBK
配置文件
- server.xml文件是服务器的主配置文件,可以设置端口号、设置域名或IP、默认加载的项目、请求
编码等。
- tomcat-users.xml文件用来配置管理Tomcat服务器的用户与权限 。
使用IDEA创建Web项目
设置IDEA中Tomcat服务器的相关配置
Servlet的概念和使用(重点)
Servlet的基本概念
- Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,是Java语言编写
的服务器端程序,换句话说,Servlet就是运行在服务器上的Java类。 - Servlet用来完成B/S架构下客户端请求的响应处理,也就是交互式地浏览和生成数据,生成动态
Web内容。
Servlet的编程步骤
- 建立一个Java Web Application项目并配置Tomcat服务器。
- 自定义类实现Servlet接口或继承 HttpServlet类(推荐) 并重写service方法。
package com.lagou.demo02;
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//public class HelloServlet implements Servlet {
public class HelloServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("这是采用继承HttpServlet类的方式创建,以后开发中推荐使用该方式...");
}
}
- 将自定义类的信息配置到 web.xml文件并启动项目,配置方式如下:
<!-- 配置Servlet -->
<servlet>
<!-- HelloServlet是Servlet类的别名 -->
<servlet-name>HelloServlet</servlet-name>
<!-- com.lagou.task01.HelloServlet是包含路径的真实的Servlet类名 -->
<servlet-class>com.lagou.demo02.HelloServlet</servlet-class>
</servlet> <!-- 映射Servlet -->
<servlet-mapping>
<!-- HelloServlet是Servlet类的别名,与上述名称必须相同 -->
<servlet-name>HelloServlet</servlet-name>
<!-- /hello是供浏览器使用的地址 -->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
Servlet接口
javax.servlet.Servlet接口用于定义所有servlet必须实现的方法。
GenericServlet类
javax.servlet.GenericServlet类主要用于定义一个通用的、与协议无关的servlet,该类实现了
Servlet接口。
若编写通用servlet,只需重写service抽象方法即可。
HttpServlet类
javax.servlet.http.HttpServlet类是个抽象类并继承了GenericServlet类。
用于创建适用于网站的HTTP Servlet,该类的子类必须至少重写一个方法。
Servlet 的生命周期
使用注解实现Servlet[推荐]
package com.lagou.demo02;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//name --> 别名:servlet-name , urlPatterns --> 浏览器使用地址:url-pattern
@WebServlet(name = "HelloServlet4",urlPatterns = "/hello4")
public class HelloServlet4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("使用注解方式请求Servlet...");
}
}
POST和GET请求(重点)
ServletRequest接口(Http请求)
- javax.servlet.ServletRequest接口主要用于向servlet提供客户端请求信息,可以从中获取到任何
请求信息。 - Servlet容器创建一个ServletRequest对象,并将其作为参数传递给Servlet的service方法。
HttpServletRequest接口
- javax.servlet.http.HttpServletRequest接口是ServletRequest接口的子接口,主要用于提供HTTP
请求信息的功能。 - 不同于表单数据,在发送HTTP请求时,HTTP请求头直接由浏览器设置。
- 可直接通过HttpServletRequest对象提供的一系列get方法获取请求头数据。
简单使用ServletRequest接口、HttpServletRequest接口
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>请求参数的获取和测试</title>
</head>
<body>
<form action="parameter" method="post">
姓名:<input type="text" name="name"/><br/>
年龄:<input type="text" name="age"/><br/>
爱好:<input type="checkbox" name="hobby" value="Java"/>Java
<input type="checkbox" name="hobby" value="C"/>C
<input type="checkbox" name="hobby" value="C++"/>C++<br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
后端
package com.lagou.demo02;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Set;
@WebServlet(name = "ParameterServlet",urlPatterns = "/ParameterServlet")
public class ParameterServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用 String getParameter(String name)
// 1.获取指定参数名称对应的参数值并打印
String name = request.getParameter("name");
System.out.println("获取到的姓名为:" + name);
//使用 String[] getParameterValues(String name)
String[] hobbies = request.getParameterValues("hobby");
System.out.print("获取到的爱好有:");
for (String ts : hobbies) {
System.out.print(ts + " ");
}
System.out.println();
System.out.println("-------------------------------------------------------");
//使用 Enumeration getParameterNames()
// 2.获取所有参数的名称
Enumeration<String> parameterNames = request.getParameterNames();
System.out.print("获取到的所有参数名称为:");
while (parameterNames.hasMoreElements()) {
System.out.print(parameterNames.nextElement() + " ");
}
System.out.println();
System.out.println("-------------------------------------------------------");
//使用 Map<String, String[]>getParameterMap()
// 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 + " ");
}
System.out.println();
}
System.out.println("-------------------------------------------------------");
// 4.获取客户端请求的其它信息
System.out.println("发送请求的客户端IP地址为:" + request.getRemoteAddr());
System.out.println("发送请求的客户端端口号为:" + request.getRemotePort());
System.out.println("请求资源的路径为:" + request.getRequestURI());
System.out.println("请求资源的完整路径为:" + request.getRequestURL());
System.out.println("请求方式为:" + request.getMethod());
System.out.println("请求的附带参数为:" + request.getQueryString());
System.out.println("请求的Servlet路径为:" + request.getServletPath());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
ServletResponse接口(Http响应)
- javax.servlet.ServletResponse接口用于定义一个对象来帮助Servlet向客户端发送响应。
- Servlet容器创建ServletResponse对象,并将其作为参数传递给servlet的service方法。
HttpServletResponse接口
- javax.servlet.http.HttpServletResponse接口继承ServletResponse接口,以便在发送响应时提供
特定于HTTP的功能。
简单使用ServletResponse接口
前端
使用ServletRequest接口的前端即可,不会有影响(其实不需要前端。。。 )
后端
ServletResponse接口、HttpServletResponse接口的基础使用、内涵发送100以内的随机数测试
package com.lagou.demo02;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "ParameterServlet",urlPatterns = "/ParameterServlet")
public class ParameterServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//PrintWriter getWriter()
//获取向客户端发送文本的PrintWriter对象
PrintWriter writer = response.getWriter();
//String getCharacterEncoding()
// 获取响应数据的默认编码方式
String characterEncoding = response.getCharacterEncoding();
System.out.println("服务器响应数据的默认编码为:" + characterEncoding);//ISO-8859-1
//void setContentType(String type)
// 设置服务器和浏览器的编码方式以及文本类型
response.setContentType("text/html;charset=UTF-8");
writer.write("I received!");
//没有设置服务器和浏览器的编码方式以及文本类型,"我接受到了..." 为乱码
writer.write("我接受到了...");
System.out.println("服务器发送数据成功...");
writer.close();//关闭流
/*
* 测试:向客户端发送100以内的随机整数
* */
Random ra = new Random();
int num = ra.nextInt(100) + 1;
writer.write("<h1>" + num + "<h1>");
System.out.println("服务器发送数据成功...");
writer.close();//关闭流
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
Servlet接收中文乱码(重点)
接收乱码原因
浏览器在提交表单时,会对中文参数值进行自动编码。当Tomcat服务器接收到浏览器请求后自动
解码,当编码与解码方式不一致时,就会导致乱码。
解决POST接收乱码
解决GET接收乱码
ServletConfig接口(熟悉)
基本概念
javax.servlet.ServletConfig接口用于描述Servlet本身的相关配置信息,在初始化期间用于将信息
传递给Servlet配置对象。
配置方式
web.xml
<servlet>
<servlet-name>config</servlet-name>
<servlet-class>com.lagou.demo02.config</servlet-class>
<!--实现初始化参数的配置-->
<init-param>
<!--初始化参数的名称-->
<param-name>username</param-name>
<!--初始化参数的数值-->
<param-value>admin</param-value>
</init-param>
<!--实现初始化参数的配置-->
<init-param>
<!--初始化参数的名称-->
<param-name>pwd</param-name>
<!--初始化参数的数值-->
<param-value>123456</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>config</servlet-name>
<url-pattern>/config</url-pattern>
</servlet-mapping>
简单使用
上面配置信息对应的页面:
名称:config
package com.lagou.demo02;
import javax.servlet.*;
import java.io.IOException;
import java.util.Enumeration;
public class config implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("初始化成功...");
//返回Servlet的别名
System.out.println(servletConfig.getServletName());
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对象
web.xml
<!-- 对于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>
<!-- 进行Servlet的配置 -->
<servlet>
<servlet-name>ContextServlet</servlet-name>
<servlet-class>com.lagou.demo02.ContextServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ContextServlet</servlet-name>
<url-pattern>/context</url-pattern>
</servlet-mapping>
上面配置信息对应的页面:
名称:ContextServlet
package com.lagou.demo02;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
public class ContextServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.配置参数的获取
ServletContext servletContext = getServletConfig().getServletContext();
Enumeration<String> initParameterNames = servletContext.getInitParameterNames();
while(initParameterNames.hasMoreElements()){
String s = initParameterNames.nextElement();
System.out.println( s + "的参数对应为:" + servletContext.getInitParameter(s));
}
System.out.println("-------------------------------------------------------------------------");
//相关路径的获取
//本质上就是获取工程路径:/工程名
String contextPath = servletContext.getContextPath();
System.out.println("获取上下文关联的路径信息是:" + contextPath);
// "/"在服务器被解析为:http://ip地址:端口号/工程名
// 获取到的是部署工程路径信息 对应 当前工程中的web目录
String realPath = servletContext.getRealPath("/");
System.out.println("获取实际路径信息是:" + realPath);
System.out.println("-------------------------------------------------------------------------");
//设置和获取属性信息
servletContext.setAttribute("key","value");
Object key = servletContext.getAttribute("key");
System.out.println("根据参数指定的属性名获取的属性值为:" + key);
//删除指定的属性名信息
servletContext.removeAttribute("key");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}