前端---tomcat与http

tomcat

底层支持Socket之间的通信进行数据共享是通过内部web服务器软件(容器:将servet/jsp进行对象的创建,将jsp翻译为java文件,ide将java文件编译为class文件)实现,tomcat 虽然不完全支持javaEE(不支持EJB),但是也是一款能支持web服务器的免费软件

tomcat 安装目录下文件夹:

bin:tomcat的可执行目录

  • startup.bat/startup.sh(linux)
  • shutdown.bat/shutdown.sh(linux)

conf:tomcat的配置目录

  • web.xml:定义全局参数,网站信息的配置
  • server.xml服务器的配置

lib:tomcat支持的jar包(本身已经包含了serlvet和jsp包)

为了防止版本冲突,因此当需要在maven项目中提供依赖时需要指定依赖范围为provide
依赖范围:
compile:编译
test:测试
provide:仅仅是当前提供者

logs:日志记录文件
temp:存储临时文件
webapp:存放网站信息(一个网站可以看成是一个文件夹),默认访问root(tomcat_home)
work:存放jsp文件(hello.jsp–>hello_jsp.java–>class文件)
WEB-INF:网站的配置信息,web.xml(配置servet/初始化参数)

  • classes:存放字节码文件
  • lib:存放jar包

启动tomcat经常会出现的问题:

闪屏
原因:tomcat启动时从bin目录的start.bat启动,会找java环境变量(JAVA_HOME)
解决:配置JAVA_HOME,添加tomcat的安装目录
启动失败
原因:一个电脑上有多个tomcat,配置了catalina_HOME
解决:不要配置catalina_HOME,只保留一个tomcat

tomcat启动后(http://localhost:8080),tomcat会发送一个请求,携带当前当问数据类型支持的语言

tomcat默认端口:8080
qq:5555
mysql:3306

servlet:针对服务器应用程序开发
其实就是一个单实例多线程的普通java类,能够被web应用服务器解析的一类
通过它的源码是否变化来区分动态资源还是静态资源:
静态资源:Html/css/js/.jpg/gif
动态资源:Servlet

在maven的web工程中,提交一个uri请求,会现在web.xml文件中查询动态资源地址,如果没有,在当前根目录下查询静态资源

手动开发Servlet:

创建一个maven工程(目录符合web工程结构)
1.在pom.xml下打war包
2.补全目录结构

src
	Man
		java
		Resource
		Webapp
			WEB-INF
				Web.xml

3.创建一个Servlet(必须在pom文件中导入依赖导入javax.servlet-api),配置pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <packaging>war</packaging>
    <groupId>com.github.sweeeeeet</groupId>
    <artifactId>tomcat-http</artifactId>
    <version>1.0-SNAPSHOT</version>

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
</project>

4.创建类继承HttpServlet,覆盖doGet():执行get方法提交;覆盖doPost():使用post方法提交

package com.github.sweeeeeet.tomcat;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Author:sweet
 * Created:2019/4/25
 * 开发者不new MyFirstServlet(),由tomcat服务器创建对象
 */
public class MyFirstServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置编码
        resp.setContentType("text/html;charset=utf-8");
        //向浏览器输出内容
        resp.getWriter().write("hello,这是我的第一个Servlet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }
}

5.配置web.xml文件

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!--配置网站信息-->
    <!--配置一个Servlet-->
    <servlet>
        <!--相当于在tomcat中穿梭的标识-->
        <servlet-name>MyFirstServlet</servlet-name>
        <servlet-class>com.github.sweeeeeet.tomcat.MyFirstServlet</servlet-class>
    </servlet>
    <!--配置Servlet的映射信息-->
    <servlet-mapping>
        <servlet-name>MyFirstServlet</servlet-name>
        <!--映射路径-->
        <url-pattern>/myFirstServlet</url-pattern>
    </servlet-mapping>
     <!--配置另一个Servlet的映射信息-->
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.github.sweeeeeet.tomcat.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet</url-pattern>
    </servlet-mapping>
</web-app>

6.使用maven打成war包,放入tomcat程序中

映射路径的写法

  1. 精确匹配
    /文件名;在浏览器请求的uri为:http://localhost:8080/文件名
  2. 模糊匹配
    a./* ;*表示任意路径
    b.*.action;以指定后缀名结尾

在映射路径中不能以精确匹配加模糊匹配的方式出现
精确匹配的优先级高于模糊匹配
以指定后缀名结尾的后缀名模糊匹配的优先级最低

在maven的web工程中,提交一个uri请求,tomcat会优先在web.xml文件中查询动态资源地址,如果没有,在当前根目录下查询静态资源。

http协议

http协议包含的内容:

HTTP	常见的请求头
Accept: text/html,image/*     --浏览器接受的数据类型
Accept-Charset: ISO-8859-1     --浏览器接受数据编码格式
Accept-Encoding: gzip,compress    --浏览器接受的数据压缩格式
Accept-Language: en-us,zh-       ---浏览器接受的语言  
Host: www.it315.org:80           --请求发出的主机和端口(必须)
If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT   --浏览器缓存的最后修改时间
Referer: http://www.it315.org/index.jsp   -- 当前请求来自于哪里 (防止非法链接)
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)   --浏览器的类型
Cookie:name=eric                 ---浏览器保存的cookie数据(会话管理)
Connection: close/Keep-Alive       ---浏览器和服务器的连接状态。close:关闭。keep-alive:保持连接
Date: Tue, 11 Jul 2000 18:23:51 GMT  --请求发出的时间

响应头
Location: http://www.it315.org/index.jsp   --重定向的地址。结合302状态使用完成重定向的效果
Server:apache tomcat    --服务器的类型
Content-Encoding: gzip     --服务器发送给浏览器的数据压缩格式
Content-Length: 80         --服务器发送给浏览器的数据长度
Content-Language: zh-cn    --服务器支持语言
Content-Type: text/html; charset=GB2312     --服务器发送给浏览器的数据类型和数据编码格式
Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT    --服务器资源的最后修改时间
Refresh: 1;url=http://www.it315.org        ---定时刷新或每隔n秒跳转资源
Content-Disposition: attachment; filename=aaa.zip   -- 以下载方式打开资源
Transfer-Encoding: chunked            
Set-Cookie:SS=Q0=5Lb_nQ; path=/search     -- 服务器发送给浏览器的cookie数据
Expires: -1            --通知浏览器不使用缓存
Cache-Control: no-cache
Pragma: no-cache   
Connection: close/Keep-Alive    连接状态
Date: Tue, 11 Jul 2000 18:23:51 GMT   响应发出的时间

一个请求=请求行+请求头

请求行

提交方式 uri http协议版本

提交方式:GET/POST
uri:/项目名称
http协议版本:Http/1.1:可以反复请求
Http/1.0:只能请求一次
URL:http://localhost:8080/hello(同一资源定位符)
url是uri的子集

请求头:Referer/User-Agent/Cookie/Connection
Referer:非法链接:代表请求地址从哪里来(应用场景:下载资源时),非法链接的情况:

  • 直接访问下载时referer:null
  • referer请求头 中不包含广告页面(!referer.contains(“adv.html”))

User-Agent:当前浏览器类型

响应头:Location/Refreah/Content-Disposition

  • Refreah:定时刷新,每隔n秒资源跳转
  • Content-Disposition:以什么方式打开资源

浏览器向服务器端发出请求(HttpServletRequset对象),服务器获取到请求的参数信息,进行响应后,tomcat等服务器就会做出一些逻辑发出响应(HttpServletResponse对象),浏览器获取到响应头信息以及响应的状态,给用户展示数据。服务器响应的时候如携带(cookie:饼干 小甜点) 将cookie携带给浏览器
不论是请求还是响应都要遵循一定的格式规则,http就是一个规则,定义请求信息和响应信息的解析规则

请求的流程:
1.tomcat 服务器启动–创建Servlet对象
2.将request对象封装到HttpServlet中,成为HttpServletRequest
3.解析HttpServlet中的一些内置方法并初始化

HttpServletRequest对象的API

获取请求方法: String method=req.getMethod();
获取请求uri: req.getRequestURI();
请求的协议版本: req.getProtocol();
获取指定的请求头信息: req.getHeader("host");
获取user-agent请求头req.getHeader("user-agent");会返回字符串,包含浏览器类型信息

Trisent:IE浏览器
Chrome:谷歌浏览器
firefox:火狐浏览器

以get方式提交请求时获取参数 数据:String queryString=req.getQueryString();
get方式会将请求信息放在地址栏中

以post方式提交请求时获取参数数据

InputStream in=   req.getInputStream();
        byte[] bytes=new byte[1024];
        int len=in.read(bytes);
        while(len!=-1){
            System.out.println(new String(bytes,1,len));
        }

post方式是以二进制字节数据向服务器发送请求的

get方式与post方式通用的获取参数的方式一
通过表单的name参数值获取表单内容,因此html中的表单一定要定义表单属性
获取所有参数值:Enumeration<String> enums= req.getParameterNames();

get方式与post方式通用的获取参数的方式二
通过指定参数名称获取参数值:req.getParameter("name");

get方式与post方式通用的获取参数的方式三
获取所有参数对象,返回值为map集合,key值为参数对象(String接收),value为参数值(参数值可以为多个,如表单为复选框的情况,用String[]):

Map<String,String[]> paraMap= req.getParameterMap();

get方式与post方式通用的获取参数的方式四
通过参数名,获取多个参数值:String[] habits= req.getParameterValues("habit");

tomcat8.0以下的版本,利用get()方法提交时:遇见参数为中文,需要手动解码,因为在表单中的信息是以UTF-8编码的,tomcat服务器是以iso-8859-1的方式编码的,若不进行解码会出现乱码的情况
手动解码:String name= req.getParameter(“name”);
name=new String(name.getBytes(“iso-8859-1”),“utf-8”);

使用post()方式提交请求时,解码的方法为: req.setCharacterEncoding(“utf-8”);

一般为了防止冲突,使用这些通用方法获取参数时会在doPost()方法中复用doGet()方法(获取参数的方法一般写在doget()中)

HttpServletResponse对象API

设置编码resp.setContentType("text/html;charset=utf-8");
向浏览器输出内容resp.getWriter().write("hello,这是我的第一个Servlet");
使用字节流的方式向浏览器输出内容(图片文件,音频视频)response.getOutputStream().write("hello,response".getBytes());

设置响应头setHeader("name","val)
设置响应的状态码response.setStatus(404); 访问不到servlet:

200 响应成功
500 服务器有问题(出现的各种异常)
404 一般情况:路径有问题 (url-pattern:路径对不上) :404状态+404错误页面
406 :异步请求出现的问题
400 项目下找不到资源
302 :进步一步请求 +location响应头 :

重定向

 //重定向原理
		// 设置状态302
        resp.setStatus(302);
        //设置location响应头
        resp.setHeader("location","adv.html");

当浏览器输入url向服务器发送请求时,服务器创建Servlet对象,调用了doGet()方法后,读到了302状态码,就会携带响应头地址resp.setHeader("location","adv.html");响应回给浏览器,浏览器会进一步访问,向服务器请求adv.html地址;所以一共有两个request对象,且不相等,因为两个请求携带的数据不同。
在实际应用中其实没有这么麻烦,在tomcat中配置web applecation的上下文路径(工程名称),就可以直接跳转resp.sendRedirect("/项目名称/资源文件名称");
重定向的地址栏会发生变化,跳转到指定的页面上。

请求转发: req.getRequestDispatcher("adv.html").forward(req,resp);
请求转发还是会处在请求的地址栏,是服务器的行为,request对象只有一个

设置定时刷新

resp.setHeader("Refresh","2");

设置编码格式:resp.setContentType("TEXT/HTML;charset=utf-8");

以指定方式打开资源:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        File file=new File("");
        //以下载方式打开资源
        resp.setHeader("Content-Disposition","attachment;filename="+file.getName());
        //下载文件
        //创建字节流输入对象
        InputStream in=new FileInputStream(file);
        //获取字节输出流对象
        OutputStream out=resp.getOutputStream();
        //边读边写
        byte[] buff=new byte[1024];
        int len=0;
        while((len=in.read(buff))!=-1){
            out.write(buff,0,len);
        }
        in.close();
        out.close();
    }

(面)Servlet生命周期

Servlet的执行过程:

  1. http://localhost:8080/hello-->
    在网站配置web.xml文件中中找是否存在一个映射url-pattern: /hello
  2. 如果找到,去servlet-maping中的servlet-name:找到对应的类名称HelloServlet,再在**配置信息(servlet标签)**中找是否存在同名的一个HelloServlet,
  3. 访问Servlet-class---->通过反射获取到HelloServlet.class 类对象 (重点)

反射机制:
创建类对象
1.Class classz=Class.forName("com.github.sweeeeeet.tomcat.HelloServlet");
2.通过数据类型的class属性获取class对象String.class
3.Object类中getClass()方法

获取Constructor 对象
Constructor con=classz.getDeclaredConstructor("构造函数的参数类型");
获取实例
Object obj=con.newInstance();
加载具体方法
Method m1=classz.getDeclaredMethod("init",ServletConfig.class);
m1.invoke(obj,config)

  1. 反射机制获取到成员方法---->tomcat解析里面内容

servlet初始化

servlet配置信息,初始化参数,或servlet加载机制
public void init(ServletConfig config)

简易初始化方法(用户自定义初始化信息时使用)
public void init()

servlet执行请求发送响应
tomcat服务器获取到浏览器的请求数据,会将请求数据封装到HttpServletRequset对象中,tomcat调用service方法,业务具体覆盖doGet()方法或doPost()方法(开发者做的事情)

业务服务protected void service(一般不会覆盖service 方法,会将逻辑写在doGet()或doPost()方法中)

  1. 使用HttpServletResponse响应给用户内容

  2. 销毁public void destroy()

销毁的几种情况
System.exit(0);
jvm停止运行

servlet架构

在这里插入图片描述

servlet中主要执行以下操作
1.获取前台页面传递过来的参数数据
2 调用service层,调用DAO(Data Acess Object)层
3.将数据存储到域
4.跳转到前台页面
Servlet是一个单实例多线程的,在内存中只会创建一次servlet对象,存在多线程的安全问题

ServletConfig对象API

ServletConfig是servlet配置对象,在处理逻辑doGet()/doPost()方法中,若需要频繁改动处理逻辑,可以将其放入到servlet配置信息中作为初始化参数,一个servlet 中可以使用多个ServletConfig对象,只需要在web.xml文件中配置init-param,在servlet标签中可以包含多个init-param

<init-param>
    <param-name>path</param-name>
    <param-value></param-value>
</init-param>

同时还可以设置servlet的加载时机:<load-on-startup>2</load-on-startup>

  • 数值越大,优先级越低

获取ServletConfig对象ServletConfig con=this.getServletConfig()
通过参数获取ServletConfig对象的值String path=fig.getInitParameter("path");

ServletContext对象API

作用:
1.获取上下文路径

ServletContext context=this.getServletContext();

2.可以请求转发(跳转页面)

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

           RequestDispatcher rd= context.getRequestDispatcher("/hello.html");
		   rd.forward(req,resp);
//简写方式
//req.getRequestDispatcher("hello.html").forward(req,resp);
    }

请求转发和重定向的区别:
1.转发请求地址不会发生变化,重定向本质上是进一步请求,因此地址会发生变化
2.请求转发在业务中跳转页面,需要用到域对象(request域);重定向无法从request域中获取数据
3.内存角度:请求转发始终只有一个request对象;重定向会产生两个不同的request对象

3.作为一个域对象使用

域对象:共享数据,在不同的jsp/servlet之间保存数据,获取数据
常见的域有:
PageContext—pageScope对象
HttpServletRequest—requestScope对象
HttpSession—sessionScope对象
ServletContext—applicationScope对象(最大的一个域)

在一个servlet中设置数据:context.setAttribute(String var1, Object var2);
在另一个servlet中获取数据:context.getAttribute(String s)

4.获取真实路径

        ServletContext context=getServletContext();
        context.getRealPath("a.txt");
//其他获取路径的方法
        PathDemo.class.getClassLoader().getResource("a.txt");

5.获取全局参数

1.String con = context1.getInitParameter("name");
2.Enumeration<String> s= context1.getAttributeNames();

猜你喜欢

转载自blog.csdn.net/weixin_42962924/article/details/89489663