servlet了解&掌握

35 篇文章 0 订阅
3 篇文章 1 订阅

1.maven介绍

在讲解servlet之前,有必要先了解一下maven,关于maven的介绍以及配置使用,请前往我的这篇笔记学习Maven的介绍与安装配置以及依赖

有了maven的基础,我们就可以正式进入servlet了吖~~

2. 创建servlet

2.1 servlet依赖导入maven

新建一个空的maven项目,将servlet的依赖给导入pom.xml文件中

 <dependencies>
<!--    每一个依赖都是写在一对<dependency></dependency>里面的,并且在<dependencies></dependencies>-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
         <!--
       compile:默认的scope,运行期有效,需要打入包中
       provided:编译期有效,运行期不需要提供,不会打入包中
       runtime:编译不需要,在运行期有效,需要导入包中。(接口与实现分离)
       test:测试需要,不会打入包中
       system:非本地仓库引入、存在系统的某个路径下的jar。(一般不使用)
     -->
    </dependency>
  </dependencies>

注意:在创建使用servlet等包的时候,是需要将servlet的依赖给导入maven项目中的,这样才可以被使用,具体的依赖找不到的话,可以直接在下面这个网站上maven依赖链接直接搜索自己想要的,然后给cv到pom.xml中即可。同时也要导入适合自己tomcate版本的依赖哦~

2.2 servlet类的创建

servlet类的创建有三种方式:

  1. 实现 javax.servlet.Servlet 接口,重写其全部方法。
  2. 继承 javax.servlet.GenericServlet 抽象类,重写 service() 方法。
  3. 继承 javax.servlet.http.HttpServlet 抽象类,重写 doGet() 或 doPost() 方法。

虽然servlet的创建有三种方式,但是现在我们都是用方法3,因为三者是存在实现与继承关系的,要是用一或二需要重写的方法就会很多,会造成代码冗余的情况,可以看一下三者的关系:

在这里插入图片描述

由图我们可以知道:

  1. GenericServlet 是实现了 Servlet 接口的抽象类。
  2. HttpServlet 是 GenericServlet 的子类,具有 GenericServlet 的一切特性。
  3. Servlet 程序(MyServlet 类)是一个实现了 Servlet 接口的 Java 类。

所以我们平时创建servlet的时候都是采用继承javax.servlet.http.HttpServlet 抽象类来完成的

现在我们来创建一个servlet类试试手~

  1. 创建一个UserController的servlet类
  2. 配置web.xml文件
  3. 完成一个servlet类的创建

第一步:创建servlet类

package com.xiaowang.createServlet;

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

/**
 * @Author:小王吖
 * @Date:2022/10/12
 */
public class UserController extends HttpServlet {
//如果请求是doGet请求会执行doGet
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
//如果请求是post请求会执行doPost
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

2.3 servlet的配置

servlet的配置由两种方式,不同的方式有不同的好处,下面来介绍下两种方式

2.3.1 web.xml配置

第二步:配置web.xml文件
无注释版本:

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<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_4_0.xsd"
         version="4.0"
         metadata-complete="false">
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>UserContrller</servlet-name>
    <servlet-class>com.xiaowang.createServlet.UserController</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UserContrller</servlet-name>
    <url-pattern>/User</url-pattern>
  </servlet-mapping>
</web-app>

有注释版本,介意看有注释版本,这样会对servlet的xml配置更加理解,

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<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_4_0.xsd"
         version="4.0"
         metadata-complete="false">
  <!--注意,这里的配置,要根据自己的toncat和servlet的版本来配置,我的tomcat是9的,所以这里的version="4.0",
  tomcat8的是version="3.0",反正就是要根据自己的版本来配置,这里如果不知道自己的是多少,可以去创建一个maven-webapp项目
  然后去看那个项目中web.xml中的配置,cv过来就好了-->
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
<!--    你的servlet项目的类名-->
    <servlet-name>UserContrller</servlet-name>
<!--    servlet项目的路径-->
    <servlet-class>com.xiaowang.createServlet.UserController</servlet-class>
  </servlet>
  <servlet-mapping>
    <!--    你的servlet项目的类名-->
    <servlet-name>UserContrller</servlet-name>
<!--    数据库中要操作的数据库的表名,同时也是我们的实体类,这两个是对应的-->
    <url-pattern>/User</url-pattern>
  </servlet-mapping>
</web-app>

2.3.2 注解配置

1. 注解解释

  • 若项目中 Servelt 数量较多时,web.xml 的配置会变得十分的冗长。这种情况下,注解(Annotation)就是一种更好的选择。
  • 注解不需要依赖于配置文件,它可以直接在类中使用,其配置只对当前类有效,这样就避免了集中管理造成的配置冗长问题。

2. 启用注解

  • web.xml 的顶层标签 中有一个属性:metadata-complete,该属性用于指定当前 web.xml 是否是完全的。若该属性设置为 true,则容器在部署时将只依赖 web.xml,忽略所有的注解。若不配置该属性,或者将其设置为 false,则表示启用注解支持。
  • 在这里插入图片描述
  • 由于 metadata-complete 属性的默认值是 false,即默认启用 Servlet 注解支持,所以默认情况下,使用该注解时,不必创建 web.xml 文件。

3. 使用@WebServlet注解

@WebServlet 属于类级别的注解,标注在继承了 HttpServlet 的类之上。常用的写法是将 Servlet 的相对请求路径(即 value)直接写在注解内,如下所示。

//完整写法:
@WebServlet(​urlPatterns = "/MyServlet")//简写:
@WebServlet("/MyServlet")  

服务器具体的操作,就看是去调用哪个方法了

3. 请求HttpServletRequest

1. http协议

  • 超文本传输协议(HyperText Transfer protocal)
  • 运行在tcp协议上的一次请求和响应协议,指定了客户端给服务器发送or得到的消息

2. 特点

	    1.基于tcp协议
	    2.缺省端口80,https基于http协议的基础上再次加密,缺省端口是443
	    3.基于请求-响应模型:一次请求一定对应一次响应;请求和响应都存在的时候才可以叫做一次完整的http请求
	    4.无状态:请求之间是相互独立的,不能互相交互数据`

3. 请求消息格式

  1. 请求行
  • 格式:请求方式 请求url 请求协议/版本
  • 请求方式
  •   Get: 1.参数会直接显示在请求行中,会在url后面暴露出来
      		2.相对不安全,效率更高一些
      		3.因为url的长度是有限的,类型为字符串
      			Chrome的url长度是8182个字符,超过后就返回错误
      			IE的长度限制2083,超过以后就自动截断(如果使用form那么提交按钮就不会起效果)
      			Apache 服务器 接收长度限制为8192
      			tomcat 通过配置Connector的maxParamterCount属性去配置长度,默认值是10000
      				maxPostSize post请求的最大值
      			nginx 服务器 可以通过修改配置来改变url请求的长度限制
      			client_header_buffer_size 默认值为1K
      			large_client_header_buffers 默认值是8k
    
  •   POST:  1.参数在请求体中
      		 2.请求url长度和get一样,因为参数不在url中,所以参数大小无限制,参数类型无限制(文件上传的时候选择post请求)
      		 3.相对安全,效率相对低一些
    
  1. 请求头
    浏览器告诉服务器的一些信息
    请求头名称:请求头的值
    能够接收的数据类型
    在这里插入图片描述

  2. 请求体
    就是封装post请求的参数

3.1 请求转发forword

  1. 是一种服务器内部实现页面跳转的方式
  2. 浏览器不知道服务器内部发生了什么,所以地址栏不会被改变
  3. 转发达到目标资源后,目标资源将其进行处理,最后响应返回给浏览器
  4. 整个过程只有一次请求和转发,是一次完整的http请求
       //获取请求转发器,参数就是需要转发到的目的地
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/my");
        //执行转发
        requestDispatcher.forward(request,response);
  1. 数据通过域对象(作用域)来共享的
  2. request(作用域):
  • 只在一次http请求中可以共享数据
//需要将数据放入作用域中
 request.setAttribute("list",list);
//java代码
 List<User> list = (List<User>) request.getAttribute("list");
//移除指定的数据
request.removeAttribute("list");
        //获取作用域中所有key的名称 可以通过遍历获取作用域中的所有数据
Enumeration<String> attributeNames = request.getAttributeNames();
  • 注意:request作用域只能作用在同一个请求中,不同的请求中是不能共享数据的

3.2 请求乱码处理

客户端发送中文到服务器后,服务器接收到中文可能出现乱码的情况

//get请求乱码
filename = new String(filename.getBytes("ISO-8859-1"),"UTF-8");
// post请求 乱码 这句话必须放在获取参数之前
request.setCharacterEncoding("UTF-8");

4. 响应HttpServletResponse

4.1 基本介绍

将服务器的消息响应给浏览器
1. 响应行

  • 协议/版本 响应状态码 状态码描述
    HTTP/1.1 200 ok
  • 响应状态码
    服务器发送给客户端用来描述这次请求的一个数字。状态码一般是3位数
    1. 1xx 服务器接收到客户端的消息,但是还没有接收完成,等待一段时间后,发送多个1xx的代码
    2. 2xx 表示成功 常见200
    3. 3xx 表示请求的资源已经转移到新的地方,需要客户端去访问新的地址 常见302(资源被临时转移) 301(资源被永久转移) 304(资源被缓存)
    4. 4xx 表示客户端的请求错误 常见404(资源未找到) 403(请求参数错误) 405(请求方式错误)
    5. 5xx 服务器错误 常见500(服务器内部错误)

2. 响应头
响应头名称:响应头的值

常见的响应头:
Content-Length: 836 内容长度
Content-Type: text/html; utf-8=;charset=UTF-8 内容类型
Date: Wed, 06 Apr 2022 02:30:35 GMT  响应时间
Server: Apache-Coyote/1.1 服务器
Set-Cookie: JSESSIONID=04FDEF35B648BDC71D4E4544BDB96439; Path=/webtest2/; HttpOnly 响应的cookie

Location: 重定向以后的地址
    Content-Disposition: 告诉浏览器响应的内容以什么方式打开
	in-line: 默认值,直接在当前页打开
	attachment;filename=xxxx  告诉浏览器响应的内容包含了附件 附件名为xxxx 需要以文件下载的方式打开
    cache-control: 缓存控制 no-cache 不需要缓存
    Refresh: 刷新界面 Refresh:5;url=xxxx 5s后跳转到url指定的路径上去
从上面可以观察到,响应头可以控制浏览器的一部分行为

3. 响应体
服务器响应给客户端的数据

4.2 response对象

这个对象主要就是针对服务器对客户端的响应进行封装的,用doGet举例:

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("myServlet");
        //服务器响应的数据乱码,加这一句就可以解决
        response.setContentType("text/html;charset=utf-8");//设置响应的数据类型
        //重定向
        /*response.sendRedirect("https://www.baidu.com");//服务器外部
        response.setStatus(302);
        response.setHeader("Location","https://www.baidu.com");
        //服务器内部  前面从项目名开始去进行访问
        response.sendRedirect("/webtest2/user/aaa?a=b");*/

        //缓存控制
        response.setHeader("Cache-Control","no-cache");
        response.setHeader("Pragma","no-cache");
        //IE 缓存1小时 如果不缓存就直接写0
        response.setDateHeader("Expires",System.currentTimeMillis() + 1000 * 60 * 60);

        //获取两个输出流 两个流不能同时使用
        PrintWriter writer = response.getWriter();//字符流
        ServletOutputStream outputStream = response.getOutputStream();//字节流

        boolean b = response.containsHeader("");//判断是否包含某个头
//        response.encodeRedirectUrl("")//URL重写
        Collection<String> headerNames = response.getHeaderNames();//获取所有响应头名称
    }

其实就是服务器要响应东西给浏览器的时候,就用response这个对象去调用对应想要的方法传过去即可,同时需要注意代码中的注释部分

4.3 重定向

  1. 服务器收到浏览器的请求,检查后发现资源被转移,所以就会响应302或者location回去
  2. 客户端收到了302和location的值后,就会去访问新的地址
  3. 浏览器是知道地址栏要改变
  4. 请求至少两次
  5. 可以访问服务器外部资源
response.sendRedirect("https://www.baidu.com");//服务器外部
        response.setStatus(302);
        response.setHeader("Location","https://www.baidu.com");
        //服务器内部  前面从项目名开始去进行访问
        response.sendRedirect("/webtest2/user/aaa?a=b");

4.4 请求转发和重定向区别

  • 请求转发:只有一次请求一次响应,浏览器地址栏不会改变,不能请求外部资源
  • 重定向:至少两次请求,地址栏要改变,可以请求外部资源

前后端数据禁止显示js语句,只是文本
将关键字给用&lt;关键字&lt;来括号起来
在这里插入图片描述
con
+
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值