JavaWeb——Servlet的请求与响应

HttpServletRequest

作用:每次只要有请求进入Tomcat 服务器,Tomcat 服务器就会把请求过来的HTTP 协议信息解析好封装到Request 对象中。然后传递到service 方法(doGet 和doPost)中给我们使用。我们可以通过HttpServletRequest 对象,获取到所有请求的信息。

常用方法

方法名方法作用
getRequestURI()获取请求的资源路径
getRequestURL()获取请求的统一资源定位符(绝对路径)
getRemoteHost()获取客户端的ip 地址
getHeader()获取请求头
getParameter()获取请求的参数
getParameterValues()获取请求的参数(多个值的时候使用)
getMethod()获取请求的方式GET 或POST
setAttribute(key, value)设置域数据
getAttribute(key)获取域数据
getRequestDispatcher()获取请求转发对象
public class RequestAPIServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //i. getRequestURI() 获取请求的资源路径
        System.out.println("URI:" + req.getRequestURI());
        //ii. getRequestURL() 获取请求的统一资源定位符(绝对路径)
        System.out.println("URL:" + req.getRequestURL());
        //iii. getRemoteHost() 获取客户端的ip 地址
        /*
        * 在IDEA中,使用localhost访问时,,得到的客户端ip地址是:127.0.0.1
        * 在IDEA中,使用127.0.0.1访问时,,得到的客户端ip地址是:127.0.0.1
        * 在IDEA中,使用真实ip访问时,,得到的客户端ip地址是:真实的ip地址
        * */
        System.out.println("客户端IP地址:" + req.getRemoteHost());
        //iv. getHeader() 获取请求头
        System.out.println("请求头User-Agent:" + req.getHeader("User-Agent"));
        //vii. getMethod() 获取请求的方式GET 或POST
        System.out.println("请求的方式:" + req.getMethod());
    }
}

字符集编码设置

GET请求时的设置:

方式一:
在Tomcat服务器的web.xml中设置端口号的那一个标签上添加配置信息URIEncoding=“UTF-8”

<Connector URIEncoding="UTF-8" connectionTimeout="50000" port="8080" protocol="HTTP/1.1" redirectPort="8443" />

方式二:

  1. 获取请求参数
    String username = req.getParameter(“username”);
  2. 先以iso8859-1 进行编码
  3. 再以utf-8 进行解码
    username = new String(username.getBytes(“iso-8859-1”), “UTF-8”);

说明: tomcat8以后默认URI编码格式是utf-8;7之前的都是iso8859-1
在这里插入图片描述


POST请求时的设置:

POST通过request body传递参数是实体内容解码方式,默认解码格式是request编码格式,与Tomcat8编码格式无关,默认以ISO8859-1的编码解析数据。
所以要用request的setCharacterEncoding(String env)方法设置编码字符集。

 @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String password = req.getParameter("password");
        //设置请求体的字符集为UTF-8,从而解决post请求的中文乱码问题
        //要在获取请求参数之前调用才有效
        req.setCharacterEncoding("UTF-8");
        System.out.println("----Post---");
        //获取请求的参数:
        String username = req.getParameter("username");
        String[] hobby = req.getParameterValues("hobby");
        System.out.println("用户名:" + username);
        System.out.println("密码:" + password);
        System.out.println("爱好:" + Arrays.toString(hobby));

    }

或者在web.xml用SpringMVC配置一个filter设置所有的post编码格式。

<!--    字符编码的Filter:要在所有Filter之前,要不其他Filter可能获取了参数-->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--        encoding:指定解决POST请求乱码-->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
<!--        forceEncoding:是否解决响应乱码,但是不指定文本类型-->
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern> / *</url-pattern>
    </filter-mapping>

请求转发

请求转发的特点:

  1. 浏览器地址栏没有变化
  2. 请求转发一共是一次请求
  3. 他们共享Request域中的数据
  4. 可以转发到WEB-INF目录下(该目录无法直接访问)
  5. 不可以转到工程以外访问资源

示例:页面1(实施请求转发)

public class Servlet1 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取请求的参数
        String username = request.getParameter("username");
        System.out.println("在Servlet1中查看参数:" + username);

        //给请求(材料)盖个章,并传递到Servlet2去查看
        request.setAttribute("key","柜台1的章");

        //问路:Servlet2怎么走
        /*
        * 请求转发必须要以/斜杠打头,/表示地址为:http://ip:port//工程名/,映射到IDEA代码的web目录
        * */
//        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/servlet2");
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/WEB-INF/form.html");//可行!
//        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/http://www.baidu.com");//不行这是在自己的工程下
        //不行还是在自己工程下,请求转发访问不了外面的资源
//        RequestDispatcher requestDispatcher = request.getRequestDispatcher("http://www.baidu.com");

        //走向Servlet2
        requestDispatcher.forward(request,response);
    }
}

页面2(实际页面)

public class Servlet2 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String username = request.getParameter("username");
        System.out.println("在Servlet2中查看参数:" + username);

        //查看柜台1是否有章
        Object key = request.getAttribute("key");
        System.out.println("是否是柜台1的章:是" + key);

        //处理自己的业务
        System.out.println("Servlet2处理自己的业务");
    }
}

base标签

问题引入:
在浏览器显示的超链接地址中,所有相对路径在工作时候都会参照当前浏览器地址栏中的地址来进行跳转,从而导致可能得不到想要的路径。

base标签的作用:
可以设置当前页面中所有相对路径工作时,参照哪个路径来进行跳转。

<!--    base标签,永远固定相对路径跳转的结果-->
    <base href="http://localhost:8080/"/>

web中"/ "斜杠的不同意义

在web 中/ 斜杠是一种绝对路径。
情况1:
/ 斜杠如果被浏览器解析,得到的地址是:http://ip:port/

<a href="/">斜杠</a>

情况2:
/ 斜杠如果被服务器解析,得到的地址是:http://ip:port/工程路径

  1. <url-pattern>/servlet1</url-pattern>
  2. servletContext.getRealPath(“/”);
  3. request.getRequestDispatcher(“/”);

特殊情况:

response.sendRediect(“/”); 把斜杠发送给浏览器解析。得到http://ip:port/

不以/斜杠开始是相对路径,以当前资源路径为基准,但是经常容易出问题。

HttpServletResponse

概述:HttpServletResponse 类和HttpServletRequest 类一样。每次请求进来,Tomcat 服务器都会创建一个Response 对象传递给Servlet 程序去使用。
HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息,我们如果需要设置返回给客户端的信息,可以通过HttpServletResponse 对象来进行设置。

HttpServletResponse的两个输出流:

字节流getOutputStream()常用于下载(传递二进制数据)
字符流getWriter()常用于回传字符串(常用)

:两个流同时只能使用一个。即使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。

如下代码会报错:java.lang.IllegalStateException: getWriter() has already been called for this response

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        PrintWriter writer = response.getWriter();
        ServletOutputStream outputStream = response.getOutputStream();
        
    }

响应乱码解决

方式一:(不推荐使用)

设置服务器字符集为UTF-8
resp.setCharacterEncoding(“UTF-8”);
通过响应头,设置浏览器也使用UTF-8 字符集
resp.setHeader(“Content-Type”, “text/html; charset=UTF-8”);

方式二:(推荐使用)

它会同时设置服务器和客户端都使用UTF-8 字符集,还设置了响应头
此方法一定要在获取流对象之前调用才有效
resp.setContentType(“text/html; charset=UTF-8”);

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        System.out.println(response.getCharacterEncoding());//默认ISO-8859-1
//        设置服务器字符集为UTF-8
//        response.setCharacterEncoding("UTF-8");
        //通过响应头,设置浏览器也使用UTF-8字符集
//        response.setHeader("content-Type","text/html;charset=utf-8");


        //以下方法会同时设置服务器和客户端都是用utf-8字符集,还设置了响应头
        //此方法一定要在获取流对象之前调用才有效
        response.setContentType("text/html;charset=utf-8");
        System.out.println(response.getCharacterEncoding());//utf-8

        //要求:往客户端回传字符串数据
        PrintWriter writer = response.getWriter();
        writer.write("字符集编码设置成功");

    }

请求重定向

概念:客户端给服务器发请求,然后服务器给客户端一些地址,让客户端去新地址访问,叫请求重定向(因为之前的地址可能已经被废弃)。

请求重定向的特点:

  1. 浏览器地址栏会发生变化
  2. 一共发生两次请求
  3. 不共享Request域中数据
  4. 不能访问WEB-INF下的资源
  5. 可以访问工程外的资源

:与请求转发的特点相反

方式一:(不推荐使用)

设置响应状态码302 ,表示重定向,(已搬迁)
resp.setStatus(302);
设置响应头,说明新的地址在哪里
resp.setHeader(“Location”, “http://localhost:8080”);

方式二:(推荐使用)

请求重定向的第二种方案(推荐使用):
resp.sendRedirect(“http://localhost:8080”);

代码示例:
旧地址

public class Response1 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("曾到此一游——Response1");
        //方式一:
        //设置响应状态码302,表示重定向(已搬迁)
//        response.setStatus(302);
        request.setAttribute("key","keyValue");
        //设置响应头说明新地址在哪里
//        response.setHeader("Location","http://localhost:9999/07_servlet/response2");//可以
//        response.setHeader("Location","http://localhost:9999/07_servlet/WEB-INF/form.html");//404
//        response.setHeader("Location","http://baidu.com");//可以
        
        //方式二:
        response.sendRedirect("http://localhost:9999/07_servlet/response2");

    }
}

新地址

public class Response2 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        response.getWriter().write("response2's result!");
        response.getWriter().println("response2's result!");
        System.out.println(request.getAttribute("key"));//null

    }
}

### Java Web 中的请求响应工作原理 Java Web 的核心在于客户端(通常是浏览器)向服务器发送 HTTP 请求,而服务器接收并处理该请求后返回相应的 HTTP 响应。这一过程主要依赖于 `HttpServletRequest` 和 `HttpServletResponse` 接口来实现。 #### 1. HttpServletRequest的作用 `HttpServletRequest` 是用于封装 HTTP 请求的对象,它包含了来自客户端的所有信息,例如请求参数、头部信息、会话数据等。以下是其常见功能: - 获取请求方法:通过 `getMethod()` 方法可以获取客户端使用的 HTTP 方法(GET/POST 等)。 - 获取请求参数:可以通过 `getParameter(String name)` 或者 `getParameterMap()` 来读取 URL 参数或者表单提交的数据[^2]。 - 访问会话管理:如果启用了会话跟踪,则可通过 `getSession(boolean create)` 获得 HttpSession 对象以便存储和检索用户特定的信息。 #### 2. HttpServletResponse的功能 `HttpServletResponse` 则负责构建发回给用户的响应消息。这包括但不限于设定状态码、定义实体主体内容类型以及实际写入输出流等内容。 - 设置响应的状态码:比如成功时通常设为200 OK;当发生错误则可能设置成404 Not Found等等。可调用 setStatus(int sc) 实现这一点。 - 添加响应头字段:像 Content-Type, Cache-Control 这样的元数据能够指导浏览器如何解释接收到的内容。addHeader() 函数允许添加自定义头部项。 - 发送重定向指令:sendRedirect(java.lang.String location),指示客户重新访问指定的新URL位置[^3]。 #### 3. RequestDispatcher的工作方式 除了直接生成HTML页面作为回应之外,在某些情况下还需要把控制权交给另一个组件继续完成剩余的任务——这就是所谓的“转发”。RequestDispatcher 提供了一种机制让当前 servlet请求传递至其他资源(如JSP文件或其他servlet)去执行进一步操作而不改变原始URI路径可见性给最终使用者看到的是统一入口点的效果[^1]。 ```java // Example of using RequestDispatcher to forward a request. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String target = "/anotherResource"; getServletContext().getRequestDispatcher(target).forward(request,response); } ``` 上述代码片段展示了如何在一个简单的 GET 请求处理器中运用 RequestDispatcher 执行内部跳转到名为 `/anotherResource` 的目标上。 --- ### 总结 综上所述,Java Web 应用程序中的请求响应交互遵循标准的 HTTP 协议流程,并借助 Servlet API 提供的强大工具集简化了开发人员对于复杂网络通信细节的关注度。通过对 HttpServletRequest 和 HttpServletResponse 的灵活操控配合诸如 RequestDispatcher 类似的辅助类库的支持下实现了高效便捷的服务端逻辑编写能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值