Request+Response

1.目标

1.使用request对象接收来自客户端浏览器的请求数据。
2.使用response对象响应数据给浏览器客户端。
3.使用注解开发servlet。

2.绝对路径(掌握)

前端页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--
  TODO:绝对路径
    1.带网络三要素的绝对路径:http://127.0.0.1:8080/pathAbso
    2.省略网络三要素的绝对路径:只能访问当前服务器。/pathAbso 不能省略/
-->
<a href="http://127.0.0.1:8080/pathAbso">带网络三要素的绝对路径</a><br>
<a href="/pathAbso">不带网络三要素的绝对路径</a><br>
</body>
</html>

servlet类:

package com.itheima.sh.a_servlet_01;

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

public class PathDemo01Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("绝对路径  get");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("绝对路径  post");
    }
}

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_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>PathDemo01Servlet</servlet-name>
        <servlet-class>com.itheima.sh.a_servlet_01.PathDemo01Servlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>PathDemo01Servlet</servlet-name>
        <url-pattern>/pathAbso</url-pattern>
    </servlet-mapping>
</web-app>

浏览器访问:

3.相对路径(掌握)

web阶段的相对路径相对的不是当前项目,相对的是当前url地址栏。

demo02.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--
  TODO:相对路径 相对当前url地址栏的
    1.我们在浏览器地址栏上访问的页面是: http://localhost:8080/demo02.html。
       而在该页面中访问servlet的地址是:http://localhost:8080/pathAbso2
       对于当前页面而言,pathAbso2即servlet类的地址和demo02.html是同一级目录,因此在/demo02.html页面如果使用相对路径访问那么
       可以书写:./pathAbso2   .表示当前路径可以省略,省略后:pathAbso2 
-->
<a href="./pathAbso2">相对路径</a><br>
<a href="pathAbso2">相对路径</a><br>
</body>
</html>
package com.itheima.sh.a_servlet_01;

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

public class PathDemo02Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("相对路径。。。。PathDemo02Servlet");
    }

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

    }
}
<servlet>
        <servlet-name>PathDemo02Servlet</servlet-name>
        <servlet-class>com.itheima.sh.a_servlet_01.PathDemo02Servlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>PathDemo02Servlet</servlet-name>
        <url-pattern>/pathAbso2</url-pattern>
    </servlet-mapping>

demo03.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--
  TODO:相对路径 相对当前url地址栏的
   2.需求:在demo03.html页面访问pathAbso3的servlet类
        在浏览器地址栏上访问的静态资源路径是:http://localhost:8080/aaa/demo03.html
        那么我们要访问的Servlet路径是:    http://localhost:8080/pathAbso3
        在demo03.html使用相对路径访问pathAbso3的相对路径写法是:../pathAbso3
        针对http://localhost:8080/aaa/demo03.html 页面我们这里使用..表示demo03.html的上一级目录即http://localhost:8080/aaa
        然后在aaa同一级目录下查找pathAbso3
-->
<a href="../pathAbso3">相对路径</a><br>
</body>
</html>
package com.itheima.sh.a_servlet_01;

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

public class PathDemo03Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("相对路径。。。。PathDemo03Servlet....");
    }

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

    }
}
<servlet>
        <servlet-name>PathDemo03Servlet</servlet-name>
        <servlet-class>com.itheima.sh.a_servlet_01.PathDemo03Servlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>PathDemo03Servlet</servlet-name>
        <url-pattern>/pathAbso3</url-pattern>
    </servlet-mapping>

web阶段的相对路径相对的是浏览器url地址栏。

. 表示当前路径,可以省略

.. 表示上一级路径。

4.Servlet3.0注解开发 (掌握)

我们之前都是servlet2.5使用的是xml开发,弊端是在web.xml中进行配置会导致配置冗余并且麻烦。从servlet3.0开始我们引入注解开发,主要简化代码开发的。因此要求导入的servlet依赖必须是servlet3.0之后

<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
</dependency>

注解开发实现:

1.导入依赖:

<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
</dependency>

2.在包上右键====》new ===>servlet(create servlet)

package com.itheima.sh.b_anno_servlet_02;

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

@WebServlet("/annoDemo01Servlet")
public class AnnoDemo01Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("注解开发...简单");
    }
}

5.Servlet3.0注解开发注意事项 (掌握)

package com.itheima.sh.b_anno_servlet_02;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
    TODO:
        1.注解开发使用的注解是 @WebServlet
        2.@WebServlet注解常见的属性是:
            1)String name() default ""; 相当于web.xml中的 <servlet-name></servlet-name> 不写
                name="AnnoDemo01Servlet" ====><servlet-name>AnnoDemo01Servlet</servlet-name>
            2)String[] urlPatterns() default {}; 相当于web.xml中的<url-pattern></url-pattern>
                回顾:
                    I:使用注解的时候,如果注解的属性是数组,那么我们使用的时候只给属性一个值,此时可以省略{}
            3)String[] value() default {}; 该属性等价于urlPatterns属性,定义该属性的目的就是为了简化代码书写。
            在使用注解的时候关于属性名是value是可以省略的
                回顾:
                    I:如果注解中只有一个属性是value,那么可以省略
                    II:如果注解中有多个属性,并且每个属性都有默认值,此时在给value赋值的时候可以省略value,如果除了给value
                    赋值还有其他属性赋值不能省略value
 */
//@WebServlet(urlPatterns={"/annoDemo01Servlet"},name="AnnoDemo01Servlet")
//@WebServlet(urlPatterns={"/annoDemo01Servlet","/annoDemo02Servlet"},name="AnnoDemo01Servlet")
//@WebServlet(value="/annoDemo01Servlet",name="AnnoDemo01Servlet")
@WebServlet("/annoDemo01Servlet")//这里给value赋值
public class AnnoDemo01Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("注解开发...简单");
    }
}

6.在idea中配置Servlet3.0注解开发的模板 (掌握)

#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
@javax.servlet.annotation.WebServlet("/${Entity_Name}")
public class ${Class_Name} extends javax.servlet.http.HttpServlet {
    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {
        doGet(request,response);
    }

    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {

    }
}

7.HTTP协议

1.介绍

超文本传输协议。是互联网行传输数据的一种规范。

2.浏览器抓包观察请求报文协议(必须会)

1.在浏览器中按f12

2.

3.

8.request请求对象和response响应对象初体验

package com.itheima.sh.c_http_request_03;

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

@WebServlet("/requestAndResponseDemo01Servlet")
public class RequestAndResponseDemo01Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //TODO:request对象处理客户端浏览器的请求数据
        String username = request.getParameter("username");
        System.out.println("username = " + username);

        //TODO:response响应数据给浏览器的
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print("程序员");
    }
}

9.request对象的继承关系 掌握

1.HttpServletRequest 接口继承了ServletRequest 接口,对父接口进行扩展,可以处理满足所有http协议的请求。

2.HttpServletRequest 和 ServletRequest都是接口,不能创建对象,因此在tomcat底层定义实现类并创建实现类对象:

public class RequestFacade implements HttpServletRequest  {}

tomcat底层创建门面类RequestFacade对象

ServletRequest  request = new RequestFacade(); 多态

10.请求行的方法(掌握)

package com.itheima.sh.d_request_04;

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

@WebServlet("/requestRowDemo01Servlet")
public class RequestRowDemo01Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取请求方式: GET   String getMethod()
        System.out.println(request.getMethod());
        //2.获取虚拟目录(项目访问路径):  String getContextPath()  就是我们在tomcat配置的位置设置的路径,是虚拟的,就是随便定义
        //如果设置虚拟路径位置是/那么该方法获取的内容是空字符串
        System.out.println(request.getContextPath());//""
        //3.获取URL(统一资源定位符): http://localhost:8080/request-demo/req1
        //StringBuffer getRequestURL() 获取的是请求资源的绝对路径(含三要素)
        //StringBuilder 和  StringBuffer都表示字符串缓冲区,字符可以改变 。StringBuilder多线程不安全 效率高
        //StringBuffer多线程安全 效率低
        StringBuffer sb = request.getRequestURL();
        String s = sb.toString();
        //  http://localhost:8080/day16/requestRowDemo01Servlet
        System.out.println("s = " + s);
        //4.获取URI(统一资源标识符): /request-demo/req1
        //String getRequestURI() 获取的是请求资源的绝对路径(不含三要素)
        //  /day16/requestRowDemo01Servlet
        System.out.println(request.getRequestURI());
        //5.获取请求参数(GET方式): username=zhangsan&password=123  了解
        //String getQueryString()
        System.out.println(request.getQueryString());//"username=suoge&pwd=1234"
    }
}

1.获取请求方式: GET String getMethod()。

2.获取虚拟目录(项目访问路径): String getContextPath()。

3.StringBuffer getRequestURL() 获取的是请求资源的绝对路径(含三要素) 获取URL。

4.String getRequestURI() 获取的是请求资源的绝对路径(不含三要素) 获取URI。

11.获取请求头的方法(掌握)

package com.itheima.sh.d_request_04;

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

@WebServlet("/requestHeaderDemo02Servlet")
public class RequestHeaderDemo02Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       /*
            String getHeader(String name) 参数name书写的是请求头冒号左边的内容例如:User-Agent
        */
        //需求:获取请求头key是User-Agent的值
        String header = request.getHeader("User-Agent");
        //Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
        System.out.println("header = " + header);
    }
}

12.获取请求体数据 掌握

package com.itheima.sh.d_request_04;

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

@WebServlet("/requestBodyDemo03Servlet")
public class RequestBodyDemo03Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       /*
           1.获取请求体数据的方法:
            1)ServletInputStream getInputStream()该方法可以获取字节和字符数据
            2)BufferedReader getReader() 获取字符数据
        */
        //1.获取输入流对象
        BufferedReader reader = request.getReader();
        //2.使用字符缓冲流读取字符数据
        String line=null;
        while((line= reader.readLine())!=null){
            System.out.println(line);//"username=zhangsan&pwd=123"
        }
        //这里不用单独释放IO流了,因为reader对象使用request获取,只要request对象销毁,流关闭
    }
}

13.获取请求参数的通用方式(很重要)

1.问题

根据上述API的讲解,我们发现如果是get请求,获取请求参数使用的API是:

String getQueryString()

如果是post请求,获取请求参数的API是:

1)ServletInputStream getInputStream()该方法可以获取字节和字符数据
2)BufferedReader getReader() 获取字符数据
package com.itheima.sh.d_request_04;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

@WebServlet("/requestDemo05Servlet")
public class RequestDemo05Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
            获取请求参数的通用方式:
                1.Map<String,String[]> getParameterMap() 获取所有的请求参数。
                    抓包冒号左边的作为map集合的key,冒号右边的值作为map集合的value
               2.String[] getParameterValues(String name) 获取指定的值。参数是抓包冒号左边的标识。获取的值放到数组中
               3.String getParameter(String name)获取指定的值。 参数是抓包冒号左边的标识
                    注意:如果参数的name有多个值谁在前面先获取谁

                    抓包结果:
                        username: zhangsan
                        password: 1234
                        hobby: 1
                        hobby: 2
         */
        /*
             1.Map<String,String[]> getParameterMap() 获取所有的请求参数。
                    抓包冒号左边的作为map集合的key,冒号右边的值作为map集合的value
         */
        Map<String, String[]> map = request.getParameterMap();
        //jdk8遍历map
        map.forEach((key,value)->{
            System.out.println(key+"---"+ Arrays.toString(value));
        });

        /*
             2.String[] getParameterValues(String name) 获取指定的值。参数是抓包冒号左边的标识。获取的值放到数组中
         */
        //参数username是是抓包冒号左边的标识===》 username: zhangsan
        String[] usernames = request.getParameterValues("username");
        System.out.println(Arrays.toString(usernames));


        /*
              3.String getParameter(String name)获取指定的值。 参数是抓包冒号左边的标识
                    注意:如果参数的name有多个值谁在前面先获取谁
         */
        //参数username是是抓包冒号左边的标识===》 username: zhangsan
        String username = request.getParameter("username");
        System.out.println("username = " + username);

        String hobby = request.getParameter("hobby");
        System.out.println("hobby = " + hobby);
    }
}

14.解决post请求乱码问题 掌握

从tomcat8开始,对get请求已经解决了中文乱码问题。对于post请求没有解决中文乱码问题。需要我们使用代码解决。

【1】产生乱码的原因以及解决乱码分析

【2】代码实现

package com.itheima.sh.d_request_04;

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

@WebServlet("/requestDemo06Servlet")
public class RequestDemo06Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
           TODO:解决post请求中文乱码
             1.使用request对象调用方法 request.setCharacterEncoding("UTF-8");//告知tomcat使用UTF-8解码
                注意:是解决请求体数据的乱码的。是解决post乱码的
             2.使用javase的API解决
                编码:URLEncoder类中的静态方法static String encode(String s, String enc)  s:编码的字符串  enc 表示编码表
                解码:URLDecoder类中的静态方法static String decode(String s, String enc)   s:解码的字符串  enc 表示编码表
             3.使用javase的API解决即String类
               编码:URLEncoder类中的静态方法static String encode(String s, String enc)  s:编码的字符串  enc 表示编码表
               解码:URLDecoder类中的静态方法static String decode(String s, String enc)   s:解码的字符串  enc 表示编码表
         */
        //TODO:1.使用request对象调用方法
//        request.setCharacterEncoding("UTF-8");//告知tomcat使用UTF-8解码
        //获取数据
        String username = request.getParameter("username");//username: 锁哥
//        System.out.println("username = " + username);

        //TODO:2.使用javase的API解决
        /*
            编码:URLEncoder类中的静态方法static String encode(String s, String enc)  s:编码的字符串  enc 表示编码表
            解码:URLDecoder类中的静态方法static String decode(String s, String enc)   s:解码的字符串  enc 表示编码表
         */
        // 编码:URLEncoder类中的静态方法static String encode(String s, String enc)  s:编码的字符串  enc 表示编码表
        //username = URLEncoder.encode(username, "ISO-8859-1");
        //解码:URLDecoder类中的静态方法static String decode(String s, String enc)   s:解码的字符串  enc 表示编码表
        //username = URLDecoder.decode(username, "UTF-8");

        //TODO:3.使用javase的API解决即String类
         /*
            编码:String类中的非静态方法byte[] getBytes(String charsetName) 参数表示编码表
            解码:使用String类中的构造方法String(byte[] bytes, String charsetName) bytes:解码的字节数组 charsetName 表示编码表
         */
         //编码:String类中的非静态方法byte[] getBytes(String charsetName) 参数表示编码表
        byte[] bytes = username.getBytes("ISO-8859-1");
        //解码:使用String类中的构造方法String(byte[] bytes, String charsetName) bytes:解码的字节数组 charsetName 表示编码表
        username = new String(bytes,"UTF-8");

        System.out.println("username = " + username);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值