javaWeb快速入门学习记录 2021-09-29

学习方向

  • 快速学习数据库软件navicat、Sqlyog的安装,掌握数据库基本的增删改查语法

    • 数据库管理软件:

      1. navicat
      • 官方下载地址:https://www.navicat.com.cn/products
      • https://www.bilibili.com/video/BV1JK411V7bQ
      1. Sqlyog
      • 官方下载地址:https://sqlyog.en.softonic.com/
  • IDEA散记:

    调用方法之后,在末尾写.var可以自动添加返回值类型和返回值变量,方便快捷编码

  • javaEE7帮助文档:https://gitee.com/Kevin_Hunter/picgo/tree/master/

  • 快速学习服务器软件tomcat的安装和项目部署,连接IDEA

  • 软件架构
    B/S 浏览器/服务器
    C/S 客户端/服务器

  • 服务器软件:

    • tomcat
      • 官方下载地址:https://tomcat.apache.org/ 下载压缩包解压到目录即可完成安装
  • Servlet快速入门

  • 浏览器访问服务器:

    • 常规浏览器搜索框直接访问服务器是Get请求,url会携带参数
    • <form> 表单形式指定method="post"可以发送post请求,参数会存放在请求体(正文)
  • MarkDown编辑软件:

    • Typora的下载地址:https://www.typora.io/
  • 图片管理软件:

    • PicGo下载地址:https://github.com/Molunerfinn/PicGo/releases/tag/v2.3.0

    • 搭配Gitee配置云图库教程:https://blog.csdn.net/qq_40683225/article/details/105124810

    • 配置步骤:

        1. 设置Typora:

          image-20211002004523374

        1. 下载gitee图片上传插件(搜索gitee):

          image-20211002004228475

        1. 在PicGo中设置gitee:

Servlet

一、概念:

全称 sever applet, 运行在服务器端的小程序

Servlet就是一个接口,定义了java类被浏览器访问到(tomcat识别)的规则
将来自定义一个类,实现Servlet接口,复写方法实现功能

二、Servlet快速入门

1.创建JavaEE项目
2.定义一个类,实现Servlet接口
3.实现接口中的抽象方法
4.配置Servlet

三、Servlet执行原理

  1. 当服务器接受客户端浏览器的请求之后,会解析请求URL路径,获取访问的Servlet的资源路径
  2. 查找web.xml文件,看是否有对应的<url-patton>的标签体内容
  3. 如果有,则再查找到对应的<servlet - class>全类名
  4. tomcat会将字节码文件加载进内存,并且创建其对象
  5. 再调用类中的方法

四、Servlet的生命周期

常用:

1. 被创建:

执行init()方法,只执行一次,一般用于加载资源
要点:Servlet方法什么时候被创建?
默认情况下,第一次被访问时,Servlet被创建
但是可以通过配置,来控制Servlet被创建的时机

  • 配置方法
    在web.xml文件下的<servlet></servlet>标签中配置
    (1).当<load-on-startup></load-on-startup>标签中的值为负数时(默认),第一次被访问时,Servlet对象被创建
    (2).当<load-on-startup></load-on-startup>标签中的值为0或者正整数时,服务器启动时i,Servlet对象被创建

  • 注意事项
    Servlet的init方法只被调用一次,说明只有一个Servlet在内存中只存在一个对象,Servlet是单例的
    多个用户同时访问时,可能存在线程安全问题

  • 解决方法
    尽量不要在Servlet中定义成员变量,即是定义了,也不要修改成员变量,可以定义方法中的临时局部变量,以此避免并发数据安全问题

2. 提供服务:

执行server方法,每次调用都执行一次
每次访问Servlet时,server方法都会被执行一次

3. 被销毁:

执行destroy方法,只执行一次
Servlet被销毁时执行。服务器关闭时,Servlet会被销毁
只有服务器正常关闭时,才会执行destroy()方法
destroy()方法在Servlet销毁前被执行,一般用户释放资源

不常用:

1.getServletConfig()方法:

用于获取ServletConfig对象
方法返回值为:ServletConfig(Servlet的配置对象)

2.getServletInfo()方法:

用于获取Servlet的一些版本、作者等信息

方法返回值为:String(Servlet的版本信息)

五、Servlet的体系结构

一、父子接口关系

Servlet — 接口
| 继承
GenericSeverlet – -抽象类,继承了Servlet类
| 继承
HttpServlet —抽象类,继承了GenericServlet类

  • GenericServlet : 将Servlet接口中其他的方法做了默认空实现,只将常用的server()方法作为抽象

    将来定义Servlet类时,可以继承GeneriServlet类,直接实现service()方法即可

  • HttpServlet : 对浏览器访问服务器的请求方式进行了判断的封装,如果是GET请求,则调用doGet()方法;如果是POST请求,则调用doPost()方法

    将来定义Servlet类时,可以继承HttpServlet类,只需要复写doGet()或者doPost()方法即可

二、Servlet3.0注解配置:

urlpartten: Servlet访问路径

一个Servlet可以有多个访问路径:@WebServlet({"/虚拟路径1", “虚拟路径2”,“虚拟路径3”}),可以由多个路径进行访问

三、路径定义规则:

/xxx: 路径匹配(常规)

/xxx/xxx/xxx: 多层路径,虚拟路径,目录结构

*号代表任意,前面不加/号,否则报错

例如:

①. @WebServlet("/demo/*") 服务器访问url: `localhost/demo/任意路径

②. WebServlet(/*) 服务器访问url;localhost/任意路径 访问的优先级别最低,如果能访问到其他资源,则不会访问此路径的资源

③. @WebServlet("*.do") 服务器访问url:localhost/任意路径.do do为拓展名,可自定义

HTTP

一、概念:

Hyper Text Tranfer Protocol 超文本传输协议

HTTP请求总共有7种方式,常用的有GET请求和POST请求

  • GET请求:

    1. 请求参数在请求的请求行中 在url后
    2. 请求的url长度有限制(文件传输较大,长度超过限制)
    3. 相对不安全
  • POST请求:

    1. 请求参数在请求体中
    2. 请求的url长度没有限制(可用于文件传输)
    3. 相对安全

二、传输协议 :

定义了客户端和服务端通信时,发送数据的格式

三、特点 :

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

  2. 默认端口号为 : 80

  3. 基于请求/响应模型的:一次请求,一次响应

  4. 无状态的:请求与请求之间是相互独立的,不能交互数据

四、历史版本:

版本1.0(每一次请求,响应都会建立一次连接)

版本1.1 (可以复用连接,多次请求响应,同用一次连接)

五、请求消息格式

1、请求行

  • 请求方式 请求url 请求协议/版本

    GET /localhost/login.html HTTP/1.1

2、请求头

  • 请求头名称 :请求头值(值如果有多个,可以用逗号隔开)

  • 常见的请求头

    1. User-Agent : 携带浏览器的版本信息,服务器可以通过获取浏览器的版本信息,解决浏览器数据兼容性问题
    2. Accept: 浏览器可以响应的文件格式
    3. Accept-Language:浏览器支持的语言
    4. Accept-Encoding :浏览器支持的压缩格式
    5. `Reffer(重要)``
    6. ``Connection`:标识连接是否还在
    7. Upgrade-Insecure-Requests:升级信息
  • 请求头中的Reffer:http:/localhost/login.html

    • 作用:告诉服务器,当前请求从哪里来

      1. 防止盗链

        image-20211002010550798

      2. 统计工作

3、请求空行

  • 空行(用于分隔请求头和请求体)

4、请求体

只有当请求方式为POST时才有请求体GET方式没有请求体

  • 参数名1=参数值1&参数名2=参数值2&…

5、请求数据示例:

POST /login.html HTTP/1.1   //1.请求行
/*2.请求头开始*/
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://localhost/login.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1
/*请求头结束*/
						//3.请求空行
username=zhangsan		//4.请求体

六、响应消息格式

1. 概念:

image-20211002013739947

  • 请求响应流程:

1.浏览器发送请求之后,tomcat服务器会根据请求url中的资源路径,创建对应的Servlet类的对象

2.tomcat服务器还会将请求数据封装成对象,创造request对象和response对象,request对象封装了请求中的消息数据

3.tomcat将request对象和response对象传给service()方法,并且调用service()方法

4.程序员则可以在service()方法中通过request对象获取请求的消息数据,再通过response对象设置响应消息数据

5.服务器在给浏览器做出响应之前,会从response对象中解析程序员写的response对象中的响应消息数据

2.知识点:

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

  1. resquest对象和resopnse对象是由服务器创建的,我们只是使用它们
  2. resquest对象是用来获取请求消息,response对象是用来设置响应消息

2、request对象的继承体系结构:

ServletRequest --接口

| 继承

HttpServletRequest —接口

| 继承

org.apache.catalina.connector.RequestFacade@17d6087b 类(tomcat的开源的类)

  • Servlet类中的service()方法中有ServletRequest对象
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

}
  • HttpServlet类中的doGet()方法和doPost()方法中有HttpServletRequest对象

    打印出HttpServletRequest对象的值:org.apache.catalina.connector.RequestFacade@17d6087b

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String protocol = req.getProtocol();
    String msg = lStrings.getString("http.method_get_not_supported");
    if (protocol.endsWith("1.1")) {
        resp.sendError(405, msg);
    } else {
        resp.sendError(400, msg);
    }
}

3、request的功能:

获取请求消息数据:
①、获取请求行数据:
  • GET /localhost/login.html?userName=zhangsan HTTP/1.1

    • 请求方式 主机地址/虚拟路径/Servlet类的路径?参数
  • 方法:

    • 1. 获取请求的方式:GET

      String getMethod()

    • *2. (重要)获取虚拟目录:/

      String getContextPath()

      image-20211002093416951

    • 3. 获取Servlet路径:/login.html

      String getServletPath()

    • 4. 获取请求参数:userName=zhangsan

      String getQueryString()

    • *5. (重要)获取请求URI:/login.html

      String getRequestURI()

      • 统一资源标识符(范围相对较大,限制相对较少)
    • 6. 获取请求URL: http:localhost/login.html

      StringBuffer getRequestURL()

      • 统一资源定位符
    • 7. 获取协议及版本:HTTP/1.1

      String getProtocol()

    • 8. 获取客户机的IP地址:

      String getRemodeAttr()

    代码示例:

浏览器中访问的地址:http://localhost/demo4

@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        1.获取请求的方式
        String method = req.getMethod();
//        2.获取请求的虚拟路径
        String contextPath = req.getContextPath();
//        3.获取请求的Servlet路径
        String servletPath = req.getServletPath();
//       4.获取请求的参数
        String queryString = req.getQueryString();
//        5.获取请求的URI
        String uri = req.getRequestURI();
//        6.获取请求的URL
        StringBuffer url = req.getRequestURL();
//        7.获取请求的协议和版本
        String tip = req.getProtocol();
//        8.获取主机地址
        String addr = req.getRemoteAddr();
//        打印
        System.out.println("请求方式-->" + method);
        System.out.println("虚拟路径-->" + contextPath);
        System.out.println("请求参数-->" + queryString);
        System.out.println("URI-->" + uri);
        System.out.println("URL-->" + url);
        System.out.println("版本协议-->" + tip);
        System.out.println("主机地址-->" + addr);
    }
}
输出:
    
请求方式-->GET
虚拟路径-->
请求参数-->null
URI-->/demo4
URL-->http://localhost/demo4
版本协议-->HTTP/1.1
主机地址-->0:0:0:0:0:0:0:1

image-20211002104850992

②、获取请求头数据:
  • 方法:

    • (*常用*)String getHeader(String name):通过请求头的名称获取请求头的值

    • Enumeration<String> req.getHeaderNames():获取请求头信息的类(接口)

      类中定义了两个方法:

      hasMoreElements():检测此枚举对象是否有更多元素

      nextElement():如果此枚举对象至少有一个要提供的元素,则返回此枚举的下一个元素

    代码示例:

    @WebServlet("/demo3")
    public class ServletDemo3 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        获取所有请求头的名称
            Enumeration<String> headerNames = req.getHeaderNames();
            System.out.println("请求头中所有请求头的名称-->" + headerNames);
    //        遍历所有请求头
            while (headerNames.hasMoreElements()) {
    //            获取一个请求头的名称
                String headerName = headerNames.nextElement();
    //            根据请求头的名称获取请求头的值
                String headerValue = req.getHeader(headerName);
    //            打印请求头的名称和请求头的值
                System.out.println("请求头 " + headerName + " 的值为 " + headerValue);
            }
        }
    }
    
    输出:
    
    请求头中所有请求头的名称-->org.apache.tomcat.util.http.NamesEnumerator@676a55e8
    请求头 host 的值为 localhost
    请求头 connection 的值为 keep-alive
    请求头 sec-ch-ua 的值为 "Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"
    请求头 sec-ch-ua-mobile 的值为 ?0
    请求头 sec-ch-ua-platform 的值为 "Windows"
    请求头 upgrade-insecure-requests 的值为 1
    请求头 user-agent 的值为 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36
    请求头 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.9
    请求头 sec-fetch-site 的值为 none
    请求头 sec-fetch-mode 的值为 navigate
    请求头 sec-fetch-user 的值为 ?1
    请求头 sec-fetch-dest 的值为 document
    请求头 accept-encoding 的值为 gzip, deflate, br
    请求头 accept-language 的值为 zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6
    请求头 cookie 的值为 JSESSIONID=4605D1FB1B7640954F8E9C9585201EF9
    
  • 较常用法:

    • 根据版本信息在代码中判断再进行逻辑编写,以此解决浏览器兼容性问题

    image-20211002124456121

    • 获取请求头中的reffer数据,标识当前请求从哪个链接发出,如果从浏览器中直接输入发送的请求,则返回值为null
    @WebServlet("/demo5")
    public class ServletDemo5 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String reffer = req.getHeader("reffer");
            System.out.println("请求从哪里发出-->"+reffer);
        }
    }
    

浏览器输入:http://localhost/demo5 发送请求

以下代码输出:请求从哪里发出–>null

reffer作用(防盗链):https://segmentfault.com/a/1190000024540592

③、获取请求体(正文)数据:
  • 请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数

  • 步骤

      1. 获取流对象

        • 获取字符输入流:BufferedReader getReader()方法 获取字符输入流,只能操作字符

          image-20211002140155989

        • 获取字节输入流:ServletInputStream()方法 获取字节输入流,可以操作所有类型数据(主要用于文件上传)

          image-20211002140543830

      2. 再从流对象中拿数据

        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("post");
            //        获取请求消息体
        
            //        1.获取字符流
            BufferedReader reqReader = req.getReader();
            //        2.读取数据
            String line = null;
            while((line = reqReader.readLine()) != null){
                System.out.println(line);
            }
        }
        

        image-20211002142045739

        点击注册后服务器端输出:
            
        post
        username=Kevin&password=123
        
其他功能:
①、获取请求参数的通用方式:

由于GET请求的参数在url中,并且其请求体中没有参数,所有只能通过req.getQueryString()方法获取参数字符串,而POST请求的参数在请求体中,一般是通过req.getReader()方法获取参数字符串的,所有存在不统一的问题,以下几个方法在GET和POST请求中通用,都可以获取到参数的值,更为常用

image-20211002143227549

  • String getParameter(String name): 根据参数名称获取参数值 username=Kevin&password=123
  • Enumeration<String> getParameterNames(String name):获取所有参数的名称
  • String[] getParameterValues(String name):根据参数名称获取参数值的数组 hobby=xx&hobby=yy
  • Map<String, String[]> getParameterMap():获取所有参数的map集合
@WebServlet("/demo7")
public class ServletDemo7 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        设置流的编码
        req.setCharacterEncoding("utf-8");
//        System.out.println("post");
        获取单个参数的值(字符串)
//        String username = req.getParameter("username");
//        System.out.println("用户名-->"+username);

//        根据参数名称获取参数值的数组
//        String[] values = req.getParameterValues("hobby");
//        for(String item:values){//遍历数组
//            System.out.println(item);//输出每一项的值
//        }

//        获取所有参数的名称
//        Enumeration<String> parameterNames = req.getParameterNames();
//        while(parameterNames.hasMoreElements()){
//            String item = parameterNames.nextElement();
//            System.out.println(item);
//            String value = req.getParameter(item);
//            System.out.println(value);
//            System.out.println("-----------------");
//        }

//        获取所有参数的map集合(泛型)
        Map<String, String[]> parameterMap = req.getParameterMap();
        Set<String> keyset = parameterMap.keySet();
        for (String name : keyset) {

//            根据键来获取值
            String[] values = parameterMap.get(name);
            System.out.println(name);
            for (String value : values) {
                System.out.println(value);
            }
            System.out.println("----------------");
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        System.out.println("get");
//        String username = req.getParameter("username");
//        System.out.println("用户名-->" + username);
        this.doPost(req, resp);//逻辑通用,简化代码
    }
}
  • 请求参数的中文乱码问题:

GET请求方式中,tomcat已经将get方式的中文乱码问题解决了

POST请求方式中,参数中如果有中文,则会出现乱码问题

//解决:在获取参数前,设置request的编码格式
//        设置流的编码
req.setCharacterEncoding("utf-8");
②、请求转发:
1. 概念:
  • 一种在服务器内部资源跳转的方式
2.步骤:
  • 通过request对象获取请求转发器对象,RequestDispatcher getRequestDispatcher(String path)
  • 使用RequestDispatcher对象进行转发:forward(HttpServletRequest req, HttpServletResponse resp)
常用写法:
req.getRequestDispatcher("/demo9").forward(req, resp);
3.特点:
  • 转发时,浏览器地址栏路径不发生变化
  • 只能转发到当前服务器内部的资源中
  • 转发虽然有资源跳转,但只是一次请求
③、共享数据:
  • 域对象:一个有作用范围的对象,可以在范围内共享数据

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

  • 方法:(在转发之前将数据存储到request域中,转发之后在新的类中获取数据)

    1. void setAttribute(String name, Object obj):存储数据

    2. Object getAttribute(String name, Object obj):获取数据

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

④、获取ServletContext:
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值