Javaweb-servlet&http

servlet&http

1.HTTP协议

1.1 介绍

  • HTTP (Hyper Text Transfer Protocol) 超文本传输协议,是互联网上应用最为广泛的一种网络协议。
    作用:
    规范浏览器和服务器之间通信时传输数据的格式
    特点:
    基于TCP协议:面向连接,安全
    基于请求-响应模型的:一次请求对应一次响应
    HTTP协议是无状态的协议:每次请求-响应都是独立的,不相互记录数据,目的是为提高效率
    无论是请求还是响应都包含三部分:行、头、体

1.2 HTTP请求

1.2.1 请求行
  • GET /mock/169327/emp/list?username=heima HTTP/1.1
    请求行由三部分组成:请求方式 请求路径 请求协议/版本。
    请求方式有很多, 我们需要关注两种: get 和 post
    get: 请求参数在地址栏显示,不太安全; 请求参数大小有限制; 没有消息体
    post:请求参数没有在地址栏显示,而是在请求体显示,相对安全; 请求参数大小没有限制; 有消息体
1.2.2 请求头
  • Connection: keep-alive
    请求头格式是键值对 键:值
    User-Agent: 浏览器告诉服务器端,客户端操作系统和浏览器版本信息,借助它可以处理浏览器的兼容性问题
1.2.3 请求体
  • username=heima
    格式 参数名=参数值&参数名=参数值
    注意 get方式没有请求体,post方式有请求体

1.3 HTTP响应

HTTP的响应也是由行、头、体构成的。

1.3.1 响应行
  • HTTP/1.1 200 OK
    响应行由三部分组成: 协议/版本 响应码 响应描述
    常见响应状态码:由服务器告诉浏览器,本次响应状态
    200:操作成功
    404:请求路径没有对应资源
    500: 服务器错误
1.3.2 响应头
  • Content-Type: text/html;charset=utf-8
    请求头格式是键值对 键:值
    Content-Type:服务器告诉浏览器,响应体的数据类型和编码方式
1.3.3 响应体
  • 服务器返回的具体内容

2.Servlet

2.1 简介

Servlet: Server Applet,翻译为运行在服务端的Java小程序,是sun公司提供一套规范( 接口 ),用来定义代码怎么写才能被tomcat识别。
本质:接口,一个类想要被tomcat正确识别,那么这个类就必须直接或间接的实现Servlet接口。
任务:接收请求,处理请求,返回响应。

2.2 入门案例

需求:使用一个Servlet完成一个功能,接收浏览器请求,在服务器控制台打印出访问时间的同时将时间写回浏览器。

2.2.1 导入依赖
<dependencies>
    <!--servlet依赖-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
</dependencies>
2.2.2 编写servlet
//定义一个类,继承HttpServlet,并重写service方法
public class TimeServlet extends HttpServlet {
    
    //注意重写service方法的参数是Httoxxx
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.打印时间
        System.out.println(new Date());
        
        //2.返回时间给浏览器
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write("当前时间"+new Date());
    }
}
2.2.3 配置servlet

在web.xml中配置

<!-- 告知服务器创建哪个类的对象 -->
	<servlet>
		<servlet-name>timeServlet</servlet-name>
		<servlet-class>com.itheima.servlet.TimeServlet</servlet-class>
	</servlet>
<!--提供一个可供外部访问的地址-->
	<servlet-mapping>
		<servlet-name>timeServlet</servlet-name>
		<url-pattern>/timeServlet</url-pattern>
	</servlet-mapping>
2.2.4 部署测试

请添加图片描述

2.3 执行流程

  1. 当Tomcat接收到客户端浏览器的请求后,会解析出Servlet的资源路径
  2. 查找web.xml文件,是否有对应的 标签体内容
  3. 如果有,则在找到对应的 全限定名
  4. tomcat根据类的全限定名,将字节码文件加载进内存,并且创建其对象
  5. 调用service()方法
    请添加图片描述

2.4 注解版

  • @WebServlet(“访问路径”)
//定义一个类,继承HttpServlet,并重写service方法
@WebServlet("/timeServlet")//注意:对于同一个servlet,xml和注解只能使用一个
public class TimeServlet extends HttpServlet {

    //注意重写service方法的参数是Httoxxx
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.打印时间
        System.out.println(new Date());

        //2.返回时间给浏览器
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write("当前时间"+new Date());
    }
}

2.5 常见报错

  1. The servlets named [annoServlet] and [annoServlet2] are both
    mapped to the url-pattern [/annoServlet] which is not permitted
    两个servlet的路径重复
  2. Invalid url-pattern [annoServlet] in servlet mapping
    servlet路径不是/开头的

3. 请求和响应

3.1 介绍

请添加图片描述

3.2 Request获取请求

3.2.1 请求行
* 请求行例子:  
	GET /requestLine?username=zhangsan&password=123 HTTP/1.1

* 重要方法:
1. String getMethod():获取请求方式: GET
2. StringBuffer getRequestURL(): 获取URL(统一资源定位符):http://localhost:8080/requestLine
3. String getRequestURI():获取URI(统一资源标识符)/requestLine
4. String getQueryString():获取请求参数(GET方式): username=zhangsan&password=123 
=====================================================================================================
@WebServlet("/reqLineServlet")
public class ReqLineServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println(req.getMethod());//获取请求方式: GET
        System.out.println(req.getRequestURL());//获取URL(统一资源定位符):
        System.out.println(req.getRequestURI());//获取URI(统一资源标识符): /requestLine
        System.out.println(req.getQueryString());//获取请求参数(GET方式):
    }
}
3.2.2 请求头
* 请求头例子:  
	User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/78.0.3904.108 Safari/537.36

* 重要方法:
	String getHeader(String name)String的形式返回指定请求头的值
=====================================================================================================
@WebServlet("/reqHeadServlet")
public class ReqHeadServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String header = req.getHeader("User-Agent");
        if(header.toLowerCase().contains("chrome")){
            System.out.println("你使用的谷歌浏览器");
        }
    }
}

3.2.3 请求参数

这里的请求参数指的是通过请求行传递的参数(get)和通过请求体传递的参数(post)

* 请求参数的位置:
	get请求:       URL上
	post请求:      请求体中

* 请求参数例子:
	name=张三&age=18&hobby=抽烟&hobby=喝酒

* 重要方法:
	1. String getParameter(String name)           根据参数名获得参数值(单个)
	2. String[] getParameterValues(String name)   根据参数名获得参数值(数组)
	3. Map<String, String []>  getParameterMap()  获得所有的参数,封装到Map集合 
======================================================================================================
@WebServlet("/reqBodyServlet")
public class ReqBodyServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //接收请求参数(单值)
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String sex = req.getParameter("sex");
        
        //接收请求参数(多值)
        String[] hobbies = req.getParameterValues("hobby");
        String xueli = req.getParameter("xueli");
        
        //使用map一次性接收
        Map<String, String[]> parameterMap = req.getParameterMap();
        Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();
        for (Map.Entry<String, String[]> entry : entries) {
            System.out.println(entry.getKey()+":"+Arrays.toString(entry.getValue()));
        }
        //System.out.println(username+":"+password+":"+sex+":"+ Arrays.toString(hobbies) +":"+xueli);
    }
}
3.2.4 中文乱码处理
* 在请求参数传递过程中,会出现中文乱码的问题
* get请求: tomcat8及以上的版本已经解决 (UTF-8* post请求:需要手动解决 
	乱码原因:浏览器编码(UTF-8)  ------ 服务器解码(ISO-8859-1)
	解决方案:修改服务器的解码方式为UTF-8即可
	代码: request.setCharacterEncoding("UTF-8");
======================================================================================================
@WebServlet("/reqBodyServlet")
public class ReqBodyServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //页面传递的数据是UTF-8 而服务器默认使用的编码是ISO-8859-1(不支持中文)
        req.setCharacterEncoding("UTF-8");

3.3 Response返回响应

3.3.1 返回响应
* 响应行
	响应行格式例子:
		HTTP/1.1  200
		HTTP/1.1  302
	设置响应行: 	
		void setStatus(int sc)

* 响应头
	响应头格式例子:
		Content-Type:text/html;charset=utf-8
	设置响应头:
		void setHeader(String name, String value)

* 响应体
	通过response获取输出流
		字符流:PrintWriter getWriter() 
		字节流:ServletOutputStream getOutputStream() 
	注意:在同一个servlet中,不能同时使用字节流和字符流
3.3.2 向浏览器输出字符
* 使用字符流输出内容到浏览器
	PrintWriter writer = response.getWriter();
	writer.write("字符串");
	
* 统一设置服务器和浏览器编码格式
	resp.setHeader("content-type","text/html;charset=utf-8")   了解
	resp.setContentType("text/html;charset=utf-8")             推荐	
=================================================================================================
@WebServlet("/respServlet")
public class RespServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //告知服务器使用什么编码把字符串保存到流中
        //设置响应头解决
       // resp.setHeader("content-type","text/html;charset=UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        //向页面响应文本
        PrintWriter out = resp.getWriter();
        out.write("qqq");
        out.write("你好");

        //当前service方法结束前,服务器会自动检查是否有流没有关闭,有则帮我们关闭
    }
}
3.3.3 向浏览器输出字节

向浏览器输出验证码图片
1.绘制一个背景图片
2.在图片上绘制验证码文本
3.在图片上绘制干扰线
4.将图片以字节流的形式写回

3.3.3.1 加入hutool依赖(此依赖用于生成验证码及图片)
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.3</version>
</dependency>
3.3.3.2 java生成验证码
@WebServlet("/respServlet2")
public class RespServlet2 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //生成图片
        LineCaptcha lineCaptcha = new LineCaptcha(200, 50);

        //通过字节输出流
        ServletOutputStream os = resp.getOutputStream();

        lineCaptcha.write(os);
    }
}

效果如图所示:

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值