03_Tomcat

文章目录

  • Tomcat
    • 概念
    • 自制简易的服务器
    • JavaEE规范
    • Tomcat安装
    • Tomcat启动
    • Tomcat的资源部署
      • 直接部署
      • 虚拟映射
    • Tomcat的设置

Tomcat

概念

  • 服务器:两层含义。
    • 软件层面:软件,可以将本地的资源发布到网络中,供网络上面的其他用户来访问,比如tomcat
    • 硬件层面:一台性能比较高效的计算机主机,云服务器。
  • 服务器开发:指的是在服务器软件程序中进一步去编写程序来运行
  • 静态资源:页面一成不变的。
  • 动态资源:富有交互性、变化性。
    • 目前访问的网站页面基本都是动态资源。本质就是程序。比如登录之后会显示各自的用户名。开发动态资源的技术有很多种,其中java语言中 servlet。

自制简易的服务器

单线程的服务器

public class ServerDemo {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(8089);Socket socket = serverSocket.accept();// 怎么从socket获取信息InputStream inputStream = socket.getInputStream();byte[] bytes = new byte[20480];//输入的数据会放到字节数组bytes里面;读出的长度会返回lengthint length = inputStream.read(bytes);String inputStr = new String(bytes, 0, length);System.out.println(inputStr);// 想根据url上面的信息,返回1.txt 1.png// 应该拿出请求行; 再取出第二个数据// \r\n表示回车int index1 = inputStr.indexOf("\r\n");String firstLine = inputStr.substring(0, index1);// firstLine 为 GET /1.txt HTTP/1.1System.out.println(firstLine);// Strings = {GET, /1.txt, HTTP/1.1}String[] strings = firstLine.split(" ");System.out.println(strings[0]);System.out.println(strings[1]);System.out.println(strings[2]);// split之后获取到了1.txt// resourceName = 1.txtString resourceName = strings[1].substring(1);System.out.println(resourceName);// data如果有数据// 那么则传入1.txt// 1. 把数据的字节数组写回来// 2. 文件不存在,返回长度为0的字节数组byte[] data = getDataFromFile(resourceName);OutputStream outputStream = socket.getOutputStream();StringBuffer stringBuffer = new StringBuffer();if (data.length == 0) {// 代表文件没找到stringBuffer.append("HTTP/1.1 404 NotFound\r\n");stringBuffer.append("Server: coo1heisenberg\r\n");stringBuffer.append("Content-type: text/html\r\n");stringBuffer.append("\r\n");// 如果文件没找到,把data数组赋值data = "<div style = 'font-size: 50px'>file not found</div>".getBytes("utf-8");} else {stringBuffer.append("HTTP/1.1 200 Ok\r\n");stringBuffer.append("Server: coo1heisenberg\r\n");stringBuffer.append("Content-type: text/html\r\n");stringBuffer.append("\r\n");}// StringBuffer里面是响应行,响应头,空行的内容outputStream.write(stringBuffer.toString().getBytes("utf-8"));// data里面是文件的内容outputStream.write(data);outputStream.close();}private static byte[] getDataFromFile(String resourceName) throws IOException {InputStream inputStream1 = ServerDemo1.class.getClassLoader().getResourceAsStream(resourceName);byte[] bytes = new byte[20480];if (inputStream1 == null) {return new byte[0];} else {int len = inputStream1.read(bytes);byte[] bytes1 = Arrays.copyOf(bytes, len);return bytes1;}}
}

多线程的服务器

public class ServerDemo {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(8089);while (true) {Socket socket = serverSocket.accept();new Thread(() -> {// 怎么从socket获取信息InputStream inputStream = null;try {inputStream = socket.getInputStream();} catch (IOException e) {throw new RuntimeException(e);}byte[] bytes = new byte[20480];//输入的数据会放到字节数组bytes里面;读出的长度会返回lengthint length = 0;try {length = inputStream.read(bytes);} catch (IOException e) {throw new RuntimeException(e);}String inputStr = new String(bytes, 0, length);System.out.println(inputStr);// 想根据url上面的信息,返回1.txt 1.png// 应该拿出请求行; 再取出第二个数据// \r\n表示回车int index1 = inputStr.indexOf("\r\n");String firstLine = inputStr.substring(0, index1);// firstLine 为 GET /1.txt HTTP/1.1System.out.println(firstLine);// Strings = {GET, /1.txt, HTTP/1.1}String[] strings = firstLine.split(" ");System.out.println(strings[0]);System.out.println(strings[1]);System.out.println(strings[2]);// split之后获取到了1.txt// resourceName = 1.txtString resourceName = strings[1].substring(1);System.out.println(resourceName);// data如果有数据// 那么则传入1.txt// 1. 把数据的字节数组写回来// 2. 文件不存在,返回长度为0的字节数组byte[] data = new byte[0];try {data = getDataFromFile(resourceName);} catch (IOException e) {throw new RuntimeException(e);}OutputStream outputStream = null;try {outputStream = socket.getOutputStream();} catch (IOException e) {throw new RuntimeException(e);}StringBuffer stringBuffer = new StringBuffer();if (data.length == 0) {// 代表文件没找到stringBuffer.append("HTTP/1.1 404 NotFound\r\n");stringBuffer.append("Server: coo1heisenberg\r\n");stringBuffer.append("Content-type: text/html\r\n");stringBuffer.append("\r\n");// 如果文件没找到,把data数组赋值try {data = "<div style = 'font-size: 50px'>file not found</div>".getBytes("utf-8");} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}} else {stringBuffer.append("HTTP/1.1 200 Ok\r\n");stringBuffer.append("Server: coo1heisenberg\r\n");stringBuffer.append("Content-type: text/html\r\n");stringBuffer.append("\r\n");}// StringBuffer里面是响应行,响应头,空行的内容try {outputStream.write(stringBuffer.toString().getBytes("utf-8"));} catch (IOException e) {throw new RuntimeException(e);}// data里面是文件的内容try {outputStream.write(data);} catch (IOException e) {throw new RuntimeException(e);}try {outputStream.close();} catch (IOException e) {throw new RuntimeException(e);}}).start();}}private static byte[] getDataFromFile(String resourceName) throws IOException {InputStream inputStream1 = ServerDemo1.class.getClassLoader().getResourceAsStream(resourceName);byte[] bytes = new byte[20480];if (inputStream1 == null) {return new byte[0];} else {int len = inputStream1.read(bytes);byte[] bytes1 = Arrays.copyOf(bytes, len);return bytes1;}}
}

抽象出一个Request方法

public class Request {// GET POSTString method;String resourceName;String protocol;// 请求头用什么数据来装?Map<String, String> Header = new HashMap<>();public void parseContent(String content) {//parseFirstLine(content);parseHeaders(content);}private void parseHeaders(String content) {// 在windows下面是\n// 在Linux下面是 \r\n// 在mac下面是 \rint index1 = content.indexOf("\r\n");// 怎么确定请求头结束int index2 = content.indexOf("\r\n\r\n");String headersStr = content.substring(index1 + 2, index2);System.out.println(headersStr);// 1.按照\r\n切分split// 2. 得到数组,代表一行// 3. 一行切分,按照":"}private void parseFirstLine(String content) {int index = content.indexOf("\r\n");String firstLine = content.substring(0, index);String[] strings = firstLine.split(" ");method = strings[0];resourceName = strings[1];protocol = strings[2];}
}

JavaEE规范

  • 制定了一系列的接口。相应的厂商需要实现该接口,对于开发者来说,只需要面向接口编程即可。
  • JDBC也是,定义了很多的接口

Tomcat安装

在这里插入图片描述

Tomcat控制台乱码解决办法

  • 原因:cmd是GBK编码,Tomcat是UTF8编码
  • 解决:
    • 修改logging.properties配置:
      • 打开tomcat/conf/logging.properties
      • 添加语句:java.util.logging.ConsoleHandler.encoding = GBK
      • 重启tomcat,查看日志数据即可

Tomcat启动

  1. 双击startup.bat文件
  2. bin目录下换出cmd,执行startup

常见的启动故障

  • 没有正确配置好JAVA_HOME,导致tomcat一闪而过

Tomcat的资源部署

直接部署

在这里插入图片描述
eg:

  1. 写ip+端口 --> 相当于找到了webapps目录
    • localhost:8080/test
  2. 如果你想访问test文件夹下的1.txt。 只用写相对路径,
    • http://localhost:8080/test/1.txt
  3. 如果想访问test文件夹里面的2.png,怎么写呢?
    • http://localhost:8080/test/2.png

注意
不能将文件直接放置在webapps目录下。需要放在webapps目录下的文件夹内。

虚拟映射

不在webapps目录这种方式叫做虚拟映射。虚拟地映射到Tomcat的webapps目录下。

  1. conf/Catalina/localhost掌握
    • 新建一个.xml的配置文件
    • 在这里插入图片描述
    • .xml的文件(test1.xml)里面配置context的节点信息
      eg:
第一行是一个标识,表示这是一个xml
<?xml version="1.0" encoding="UTF-8"?>第二行表示在D盘有一个叫test_Photo的目录
<Context docBase="D:\test_Photo"/>
  • 访问流程
    • localhost:8080/{xml的名称}
      • 相当于会找到了docBase指定的文件夹
    • localhost:8080/{xml的名称}/{相对于docBase的相对路径}
      • eg:在这里插入图片描述

服务器最终会把url的路径映射到本地磁盘的一个路径上面

  1. conf/server.xml了解
  • 需要在Host节点下配置Context节点

    • /app452-----Context
<Context path="/app452" docBase="D:\test_Photo" />
  • http://localhost:8080/{path}/{文件相对于docBase的相对路径}
    • eg:http://localhost:8080/app452/2.jpg

Tomcat的设置

  1. 设置默认端口号
    • 对于http协议来说,默认端口号是80端口号。如果你也希望访问你的tomcat时,也不携带端口号,你只需要设置你的tomcat监听80端口号即可。
    • conf/server.xml中配置
    • 在这里插入图片描述
 <Connector port="80" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" />
  1. 设置缺省应用
    • tomcat中存在着一个缺省应用,如果没有找到匹配的应用时,则将该请求交给缺省应用来处理。
    • 具体步骤:
      • 如果希望配置一个ROOT应用,那么webapps目录下新建一个ROOT目录
      • conf/Catalina/localhost目录下新建一个ROOT.xml
    • ROOT应用下的资源文件在访问时,不需要携带应用的名称
以下为ROOT.xml的示例代码:<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="D:\test_Photo"/>

虚拟映射也可以配置一个ROOT.xml,如果虚拟映射和直接部署都有,那么则是虚拟映射优先级高

  1. 设置欢迎页面(缺省页面)
  • 比如:访问http://localhost,可以显示出一个页面,那么访问的是哪个页面:

    1. 没有应用名,说明访问的是ROOT应用

    2. 没有页面,说明访问的是欢迎页面(conf/web.xml文件中有配置)

      • 表示的是:如果请求没有指明具体访问的是哪个页面,那么会在当前应用下依次去查找是否存在该文件,如果存在,则加载;如果不存在,则返回404在这里插入图片描述

eg:
现在在chrome里面输入localhost,直接访问到我的D:\app31.jpg的图片,那么分为几个步骤?

  1. 修改端口号,改成8080端口

    • 在这里插入图片描述
  2. 虚拟映射

    • 在这里插入图片描述
  3. /conf/web.xml下修改welcome-file-list加上一个1.jpg

    • 在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/733561.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF 防止按钮Click时间多次点击响应

可能不是最好的办法&#xff0c;但是用起来效果也还是可以的。 原理&#xff1a;通过IsEnabled属性来控制按钮状态。btnConfirm.IsEnabled / this.IsEndbled 这两种方式是等价的。 案例比较简单&#xff0c;如果后期做开发的话代码量变大&#xff0c;只在结尾添加 this.IsEn…

网络综合布线

综合布线的英文表达为Structured Cabling System&#xff08;通俗表达为Cabling System&#xff0c;简称CSC&#xff0c;最早由AT&T提出&#xff09;或Premises Distribution System&#xff08;PDS&#xff0c;目前国标采用这一称法&#xff09;。   综合布线起源与发展…

Druid数据库连接池配置

客户端DruidDataSource 配置项描述建议值maxWait从连接池中获取connetion的最长等待时间10s TimeBetweenEvictionRunsMillis 轮询检查数据库连接池状态的间隔60s MinEvictableIdleTimeMillis 躺在连接池没有干活的空闲状态的最小值300s MaxEvictableIdleTimeMillis 1.躺在连接…

grafana table合并查询

注&#xff1a;本文基于Grafana v9.2.8编写 1 问题 默认情况下table展示的是一个查询返回的多个field&#xff0c;但是我想要的数据在不同的metric上&#xff0c;比如我需要显示某个pod的读写IO&#xff0c;但是读和写这两个指标存在于两个不同的metirc&#xff0c;需要分别查…

LeetCode27: 移除元素

题目描述 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出…

【DevOps基础篇】容器化架构基础设施监控方案

【DevOps基础篇】容器化架构基础设施监控方案 目录 【DevOps基础篇】容器化架构基础设施监控方案要监视什么不同监控系统方案比较1. Datadog2. Prometheus3. ELK(Elasticsearch、Logstash、Kibana)4. Sysdig5. 自行打造!如何选择总结推荐超级课程: Docker快速入门到精通 当…

Android谈谈ArrayList和LinkedList的区别?

Android中的ArrayList和LinkedList都是Java集合框架中的List接口的实现&#xff0c;但它们在内部数据结构和性能特性上有所不同&#xff1a; 1. **内部数据结构**&#xff1a; - ArrayList是基于动态数组&#xff08;可调整大小的数组&#xff09;实现的。它在内存中是连续…

ActivityRecord中Activity生命周期变化

本文基于AOSP13分析 ActivityRecord一些关键的属性&#xff1a; final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {// pause 超时时间private static final int PAUSE_TIMEOUT 500;// stop 超时时间private static fina…

Android中的抽象类与接口的区别是什么?谈谈List, Set, Map的区别?

目录 抽象类与接口的区别是什么&#xff1f; 谈谈List, Set, Map的区别&#xff1f; Android抽象类与接口的区别是什么&#xff1f; Android抽象类和接口在Java中都是用来实现多态和继承的重要特性&#xff0c;但它们之间存在一些关键的区别&#xff1a; 1. **定义和使用场…

多种方法求解数组排序

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇:Solitary_walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”。…

C++——string模拟实现

前言&#xff1a;上篇文章我们对string类及其常用的接口方法的使用进行了分享&#xff0c;这篇文章将着重进行对这些常用的接口方法的内部细节进行分享和模拟实现。 目录 一.基础框架 二.遍历字符串 1.[]运算符重载 2.迭代器 3.范围for 三.常用方法 1.增加 2.删除 3.调…

数据库-第十一章 并发控制【期末复习|考研复习】

前言 总结整理不易&#xff0c;希望大家点赞收藏。 给大家整理了一下数据库系统概论中的重点概念&#xff0c;以供大家期末复习和考研复习的时候使用。 参考资料是王珊老师和萨师煊老师的数据库系统概论(第五版)。 数据库系统概论系列文章传送门&#xff1a; 第一章 绪论 第二/…

数据分析-Pandas数据画箱线图

数据分析-Pandas数据画箱线图 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表&#xff…

【重新定义matlab强大系列十七】Matlab深入浅出长短期记忆神经网络LSTM

&#x1f517; 运行环境&#xff1a;Matlab &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#x1f917;&#x1f91…

编程笔记 html5cssjs 005 小学数学四则运算练习

编程笔记 html5&css&js 005 小学数学四则运算练习 一、代码二、解释 这段代码定义了一个页面&#xff0c;用于小学数学四则运算的练习。这可能有点难&#xff0c;实际如果需要可以通过更改代码来达到要求。 一、代码 <!DOCTYPE html> <html lang"zh&quo…

Git是一个分布式版本控制系统 一.1

git补充 通过git clone命令还是直接下载ZIP文件&#xff0c;你获取的都是代码库中的源代码。这意味着你可以查看、修改和编译这些源代码&#xff0c;根据需要进行自定义和扩展。 需要获取源代码而不需要版本控制的情况来说&#xff0c;直接下载ZIP文件和使用git clone命令确实…

音视频学习笔记——c++多线程(二)

✊✊✊&#x1f308;大家好&#xff01;本篇文章是多线程系列第二篇文章&#x1f607;。首先讲解了利用mutex解决多线程数据共享问题&#xff0c;举例更好理解lock和unlock的使用方法&#xff0c;以及错误操作造成的死锁问题&#xff0c;最后讲解了lock_guard与unique_lock使用…

Django模型层(附带test环境)

Django模型层(附带test环境) 目录 Django模型层(附带test环境)连接数据库Django ORM在models.py中建表允许为空指定默认值数据库迁移命令 开启测试环境建表语句补充(更改默认表名)数据的增加时间数据的时区 多表数据的增加一对多多对多 数据的删除修改数据查询数据查询所有数据…

Linux unset命令教程:如何删除环境变量或函数(附实例详解和注意事项)

Linux unset命令介绍 unset命令用于删除环境变量或函数。如果你不再需要某个环境变量或函数&#xff0c;你可以使用unset命令将其删除。 Linux unset命令适用的Linux版本 unset命令在大多数Linux发行版中都是可用的&#xff0c;包括Debian、Ubuntu、Alpine、Arch Linux、Kal…

鸿蒙OpenHarmony HDF 驱动开发

目录 序一、概述二、HDF驱动框架三、驱动程序四、驱动配置坚持就有收获 序 最近忙于适配OpenHarmonyOS LiteOS-M 平台&#xff0c;已经成功实践适配平台GD32F407、STM32F407、STM32G474板卡&#xff0c;LiteOS适配已经算是有实际经验了。 但是&#xff0c;鸿蒙代码学习进度慢下…