Servlet

本文详细介绍了Servlet的生命周期方法,包括init、service和destroy,以及HTTP协议的基础知识,如TCP/IP、请求/响应模型、请求头的使用。还涵盖了request和response对象的原理、请求体处理、数据共享、请求转发和重定向的区别,以及ServletContext的作用。
摘要由CSDN通过智能技术生成

Servlet的生命周期方法:

        1、被创建:执行init方法,只执行一次

                Servlet的init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的。多个用户同时访问时,可能存在线程安全问题。所以尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要去修改值。

        2、提供服务:执行service方法,执行多次

                每次访问Servlet时,Servlet方法都会被调用一次。

        3、被销毁:执行destroy方法,只执行一次

                Servlet被销毁时执行。服务器正常关闭时,Servlet被销毁。

HTTP:超文本传输协议(定义了发送数据的格式)

        1、基于TCP/IP的高级协议

        2、默认端口号:80

        3、基于请求/响应模型的:一次请求对应一次响应

        4、无状态的:每次请求之间相互独立,不能交互数据

请求消息数据格式

        1、请求行(请求url)

                请求方式有七种,常用两种,get和post.

        2、请求头:客户端浏览器告诉服务器一些信息

                请求头名称:请求头值

                常见的请求头:

                1、User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息

                        可以在服务器端获取该头的信息,解决浏览器兼容问题

                2、Referer:告诉服务器,我当前的请求从哪里来。

                        作用:防盗链、统计工作

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding:gzip, deflate, br, zstd
Accept-Language:zh-CN,zh;q=0.9
Connection:keep-alive
Cookie:JSESSIONID=28245FA9456DE80AD96030E747FDC6A3; Idea-8296eb30=8f993187-84db-4d67-80c1-c79530404e22; JSESSIONID=F3B0CC4700EADE28F10AA839ED527146
Host:localhost:63342
Referer:http://localhost:63342/WebDemo/com/example/html/h1.html?_ijt=oruo1s87g86q88uglbqtih7paj
Sec-Ch-Ua:"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"
Sec-Ch-Ua-Mobile:?0
Sec-Ch-Ua-Platform:"Windows"
Sec-Fetch-Dest:document
Sec-Fetch-Mode:navigate
Sec-Fetch-Site:same-origin
Sec-Fetch-User:?1
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36

       3、请求空行:空行就是用来分割post请求头和请求体的。

        4、 请求体(正文)

                封装POST请求消息的请求参数的。

username: 2433

Request:

1、request对象和response对象的原理

        1、request和response对象是由服务器创建的,我们来使用它们

        2、request对象是来获取请求消息,response对象是来设置响应消息

2、request对象继承体系结构:ServletRequest(接口)-HttpServletRequest(接口)-org.apache.catalina.connector.RequestFacade类(tomcat实现)

3、request功能:

        1、获取请求消息数据

                1、获取请求行数据

                        1、获取请求方式:String getMethod()

                        2、*获取虚拟目录:String getContextPath():/WebDemo

                                                        String getRealPath("文件名"):绝对路径:C:\Users\Administrator\IdeaProjects\WebDemo\target\WebDemo-1.0-SNAPSHOT\LoginServlet
 

                        3、获取Servlet路径:String getServletPath():/Login

                        4、获取get方式请求参数:String getQueryString()

                        5、*获取请求URL:String getRequestURI():/Login

                                                       StringBuffer getReuqestURL():http://localhost:8080/Login

                                                        URL:统一资源定位符

                                                        URI:统一资源标识符

                        6、获取协议及版本:String getProtocol():HTTP/1.1

                        7、获取客户机的IP地址:String getRemoteAddr():0:0:0:0:0:0:0:1

2、获取请求头数据

        方法:String getHeader(String name):通过请求头的名称获取请求头的值

                    Enumeration<String> getHeaderNames():获取所有的请求头名称

3、获取请求体数据

        请求体数:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数

        1、获取流对象

                BufferedReader getReader():获取字符输入流,只能操作字符数据

                ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据

        2、再从流对象中拿数据

BufferedReader reader=req.getReader();
String s = reader.readLine();

2、其他功能

        1、获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数

                1、String getParemeter(String name):根据参数名称获取参数值

                2、String getParameterValues(String name):根据参数名称获取其参数值的数组(比如多选框)

                3、Enumeration<String> getParemeterNames():获取其所有请求的参数名称

                4、Map<String,String[]> getParameterMap():获取所有参数的map集合

//在获取流之前设置,乱码是因为编码和解码所使用的字符集不一致
req.setCharacterEncoding("utf-8");
rep.setContentType("text/html;charset=utf-8");
Enumeration<String> parameterNames = req.getParameterNames();
while (parameterNames.hasMoreElements()) {
    System.out.println(parameterNames.nextElement());
}
System.out.println(req.getParameter("username"));
String[] habits = req.getParameterValues("habit");
for (String habit : habits) {
    System.out.println(habit);
}
Map<String, String[]> parameterMap = req.getParameterMap();
for (String s : parameterMap.keySet()) {
    System.out.print(s);
    String[] values = parameterMap.get(s);
    for (String value : values) {
        System.out.print(values);
    }
    System.out.println();
}

        2、请求转发:一种在服务器内部的资源跳转方式

               1、步骤:
                        1、通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)

                        2、使用RequestDispatcher对象来进行转发:forward(ServlerRequest request,ServletResponse response);

RequestDispatcher requestDispatcher=request.getRequestDispatcher("/Tomcat");
requestDispatcher.forward(request,response);

                2、特点:

                        1、浏览器地址栏路径不发生变化

                        2、只能转发到当前服务器内部的资源中

                        3、转发是一次请求

        3、共享数据

                域对象:一个有作用范围的对象,可以在范围内共享数据

                request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据

                方法:

                        1、void setAttribute(String name,Obiect obj):存储数据

                        2、Object getAttribute(String name):通过键获取值

                        3、void removeAttribute(String name):通过键移除值对

//LoginServlet
String username = "username";
request.setAttribute("username",username);
RequestDispatcher requestDispatcher=request.getRequestDispatcher("/Tomcat");
requestDispatcher.forward(request,response);
//TomcatServlet
Object username = req.getAttribute("username");
System.out.println(username);
req.removeAttribute("username");

        4、获取ServletContext:

                ServletContext getServletContext()


Response: 服务器发送给客户端的数据

        数据格式:

HTTP/1.1 200
Content-Type: text/html;charset=utf-8
Content-Length: 16
Date: Thu, 28 Mar 2024 09:02:44 GMT
Keep-Alive: timeout=20
Connection: keep-alive

        1、响应行:

                1、组成:协议/版本 响应状态码 状态码描述

                2、响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态

                        1、状态码都是3位数字

                        2、分类:

                                1、1xx:服务器接收客户端消息,但没有接收完成,等待一段时间后,发送1xx多状态码

                                2、2xx:成功。代表状态码:200

                                3、3xx:重定向。代表:302(重定向),304(访问缓存)

                                4、4xx:客户端错误。代表:404(请求路径没有对应的资源),405(请求方式没有对应的doxxx方法)

                                5、5xx:服务端错误。代表:500(服务器内部出现异常)

        2、响应头

                1、格式:头名称:值

                2、常见的响应头:

                        1、Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式

                        2、Content-disposition:服务器告诉客户端以什么格式打开响应体数据

                                值:in-line:默认值,在当前页面内打开

                                        attachment;filename=xxx:以附件形式打开响应体。文件下载

        3、响应空行

        4、响应体:传输的数据

Response对象:设置响应消息

        1、设置响应行

                1、格式:HTTP/1.1 200 ok

                2、设置状态码:setStature(int sc)

        2、设置响应头:setHeader(String name,String value)

        3、设置响应体:

                1、获取输出流

                        字符输出流:PrintWriter getWriter()

                        字节输出流:ServletOutputStream getOutputStream()

                2、使用输出流,将数据输出到客户端浏览器

resp.setStatus(200);
resp.setHeader("Content-Type","text/html;charset=utf-8");
PrintWriter writer1 = resp.getWriter();
writer1.write("你好!!");
ServletOutputStream outputStream = resp.getOutputStream();
outputStream.write("你好".getBytes("utf-8"));

        1、重定向-资源跳转的方式

//获取虚拟目录的路径
String contextPath = req.getContextPath();
//更改ResponseHeader的Location属性
resp.sendRedirect(contextPath+"/Login");
//访问其他服务器
//resp.sendRedirect("https://www.baidu.com/");

                重定向的特点

                        1、地址栏发生变化

                        2、重定向可以访问其他站点(服务器)的资源

                        3、重定向是两次请求。不能使用request对象来共享数据

                转发的特点:

                        1、转发地址栏路径不变

                        2、转发只能访问当前服务器下的资源

                        3、转发是一次请求,可以使用request对象来共享数据

        路径的写法:

                1、路径的分类

                        1、相对路径:通过相对路径不可以确定唯一资源

                                如:./index.html

                                规则:找到当前资源和目标资源之间的相对位置关系

                                        ./表示当前目录

                                         ../表示上一级目录

                        2、绝对路径:通过绝对路径可以确定唯一资源

                                 如:http://localhost:8080/WebDemo/response

                                 以/开头的路径

                                 规则:判断定义的路径是给谁用,判断请求将从哪儿发出

                                        给客户端浏览器使用:需要加虚拟目录(项目的访问路径)

                                                 建议虚拟目录动态获取:request.getContextPath():例如:重定向

                                        给服务器使用:不需要加虚拟目录。例如:请求转发

        2、验证码:

                1、本质:图片

                2、目的:防止恶意注册

ServletContext对象:

        1、概念:代表整个web应用,可以和程序的容器(服务器)来通信

        2、获取:

                1、通过request对象获取

                        request.getServletContext();

                2、通过HttpServlet获取
                        this.getServletContext();

ServletContext servletContext = req.getServletContext();
ServletContext servletContext1 = this.getServletContext();


        3、功能:

                1、获取MIM类型:

                        MIME类型:在互联网通信过程中定义的一种文件数据类型

                                格式:大类型/小类型        text/html        image/jpeg

                        获取:String getMimeType(String file)

                2、域对象:共享数据

                        1、setAttribute(String name,Object value)

                       2、getAttrubute(String name)

                       3、removeAttribute(String name)

                        ServletContext对象范围:所有用户所有请求的数据

                3、获取文件的真实(服务器)路径

ServletContext servletContext = req.getServletContext();
String mimeType = servletContext.getMimeType("a.html");
System.out.println(mimeType);
servletContext.setAttribute("username","张三");
//java文件的目录和webapp下的文件属于同一级目录
System.out.println(servletContext.getRealPath("WEB-INF/web.xml"));
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
//  获取文件真实路径
    String filename = request.getParameter("filename");
    ServletContext servletContext=request.getServletContext();
    String filename1 = servletContext.getRealPath("/img/"+filename);
//  设置文件类型,设置下载文件
    String jpg = servletContext.getMimeType(filename);
    response.setHeader("content-type",jpg);
//使用URL编码文件名,防止文件名出现中文乱码
    response.setHeader("content-disposition", "attachment;filename="+ URLEncoder.encode(filename,"utf-8"));
//  输出文件
    ServletOutputStream outputStream = response.getOutputStream();
    FileInputStream file=new FileInputStream(filename1);
    byte[] bytes =new byte[1024*8];
    int len=0;
    while ((len = file.read(bytes)) != -1) {
        outputStream.write(bytes,0,len);
    }
}
//前端代码
<form action="" method="get">
    <<a href="/WebDemo/DownloadServlet?filename=1.jpg">图片</a>
    <a href="/WebDemo/DownloadServlet?filename=2.mp4">视频</a>
</form>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值