Tomcat
Tomcat服务器基于Java Servlet和JavaServer Pages技术,提供Web容器的功能,为Web应用执行Java代码提供环境。下面是Tomcat服务器的基本工作原理:
-
用户请求:当用户在Web浏览器中输入URL并发送请求时,这个请求被发送到Tomcat服务器。
-
处理请求:Tomcat服务器接收到请求后,会根据URL在服务器中找到对应的Web应用。
-
Servlet容器:找到Web应用后,Tomcat的Servlet容器会根据请求来调用对应的Servlet。Servlet是一种运行在服务器端的Java程序,负责接收客户端请求,处理请求并返回响应。
-
执行Servlet:在执行Servlet的过程中,可能涉及数据库操作、调用Web服务、或者处理业务逻辑等。
-
返回响应:执行完成后,Servlet会生成HTTP响应,并通过Tomcat服务器返回给客户端。 Tomcat服务器使用JavaServer Pages(JSP)技术提供生成动态Web内容的功能。JSP使开发者能够使用HTML代码和嵌入的Java代码片段来创建动态Web页面。
除此之外,Tomcat还实现了Java WebSocket API,用于实现服务器和客户端之间的实时双向通信。 总的来说,Tomcat服务器的原理主要是基于Java Servlet和JSP技术,以及WebSocket技术,为Web应用提供执行Java代码和处理HTTP请求的环境。
如何进行网站访问的?
- 输入一个域名
- 检查本机的C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名映射;
- 如果存在则直接返回对应的ip地址
- 没有去DNS服务器找,找到则返回
HTTP
HTTP,全称为超文本传输协议(Hypertext Transfer Protocol),是一种应用层协议。它被用来在Web浏览器和网站服务器之间传送信息。这里有几个常见的HTTP版本。
-
HTTP/1.0: 这是HTTP协议的初级版本,于1996年5月发布。每次请求都需要建立新的连接。
-
HTTP/1.1: 于1997年1月发布,相比HTTP/1.0,HTTP/1.1引入了很多改进,例如持久连接,管道机制,增添PUT,PATCH,HEAD,OPTIONS,DELETE方法,引入更多的状态码等。
-
HTTP/2: 于2015年5月发布,其底层传输机制做了较大的改变,支持服务器推送(server push),首部压缩,支持多并发请求等。
-
HTTP/3: 目前还在IETF的草案阶段,方法和状态码与之前版本基本一致,最大的改变在于使用了QUIC作为传输层协议以取代TCP,这样做的目的是进一步减低延迟,同时改进了安全性。期望能解决HTTP/2 忽略的一些问题,提供更好的传输性能。
HTTP协议使用一种名为“HTTP头”的构造来携带一些HTTP请求和响应的信息。这些信息定义了如何传输数据或者请求的行为等。 HTTP请求头可以包含以下一些字段:
-
Host: 请求的目标服务器地址。
-
User-Agent: 发出请求的用户代理的信息,例如浏览器版本和操作系统。
-
Accept: 告诉服务器可以接受何种媒体类型的响应。
-
Connection: 用于告知网络连接的特性,通常的值为"keep-alive"或"close"。
-
Cookie: 在客户端存储的HTTP cookie内容。
-
Content-Type: 请求体的媒体类型,例如"application/json"或"multipart/form-data"。
HTTP响应头可以包含以下一些字段:
-
Server: 发送响应的服务器软件信息。
-
Date: 响应消息产生的时间。
-
Content-Type: 响应体的媒体类型,如"text/html"。
-
Content-Length: 响应体的长度。
-
Set-Cookie: 服务器要求客户端设置的HTTP cookie。
-
Connection: 用于告知网络连接的特性。
-
Cache-Control: 控制如何以及多久可以缓存响应。
这些仅仅是一部分HTTP请求头和响应头可能包含的字段。实际上,HTTP头部可以包含许多其他字段,这些字段可以用于携带各种类型的信息。
Maven
Maven是一个项目管理和构建自动化工具,主要用于Java项目的构建。Maven的主要功能和作用包括:
-
项目构建: Maven可以自动化完成项目构建过程,比如清理、编译、测试、打包、部署等步骤。
-
依赖管理: Maven采用中央仓库的方式来管理项目需要用到的所有依赖和其版本。我们只需要在项目的POM文件中声明所需的依赖,Maven会自动下载并管理依赖。
-
项目信息管理: Maven可以用来管理项目的相关信息,如开发者列表、版本历史、许可证信息等。
-
项目标准化: Maven提供了项目目录结构和构建生命周期的标准化,使得开发者易于理解和参与不同的Maven项目。
-
插件和生态: Maven有丰富的插件支持,可以扩展Maven的功能;同时Maven有成熟的社区支持和丰富的第三方库。
-
跨项目构建: Maven能够处理多个模块/项目的构建和依赖关系,是处理大型项目,特别是微服务项目的有力工具。
-
持续集成: Maven是实现持续集成的关键工具之一,能和Jenkins、Travis CI等持续集成工具很好的配合使用。
因此,Maven在项目构建、依赖管理以及项目信息管理等方面起着核心作用。
在构建Javaweb项目时,index.jsp有时无法自动添加到target目录下,导致tomcat无法访问页面!需要手动添加
更改webapp的版本,使其和tomcat版本一致
打开tomcat/webapps/root下找到web.xml文件,将其内容复制到项目中的web.xml中即可。
在写完servlet后运行项目对应的页面无法打开
执行mvn compile 是生成WEB-INF下的class文件,要生成target目录下的class文件,执行mvn package命令就可以了
每次更改servlet mapping 都要重新执行mvn package
Servlet
Servlet是Java Web编程的核心,这就像一个Java类一样的东西可以处理HTTP请求。HTTP请求是由WEB服务器接收的,然后发送到Servlet。Servlet是生成动态内容的主要技术。
- 在MVC设计模式中的controller层的作用相同
为什么需要web.xml映射文件
- 写好的Java程序需要让浏览器进行访问,而浏览器需要连接web服务器,所以我们需要在 web服务中注册我们写的Servlet,还需要给浏览器一个可以访问的路径。
servlet原理
重写的实现类:接收并处理请求;给出响应信息;
Mapping
- 一个servlet指定一个路径
- 一个servlet指定多个映射路径
- 一个servlet指定通用映射路径 /*
- 指定一些后缀或者前缀
ServletContext
ServletContext
是一个全局的存储信息的空间,它代表了Servlet容器中的Web应用ServletContext。
ServletContext的主要作用:
- 信息共享:在一个Web应用中,所有的Servlet和Jsp都可以共享ServletContext中的信息。
- 读取Web.xml配置中的初始化参数,如数据库连接参数等。
- 读取资源文件:可以用于读取Web应用下的资源文件。
在Servlet中,我们可以通过getServletContext()
方法获取一个ServletContext的实例,然后通过一系列的API进行操作
ServletContext对象在整个web应用中是唯一的吗?
当web应用启动时,服务器会创建一个对应的ServletContext对象,当应用结束时,这个对象会被销毁。ServletContext是一个全局的存储信息的空间,代表了Servlet容器中的web应用。它被用于在整个web应用的范围内共享数据。因此,ServletContext对象在整个web应用中确实是唯一的。
信息共享
//set方法,将信息写入context中
ServletContext context = this.getServletContext();
String username = "吴家昊";
context.setAttribute("username",username);
System.out.println(username);
//get方法,将信息从context读出
ServletContext context = this.getServletContext();
String name = (String) context.getAttribute("username");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().println("名字"+name);
//在不同的servlet中可以共享数据
请求转发
ServletContext context = this.getServletContext();
context.getRequestDispatcher("/param").forward(req,resp);
请求转发(Request Forward)和重定向(Redirect)在Web开发中是两种常见的页面跳转方式,它们的主要差别如下:
- 请求转发:这种方式只会发出一次请求,由Servlet将请求转发到其他资源(例如,另一个Servlet,JSP页面等)进行处理。在客户端浏览器的地址栏上看不到跳转的过程,因为整个过程都在服务器端进行。同时,在转发过程中,请求对象的生命周期被保持,因此在请求转发前设置的请求范围的属性可以在请求转发后仍然可以获取。 2
- 重定向:重定向则会发出两次请求,初次请求由Servlet接受,然后Servlet通知客户端(通过设置HTTP响应的状态代码和Location响应头)跳转到另一资源,客户端再次发送请求到指定资源。在地址栏上可以看到新的URL,重定向过程对客户端是可见的。同时,在重定向过程中,由于发出了新的请求,所以初次请求的对象并不会被保持,原本设置的请求范围属性会丢失。
简单来说,请求转发是服务器端的行为,客户端并不知道。而重定向是服务器告诉浏览器去向另一资源请求,所以客户端能看到新的URL地址。
读取资源文件
properties
- 在resources目录里新建properties
发现都被打包在了同一个路径下:classpath
ServletContext context = this.getServletContext();
//服务器上的类路径,第一个/代表当前目录下
InputStream resourceAsStream = context.getResourceAsStream("/WEB-INF/classes/db.properties");
//以文件流的形式来获取文件中的数据
Properties properties = new Properties();
properties.load(resourceAsStream);
Object username = properties.get("username");
Object password = properties.get("password");
resp.getWriter().println(username);
resp.getWriter().println(password);
HttpServletRequest
HttpServletRequest
: 代表客户端的请求。此接口的实例包含有关由Servlet容器创建的HTTP请求的信息,包含请求行(方法(如 GET, POST 等)、请求 URI、协议)、请求头信息、参数(通常是表单数据或者query string)、cookies等信息。- 通过请求转发
req.getRequestDispatcher("success.jsp").forward(req,resp);
-
获取请求参数
- 单个参数
String getParameter(String var1);
- 参数数组
String[] getParameterValues(String var1);
HttpServletResponse
HttpServletResponse
:代表服务器的响应。此接口的实例提供HTTP响应的功能。使得Servlet能够响应客户端的请求,比如发送请求头(包括状态码、content-type等)、设置cookies、输出HTML页面、文件、图片、Json等。- 向浏览器发送数据
//ServletResponse类
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
- 设置一些属性
//ServletResponse类
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setBufferSize(int var1);
//HttpServletResponse类
void sendError(int var1, String var2) throws IOException;
void sendError(int var1) throws IOException;
void sendRedirect(String var1) throws IOException;
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
-
下载文件
- 获取下载文件的路径
- 下载的文件名是什么
- 设置让浏览器支持下载我们所需的东西
- 创建下载文件的输入流
- 创建缓冲区
- 获取outputStream对象
- 将FileOutputStream写到缓冲区,将缓冲区数据输出到客户端
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取下载文件的路径 ServletContext context = this.getServletContext(); String realPath = "E:\\ideaWorkSpace\\javaweb\\servlet\\src\\main\\resources\\图标.png"; System.out.println("路径"+realPath); // 下载的文件名是什么 String filename = realPath.substring(realPath.lastIndexOf("\\") + 1); // 设置让浏览器支持下载我们所需的东西 resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(filename,"UTF-8")); // 创建下载文件的输入流 FileInputStream inputStream = new FileInputStream(realPath); // 创建缓冲区 int len = 0; byte[] buffer = new byte[1024]; // 获取outputStream对象 ServletOutputStream outputStream = resp.getOutputStream(); // 将FileOutputStream写到缓冲区,将缓冲区数据输出到客户端 while((len=inputStream.read(buffer))>0){ outputStream.write(buffer,0,len); } inputStream.close(); outputStream.close(); } URLEncoder.encode(filename,"UTF-8"));//用来转换url路径的编码方式
- 验证码
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 浏览器3秒刷新 resp.setHeader("refresh","3"); // 内存中创建一个图片 BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB); Graphics2D graphics = (Graphics2D) image.getGraphics(); // 设置背景颜色 graphics.setColor(Color.white); graphics.fillRect(0,0,80,20); // 给图片写数据 graphics.setColor(Color.blue); graphics.setFont(new Font(null,Font.BOLD,20)); graphics.drawString(makeNum(),0,20); // 告知浏览器以图片的方式打开 resp.setContentType("image/jpeg"); // 网站存在缓存,不让浏览器缓存 resp.setDateHeader("expires",-1); resp.setHeader("Cache-Control","nocache"); resp.setHeader("Pragma","no-cache"); // 把图片写给浏览器 ImageIO.write(image,"jpg",resp.getOutputStream()); }
- 重定向
resp.sendRedirect("/servlet_war/image"); //其实是实现了下面两段代码 resp.setHeader("/servlet_war/image"); resp.setStatus(302);