week11_day04_Tomcat

首先上一个简单的模拟服务器端的代码:
WebServer:

/**
 * Created by IntelliJ IDEA.
 * User: Administrator
 * Date: 2019/11/18
 * Time: 15:21
 */

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 1.服务器需要监听某一端口号
 * 2.当请求到达对应端口号时,解析出所请求内容
 * 3.在当前服务器上面搜寻对应的资源,作出响应(200,404)
 */
public class WebServer {

    public static void main(String[] args) {
        //监听8080端口号
        try {
            // 监听端口--->8080
            ServerSocket serverSocket = new ServerSocket(8080);
            while (true){
                Socket socket = serverSocket.accept();
                //请求报文就在输入流中
                //在建立好的连接中,通过在服务器端的Socket对象中,获取流,来进行数据传输
                //输入流中的数据其实就是请求报文
                InputStream inputStream = socket.getInputStream();
                //如果要发送数据,那么就从Socket对象中获取,输出流
                OutputStream outputStream = socket.getOutputStream();
                //将请求报文封装到request对象中
                Request request = new Request(inputStream);
                //url代表客户端需要请求的资源
                String url = request.getRequestURL();
				
                System.out.println(url);
                //利用response对象进行响应
                Response response = new Response(url,outputStream);
                //作出响应
                response.response();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

request:

import java.io.IOException;
import java.io.InputStream;

public class Request {

    private InputStream inputStream;

    public Request(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    /**
     * 获取请求的资源名称
     * @return
     */
//请求方式:GET   url第三部分:/1.html   协议:HTTP/1.1
//    GET /1.html HTTP/1.1
//    Host: localhost:8080
//    Connection: keep-alive
//    Cache-Control: max-age=0
//    Upgrade-Insecure-Requests: 1
//    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36
//    Sec-Fetch-User: ?1
//    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
//    Sec-Fetch-Site: none
//    Sec-Fetch-Mode: navigate
//    Accept-Encoding: gzip, deflate, br
//    Accept-Language: zh-CN,zh;q=0.9
//Cookie是因为之前访问过8080
//    Cookie: Idea-83cde6a5=014bf777-5194-49e4-923c-2f4a24d6bff9

    public String getRequestURL() throws IOException {

        // 创建一个数组
        byte[] bytes = new byte[2048];
        //写入到byte数组中的长度
        StringBuffer stringBuffer = new StringBuffer();
        int read = inputStream.read(bytes);
        for (int i = 0; i < read; i++) {
            stringBuffer.append((char) bytes[i]);
        }
        //完整的请求报文
		//content是端口号8080监听到的字符串形式的输入流
        String content = stringBuffer.toString();
        System.out.println("----------------------------------------------");
		//可以在浏览器中访问http://localhost:8080/src/1.html
		//就能监听到浏览器发来的信息
        System.out.println(content);
        System.out.println("----------------------------------------------");


        if(content != null && !"".equals(content)){
           return getFileName(content);
        }
        return null;
    }

    /**
     * 从请求报文中获取访问的资源名称请求行:请求方法 请求资源 版本
     * @param content
     */
    private String getFileName(String content) {
//        System.out.println(content);
       //找到第一个空格所在的位置
        int a = content.indexOf(' ');
        //第二个空格所在的位置
        int b = content.indexOf(' ',a + 1);
        //注意一点,里面很可能包含请求参数,去掉
        String fileName = content.substring(a + 2, b);
        int i = fileName.indexOf('?');
        if(i != -1){
            //存在参数,需要截取
            return fileName.substring(0,i);
        }
        return fileName;
    }
}

response:

import java.io.*;

public class Response {

    private String url;

    private OutputStream outputStream;

    public Response(String url, OutputStream outputStream) {
        this.url = url;
        this.outputStream = outputStream;
    }

    public void response() throws IOException {
        //io流
        if (url != null) {
            System.out.println(url);
            File file = new File(url);
            StringBuffer stringBuffer = new StringBuffer();

            if (file.exists() && file.isFile()) {
                //200 构建响应报文
                //构建响应消息头, stringBuffer里是响应行和消息头
                stringBuffer.append("HTTP/1.1 200 OK \r\n");
                stringBuffer.append("Content-Type:text/html;charset=utf-8 \r\n");
                stringBuffer.append("\r\n");
                FileInputStream fileInputStream = new FileInputStream(file);
                byte[] bytes = new byte[1024];
                int length = 0;
                //我们要让输出流写回给浏览器一个响应报文
                outputStream.write(stringBuffer.toString().getBytes("utf-8"));
                //构建响应正文,file是正文
                while ((length = fileInputStream.read(bytes)) != -1) {
                    outputStream.write(bytes, 0, length);
                }
                System.out.println(bytes.toString());
                return;
            }
            //如果文件不存在,就构建一个404状态的响应报文
            stringBuffer.append("HTTP/1.1 404 Not Found \r\n");
            stringBuffer.append("Content-Type:text/html;charset=utf-8 \r\n");
            stringBuffer.append("\r\n");
            stringBuffer.append("<h1>File Not Found 404!</h1>");
            outputStream.write(stringBuffer.toString().getBytes("utf-8"));
            // 404
        }
    }
}

E:\WangDao\Vue_project\Socket这个项目的缺点:
1.效率低。WebServer通过while(true)循环一直在监听端口8080。
2.得一直运行这个项目才有对象存在。资源利用率太低。


1Tomcat

E:\WangDao\Vue_project\Socket这个项目的缺点:
1.效率低。WebServer通过while(true)循环一直在监听端口8080。
2.得一直运行这个项目才有对象存在。资源利用率太低。
1.1服务器
服务器至少需要干什么事情:
1.监听端口
2.分析请求报文
3.构建响应报文
承载java对象

WEB服务器开发(服务器)的相关知识
WEB,在英语中web即表示网页的意思,它用于表示Internet SERVER 上供外界访问的资源。
Internet上供外界访问的Web资源分为:
静态web资源(如html 页面):指web页面中供人们浏览的数据始终是不变。
动态web资源:指web页面中供人们浏览的数据是由程序产生的,不同时间点访问web页面看到的内容各不相同。
静态web资源开发技术
Html css javascript ? 图片 音频 视频
常用动态web资源开发技术:
JSP/Servlet、ASP、PHP 等 node.js
在Java中,动态web资源开发技术统称为Javaweb,我们课程的重点也是教大家如何使用Java技术开发动态的web资源,即动态web页面。(我们关注点:后台怎么处理请求提供数据)

JavaWEB应用程序
WEB应用程序指供浏览器访问的程序,通常也简称为web应用。

一个web应用由多个静态web资源和动态web资源组成,如:
html、css、js文件
Jsp文件、java程序、支持jar包、
配置文件
……

Web应用开发好后,若想供外界访问,需要把web应用所在目录交给web服务器管理,这个过程称之为虚似目录的映射,应用在webapps目录下无需映射。

1.2现成服务器
Javaee: 企业级开发:
包括13块内容: ejb、 jdbc、 jndi,、rmi、xml、Servlet, jsp等。
Javaee最主要关注的是Servlet, jsp

Tomcat简介
Tomcat是在SUN公司推出的小型Servlet/JSP调试工具的基础上发展起来的一个优秀的Servlet容器,Tomcat本身完全用Java语言编写。目前是Apache开源软件组织的一个软件项目,它的官方网址为http://tomcat.apache.org。得到了广大开源代码志愿者的大力支持,且可以和目前大部分的主流Web服务器(Apache服务器)一起工作,它运行稳定、可靠且高效。已成为目前开发企业JavaWeb应用的最佳Servlet容器选择之一。
我们后面的Java Web学习都是基于Tomcat服务器的。

1.3安装tomcat
推荐下载Tomcat8或Tomcat9
在这里插入图片描述
避免中文路径
有时候并不是直接安装就能用的?
要有(环境变量): JAVA_HOME

命令行:判断JAVA_HOME在不在
在这里插入图片描述
E:JDK表示JAVA_HOME在我的电脑上代表的路径。

1.4Tomcat使用

是用来部署服务器的: 主要用来部署java程序
在这里插入图片描述
开启:startup.bat
关闭:shutdown.bat
用命令行的话:
在这里插入图片描述
不过,Linux的命令是:./startup.bat和./shutdown.bat

Tomcat部署vue项目:
1, 在vue项目里执行 npm run build --打包出一个dist文件(包含一个html 和多个css, js 文件)
2, 把dist里面的内容放到tomcat的webapps下的ROOT里, 启动Tomcat

注意1: 如果不是windows, 改配置:将/改成./
在这里插入图片描述

注意2: vue — nuxt(服务端渲染)
用vue写博客,想让别人搜到你,但是没法儿搜到,因为vue项目打包后只是一个index.html文件,这个文件里没有你博客里的任何关键词。
但有一个基于vue的框架:nuxt,别人访问你的东西,就是一个实实在在的页面,页面里是你写的东西。

注意3: 打包方式 npm run build
在这里插入图片描述
注意4:
我们把vue项目打包-- webapps下的ROOT
如果你要用tomcat部署vue, 那么就放到root里,
如果你不想把打包好的文件放到root中,就得改webpack的配置并重新打包。最好不要这么做。最好还是放在root下。

发现:
1.利用npm run dev启动vue_homework项目,没有那么多js和css请求
在这里插入图片描述
2.而利用Tomcat访问vue_homework项目,会有很多js和css请求
在这里插入图片描述
为什么呢?
因为2是经过打包的,打包会对资源进行整理、压缩、合并,js样式、css样式,webpack帮我们自动合并整理了,形成js文件、css文件。

看一下dist目录:
在这里插入图片描述
Vue项目每次打包完都只有一个index.html文件和若干js、css文件,就算页面做的很复杂,也只有这些文件,为什么?
之前将Vue时,有这么一句话:Vue 完全有能力驱动采用单文件组件和Vue生态系统支持开发复杂单页应用。
单文件组件: 一个文件描述一个组件
单页应用: 经过打包生成一个单页的html文件和一些js、css文件

1.5Tomcat: 主要给java程序用的
实际上, 主要部署java war包 (java程序经过打包, 形成一个war包, 放到tomcat, 让tomcat运行)
所谓的让Tomcat运行war包, 本质的目的? 根据我们提供的war(代码) 创建出对应的对象。
之前讲前端服务器和后端服务器的功能有很大区别:
前端服务器:项目vue_homework放到Tomcat服务器中,此时的Tomcat就相当于一个前端服务器。浏览器发送请求,Tomcat封装并返回给浏览器打包后的项目vue_homework对应的文件,由浏览器来创建这些文件(代码)中对应的vue对象。
后端服务器:Tomcat中有一个war包,Tomcat根据war包生成一些java对象在Tomcat里面,当别人来访问了,Tomcat接受这些请求,把这些请求再转化给java对象,对这个对象进行一些逻辑上的操作,比如用这个对象调用数据库连接,访问数据等操作,做完这些操作后,将得到的结果通过Tomcat封装响应报文返回给浏览器。
比如JDBC,是根据代码生成的对象帮我们取数据库中取的数据。包括承载数据,class文件、java代码都没法儿承载数据,能承载数据的是根据代码生成的对象。
现在就更容易理解静态资源和动态资源了。

相当于一个是自动贩卖机,要了就直接给,一个是人工处理,要了别人就加工,做成后给你。

打包前浏览器访问服务器的流程:
在这里插入图片描述

打包后浏览器访问服务器的流程。
在这里插入图片描述

访问http://localhost:8081/的首页是这样的:
在这里插入图片描述
注意:这是首页的内容,当我们点击百度、淘宝后,右侧内容会变化,只有点击后,百度、淘宝所对应的的Vue对象才会挂载到DOM树上。并不是说浏览器拿到前端代码后,进行DOM解析,一下子把所有的Vue对象都挂载到DOM树上了。

有同学问为啥要打包,原因:
打包前的项目80M-200M,打包后的项目700k。
因为打包前的项目引用了很多包,因为开发项目需要各种功能,比如:热加载(改了前端代码,在浏览器中就能反应出来)。做了很多底层的工作,所以它很大。并且它还帮我们模拟了一个前端服务器。这些功能对我们开发者而言非常有用,但是开发好了后用户用的时候没有用。而且开发环境不稳定。
而打包后只需要导入很少的包,如下只导入vue和axios。而且并不是完全导入,只是抽出这两个包中的语法,转化成js文件了。打包后的文件放在服务器中,浏览器请求时,服务器返回dist目录下的文件给浏览器,浏览器解析。

"dependencies": {
  "axios": "^0.19.2",
  "vue": "^2.5.2"
},
"devDependencies": {
  "autoprefixer": "^7.1.2",
  "babel-core": "^6.22.1",
  "babel-helper-vue-jsx-merge-props": "^2.0.3",
  "babel-loader": "^7.1.1",
  "babel-plugin-syntax-jsx": "^6.18.0",
  "babel-plugin-transform-runtime": "^6.22.0",
  "babel-plugin-transform-vue-jsx": "^3.5.0",
  "babel-preset-env": "^1.3.2",
  "babel-preset-stage-2": "^6.22.0",
  "chalk": "^2.0.1",
  "copy-webpack-plugin": "^4.0.1",
  "css-loader": "^0.28.0",
  "extract-text-webpack-plugin": "^3.0.0",
  "file-loader": "^1.1.4",
  "friendly-errors-webpack-plugin": "^1.6.1",
  "html-webpack-plugin": "^2.30.1",
  "node-notifier": "^5.1.2",
  "optimize-css-assets-webpack-plugin": "^3.2.0",
  "ora": "^1.2.0",
  "portfinder": "^1.0.13",
  "postcss-import": "^11.0.0",
  "postcss-loader": "^2.0.8",
  "postcss-url": "^7.2.1",
  "rimraf": "^2.6.0",
  "semver": "^5.3.0",
  "shelljs": "^0.7.6",
  "uglifyjs-webpack-plugin": "^1.1.1",
  "url-loader": "^0.5.8",
  "vue-loader": "^13.3.0",
  "vue-style-loader": "^3.0.1",
  "vue-template-compiler": "^2.5.2",
  "webpack": "^3.6.0",
  "webpack-bundle-analyzer": "^2.9.0",
  "webpack-dev-server": "^2.9.1",
  "webpack-merge": "^4.1.0"
},

现在我们想这样整:本机8080端口既可以处理前端业务又可以处理后端业务。
即:把前端项目放在D:\developmer_tools\apache-tomcat-7.0.78\webapps\ROOT目录下
把后端代码放在:D:\developmer_tools\apache-tomcat-7.0.78\webapps目录下
这依旧是前后端不分离的。只不过是让本机上的一个Tomcat服务器既当前端服务器,又当后端服务器。

1.6怎么通过Tomcat部署java包
1.6.1Maven
前端: 包,用webpack打包
后端: 包, jar 用maven打包

把war包放进D:\developmer_tools\apache-tomcat-7.0.78\webapps目录下(这就是部署),然后点击startup.bat运行,Tomcat会把war包解压成一个文件。
在这里插入图片描述
解压后的文件目录下有三个文件夹:
在这里插入图片描述

注意:
War的目录结构:

Metainf: maven的自动生成目录
WEB-INF: 项目内容目录(WEB-INF是和我们写的代码息息相关的一些东西。)
Web.xml: war包描述文件
Classes: java代码的class文件
Lib: 项目依赖的jar包
Index.jsp: 可选项 (首页)
别的文件: 可选

1.7Tomcat目录结构
在这里插入图片描述
Bin: binary: 二进制文件: 一些tomcat启动关闭相关的文件
Conf: tomcat配置文件
Lib: tomcat依赖的第三方包
Logs: 日志文件, tomcat的日志文件
Temp: 临时文件
Webapps: 服务应用/服务项目
Work: tomcat的工作目录

1.8Tomcat的组成结构
Tomcat本身由一系列可配置的组件构成,其中核心组件是Servlet容器组件,它是所有其他Tomcat组件的顶层容器。每个组件都可以在Tomcat安装目录/conf/server.xml文件中进行配置,每个Tomcat组件在server.xml文件中对应一种配置元素。以下用XML的形式展示了各种Tomcat组件之间的关系

在这里插入图片描述

Server: 表示整个tomcat, 控制tomcat开启和关闭, 包含多个service
Service: 表示一个具体的服务, 对外的服务(暴露出端口号).
一个服务包含两部分:
Connector: 监听端口, 监听到请求之后, 封装request, response报文
,交给container处理
Container: (一个服务一个Container) 处理请求
具体表现就是一个engine
Engine: 具体处理请求, 要进一步交给host处理,一个engine可以包含多个host
Host: 站点, 虚拟主机,包含多个context
一个Tomcat就可以对应多个域名,因为一个域名对应一个host
Context: 具个的某个服务, 某个应用
在这里插入图片描述
在这里插入图片描述

Tomcat处理HTTP请求的过程localhost/test/index.jsp:

  1. 用户发送一个请求,被发送到当前机器的80端口号,被正在监听80端口号的coyote HTTP/1.1获得
  2. Connector组件将收到的请求传递给Engine组件
  3. Engine获得了请求地址为localhost/test/index.jsp,匹配虚拟主机
  4. 匹配到名为localhost的host,如果没匹配到,也将请求交给它处理,它被定义为Engine的默认虚拟主机,该host获得/test/index.jsp,匹配它所拥有的全部Context
  5. 匹配/test应用名对应的Context节点,Context节点获得index.jsp,它再去寻找响应的servlet
  6. Servlet处理完逻辑
  7. Context节点把执行完的结果返回给Host
  8. Host将结果返回给Engine
  9. Engine将结果返回给Connector组件
  10. Connector将最终的响应结果返回给客户端

1.9配置虚拟主机host
在这里插入图片描述
假如我们真的一个电脑申请了两个域名:localhost和localhost1,这样就可以通过访问http://localhost:8080/和http://localhost:8080/进入不同的虚拟主机host。
appBase表示默认访问路径。
但实际上我们只有http://localhost:8080/这个域名
在这里插入图片描述
注:http://localhost:8080/和http://localhost:8080/端口号不一定要一样,端口号是有Connector监听的,监听到请求交给Engine处理,所以一个Engine下只能有一个端口。但我们完全可以在一个Server下配置多个Service,让一个service监听8080,另一个service监听8099这样。

1.10虚拟目录映射
假如我不把项目放在D:\developmer_tools\apache-tomcat-7.0.78\webapps下,我就放在桌面,怎么让Tomcat帮我启动它呢?

Context: 具体的某个服务, 某个应用
所以按道理来讲,应该配置Context,配置完后一定要重启Tomcat。

1.10.1第一种: conf下server.xml之中host节点下面
Path是虚拟目录名称,docBase是Web应用所在目录。

在这里插入图片描述

1.10.2第二种: conf:
到目录:D:\developmer_tools\apache-tomcat-7.0.78\conf\Catalina\localhost下
创建一个xml, 给用户使用的应用名, 就是xml的文件名
在这里插入图片描述
在Tomcat6中,不再建议在server.xml文件中配置context元素,细节查看tomcat服务器关于context元素的说明。
让tomcat自动映射: tomcat服务器会自动管理webapps目录下的所有web应用,并把它映射成虚似目录。换句话说,tomcat服务器webapps目录中的web应用,外界可以直接访问。

Context元素的属性
在这里插入图片描述
Tomcat提供了多种配置元素的途径。当其加载一个web应用时,会:
1)到Tomcat安装目录/conf/[enginename]/[hostname]/[contextpath].xml文件中查找元素。
2) 到Tomcat安装目录/conf/server.xml文件中查找元素。只适用于单个Web应用
[contextpath]:表示单个Web应用的URL入口。如果修改为ROOT,则该应用就是默认访问的应用。

Note:若想让程序成为默认的Web应用,即访问http://localhost:8080时自动登录到Web应用的主页,可以在此处增加名字为ROOT.xml文件,其元素的path属性应该为””

1.11默认端口和页面
我们的电脑., 如果一个请求进来, 它没有带端口, 我们的电脑自动的把这个请求, 交给80端口处理
我们可以让tomcat直接监听80端口, 那么所有不带端口的请求, 都会触发到我们的tomcat中去
那么访问http://localhost就好了

1.11.1默认页面
默认加载index.html,你可以改成aaa.html
在这里插入图片描述
在这里插入图片描述

就算写两个默认页面也是从上往下解析,所以这样设置默认解析的还是index.html
在这里插入图片描述
web.xml文件
通过web.xml文件,可以将web应用中的:
某个web资源配置为网站首页

<welcome-file-list>
         <welcome-file>hello.html</welcome-file>
         <welcome-file>index.html</welcome-file>
         <welcome-file>index.htm</welcome-file>
         <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

将servlet程序映射到某个url地址上
……
但凡涉及到对web资源进行配置,都需要通过web.xml文件

举例:通过web.xml文件配置网站首页。

注意:web.xml文件必须放在web应用\WEB-INF目录下。

1.12WEB开发的前景
软件开发的两种架构:c/s 和 b/s
cs,如电脑桌面上的腾讯视频
Bs:如访问网站
在这里插入图片描述
在这里插入图片描述

随着网络带宽的不断提升,云计算概念的提出,浏览器只要足够强大,c/s架构立马就会被淘汰,不仅c/s架构会被淘汰,软件最终都会消失、操作系统都可以没有,最终将会是b/s架构的天下,也就是浏览器+搜索引擎的天下。所有现在桌面软件提供的功能,最后都由网站提供,也就是说,将来打开电脑就是一个浏览器,想要什么服务,通过搜索引擎一找,就可以在网上找到相应的服务,用就是了。所以web开发人员是现在最流行的岗位。
在这里插入图片描述
2重点
1, 安装和启动tomcat,
2, 部署java的war 包(放到webApps下,启动Tomcat)
3, 熟悉tomcat组成结构
4, 熟悉虚拟映射

3作业:
在浏览器上
http://localhost
就能返回一个页面

把项目放到D:\developmer_tools\apache-tomcat-7.0.78\webapps\ROOT目录下,更改D:\developmer_tools\apache-tomcat-7.0.78\conf目录下的server.xml文件:

<Connector connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="8443"/>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-玫瑰少年-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值