JavaWeb-Servlet服务连接器(二)

简介: Request(获取请求信息)、1.获取请求行内容、2.解决乱码问题、3.获取请求头部分、4.获取请求体、5.其他功能

Request(获取请求信息)

工作流程:

1.通过请求的url的资源路径,tomcat会生成相应的Servlet实现对象。

2.tomcat服务器会创建request对象和response对象,request对象接收请求消息数据。

3.tomcat将request和response方法传递给service方法并且调用service方法

4.程序员可以通过request对象获取请求的消息数据,并且设置response的响应数据

5.服务器在给浏览器响应之前获取response

1.获取请求行内容

请求行部分 获取请求行内容的方法 示例代码 返回值
请求方法(Method) getMethod() String method = request.getMethod(); "GET"
(重点)请求       URI(URL) getRequestURI() String uri = request.getRequestURI(); "/index.html"
协议版本(Protocol) getProtocol() String protocol = request.getProtocol(); "HTTP/1.1"
查询字符串(Query String) getQueryString() String queryString = request.getQueryString(); null (如果没有查询字符串)
(重点)上下文路径(Context Path) getContextPath() String contextPath = request.getContextPath(); "" (如果没有上下文路径,则为空字符串)

案例代码:

package com.company;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/requestHang")
public class RequestHang extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        获取方法
        String method =req.getMethod();
        System.out.println("使用的方法是"+method);
//       * 获取上下文路径
        String contextPath = req.getContextPath();
        System.out.println("请求的上下文路径是"+contextPath);
//       * 获取URI
        String Uri = req.getRequestURI();
        System.out.println("请求的URI是"+Uri);
//        获取协议版本
        String version = req.getProtocol();
        System.out.println("请求的协议版本是"+version);
//        获取查询字符串
        String string = req.getQueryString();
        System.out.println("请求附带的查询字符串是"+string);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //        获取方法
        String method =req.getMethod();
        System.out.println("使用的方法是"+method);
//       * 获取上下文路径
        String contextPath = req.getContextPath();
        System.out.println("请求的上下文路径是"+contextPath);
//       * 获取URI
        String Uri = req.getRequestURI();
        System.out.println("请求的URI是"+Uri);
//        获取协议版本
        String version = req.getProtocol();
        System.out.println("请求的协议版本是"+version);
//        获取参数
        String username = req.getParameter("username");
        System.out.println("Username is "+username);
    }
}

image.gif

index.jsp代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>测试发送消息</title>
  </head>
  <body>
    <form action="/com_alphamilk_war_exploded/requestHang" method="get">
      <input name="username">
      <input type="submit" value="提交">
    </form>
  </body>
</html>

image.gif

通过url访问结果如下:

image.gif编辑

可以看到请求出现了乱码,下一步就是解决请求乱码问题.


 

2.解决乱码问题

1.控制台输出乱码

如果tomcat的版本是在10以下的,用中文可能会出现乱码问题,这里用的是9版本,解决方法:

打开tomcat文件夹找到conf配置文件

配置文件在conf下面,将配置中的字符集改成GBK,修改后的配置如下图:

image.gif编辑

修改后重新启动结果如下:

image.gif编辑

2.post请求方式中参数中文乱码

通过将表单提交方式改为post,再在内容输入中文,通过request方法的getParameter获取参数username

image.gif编辑

可以看到输出的结果是一串乱码。所以需要进行修补

image.gif编辑

解决方法:设置流的编码即可

//        设置流的编码
        req.setCharacterEncoding("utf-8");

image.gif

image.gif编辑

重启服务器并再次运行:

image.gif编辑

 


3.获取请求头部分

示例:请求头(Request Header):Accept-Language: en-US,en;q=0.9

请求头名称 获取请求头值的方法 示例代码 返回值
Accept-Language getHeader("Accept-Language") String acceptLanguage = request.getHeader("Accept-Language"); "en-US,en;q=0.9"
所有请求头名称 getHeaderNames() Enumeration<String> headerNames = request.getHeaderNames(); 包含所有请求头名称的枚举

案例代码:获取所有请求头信息与对应的值

package com.company;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
@WebServlet("/rsHead")
public class RequestHead extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        通过迭代器Enumration遍历请求头
        Enumeration<String> enumeration = req.getHeaderNames();
//        开始遍历
        while (enumeration.hasMoreElements()){
            String name = enumeration.nextElement();
//            找到获取头名称的值
            String value = req.getHeader(name);
            System.out.println(name+" == " +value);
        }
    }
}

image.gif

image.gif编辑

案例代码2:设置外部跳转无法访问,只能通过项目内的页面访问资源

通过请求头referer获取访问到当前页面的来源(如果是直接输入地址则referer为空)

首先桌面随便创建一个html文件,然后通过文件的超链接实行跳转到刚才页面

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>冒牌登陆系统</title>
  </head>
  <body>
    <a href="http://localhost:9998/com_alphamilk_war_exploded/rsHead">访问尝试</a>
  </body>
</html>

image.gif

image.gif编辑 防止外部跳转访问代码:

package com.company;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/refererTest")
public class rsRefer extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        设置Referer
        String referer = req.getHeader("referer");
//        防盗链机制
        if (referer != null){
            if (referer.contains("/com_alphamilk_war_exploded")){
                System.out.println("正常访问");
            }else {
                System.out.println("非法访问,请从官网处进行访问");
            }
        }
    }
}

image.gif

重启服务器后,此时再通过随便创建的html文件修改路径后访问得到:

image.gif编辑


4.获取请求体

只有post请求方式才有请求体

步骤:

1.获取流对象 BufferReader

2.从流对象中获取值 nextline();

常用方法:

方法名 作用
getReader() 获取请求的输入流,并返回一个BufferedReader对象,用于读取来自客户端的请求数据。
getInputStream() 获取请求的输入流,并返回一个ServletInputStream对象,用于直接从客户端请求中读取字节数据。

案例代码:

html代码:

<html>
  <head>
    <title>测试发送消息</title>
  </head>
  <body>
  <form action="http://localhost:9998/com_alphamilk_war_exploded/body" method="post">
    <input type="text" name="username" placeholder="用户名"><br>
    <input type="text" name="password" placeholder="密码"><br>
    <input type="submit">
  </form>
  </body>
</html>

image.gif

Servlet类代码:

package com.company;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
@WebServlet("/body")
public class RequestBody extends HttpServlet{
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        BufferedReader reader = req.getReader();
        String line;
        while (reader.readLine()!=null){
            line = reader.readLine();
            System.out.println(line);
        }
    }
}

image.gif

通过输入用户名与密码再提交表单

image.gif编辑

image.gif编辑

 


5.其他功能

1.获取参数通用方式(不管post请求还是get请求都可以用、重点):    

方法名 作用
getParameter(String name) 获取指定名称的请求参数的值。如果有多个同名参数,只返回第一个参数的值。
getParameterValues(String name) 获取指定名称的请求参数的所有值。如果参数存在多个值,返回一个包含所有值的字符串数组。
Enumeration<String> getParameterNames() 返回一个枚举对象,包含所有请求参数的名称。可以使用该枚举对象遍历所有请求参数的名称。
getParameterMap() 返回一个Map对象,其中包含所有的请求参数和它们的值。键是参数名称,值是参数的值(以字符串数组形式)。

案例代码:

服务器代码

package com.company;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
@WebServlet("/Demo3")
public class ReqOther extends HttpServlet{
    HttpServletRequest req;
    HttpServletResponse resp;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Enumeration<String> enumeration = req.getParameterNames();
        String names;
//        通过迭代器遍历输出所有的参数名与对应的值
        while (enumeration.hasMoreElements()){
            names = enumeration.nextElement();
            System.out.println(names+":"+req.getParameter(names));
        }
    }
//    由于是通用方法,所以如果有post请求则更改为Get请求流程
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        注意post方法会出现中文乱码问题,需要转为utf-8格式编码
        req.setCharacterEncoding("utf-8");
        this.req = req;
        this.resp = resp;
        this.doGet(req, resp);
    }
}

image.gif

web代码更改路径地址后输入,并提交

image.gif编辑

image.gif编辑

当一个表单中出现多个相同的名字时候就需要用getParameterValues或者getParameterMap存放。

2.请求转发(服务器内部资源的跳转方式)

方法名 作用
getRequestDispatcher(String path) 获取与给定相对路径(path)相关联的 RequestDispatcher 对象,用于在同一个 Web 应用程序内部的不同资源之间进行请求转发。
forward(ServletRequest request, ServletResponse response) 将请求和响应对象转发给另一个资源(如 Servlet、JSP 页面),停止当前资源的执行,并将控制权交给目标资源,由目标资源负责生成响应。

案例代码:

创建一个资源类,一个访问类,通过访问类访问资源类

访问类:

package com.company;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
//资源跳转
@WebServlet("/Demo4")
public class rsPatcher extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            System.out.println("3s后进行跳转");
//            3秒后进行跳转
            TimeUnit.SECONDS.sleep(3);
        }catch (Exception e){
            e.printStackTrace();
        }
//        定义要跳转的资源类路径
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/Demo5");
//        进行跳转
        requestDispatcher.forward(req,resp);
    }
}

image.gif

资源类:

package com.company;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/Demo5")
public class pro extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("我是资源类,我被访问了");
    }
}

image.gif

输出:

image.gif编辑

注意:跳转只能跳转到当前项目中的资源,如果把资源改为外部路径,比如www.baidu.com这样就无法进行跳转。并且转发知识一次的请求

3.共享数据

由于一个类中的数据往往只能该类使用,但是有些资源需要进行多个对象能共享使用,所以引入了共享数据

方法名 作用
setAttribute(String name, Object value) 将一个数据对象(value)与给定的名称(name)关联起来,将其存储在 ServletContext、HttpSession 或 HttpServletRequest 中,以便多个对象之间共享使用。
getAttribute(String name) 根据给定的名称(name),从 ServletContext、HttpSession 或 HttpServletRequest 中获取与之关联的数据对象。
removeAttribute(String name) 根据给定的名称(name),从 ServletContext、HttpSession 或 HttpServletRequest 中删除关联的数据对象。

案例代码:

设置一个运输物资类,一个资源类

运输物资类:

package com.company;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/Demo6")
public class Demo6 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        设置共享资源,格式为   键值->对象
        req.setAttribute("msg","物资");
        System.out.println("当前为跳转类进行运输:"+req.getAttribute("msg"));
        RequestDispatcher requestDispatcher  = req.getRequestDispatcher("/Demo7");
//        进行跳转
        requestDispatcher.forward(req,resp);
    }
}

image.gif

资源类

package com.company;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/Demo7")
public class Demo7 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("资源类获取到"+req.getAttribute("msg"));
    }
}

image.gif

image.gif编辑

 


目录
相关文章
JavaWeb-Servlet服务连接器(三)
Response响应对象、1.基本功能、2.重定向、3.路径、4.服务器输出数据到浏览器
73 2
|
存储 XML JSON
JavaWeb-Servlet服务连接器(四)
1.ServletContext Cookie与Session 1.Cookie 2.Session
62 0
|
XML 前端开发 Java
关于服务连接器(Servlet)你了解多少?
Servlet是JavaWeb最为核心的内容,它是Java提供的一门动态web资源开发技术。 使用Servlet就可以实现,根据不同的登录用户在页面上动态显示不同内容。 Servlet是JavaEE规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet
80 0
关于服务连接器(Servlet)你了解多少?
|
4月前
|
缓存 安全 Java
Java服务器端技术:Servlet与JSP的集成与扩展
Java服务器端技术:Servlet与JSP的集成与扩展
40 3
|
4月前
|
存储 缓存 前端开发
Servlet与JSP在Java Web应用中的性能调优策略
Servlet与JSP在Java Web应用中的性能调优策略
36 1
|
4月前
|
存储 Java 关系型数据库
基于Servlet和JSP的Java Web应用开发指南
基于Servlet和JSP的Java Web应用开发指南
73 0
|
4月前
|
前端开发 安全 Java
在Java服务器端开发的浩瀚宇宙中,Servlet与JSP犹如两颗璀璨的明星,它们联袂登场,共同编织出动态网站的绚丽篇章。
在Java服务器端开发的浩瀚宇宙中,Servlet与JSP犹如两颗璀璨的明星,它们联袂登场,共同编织出动态网站的绚丽篇章。
31 0
|
6月前
|
自然语言处理 前端开发 Java
Servlet与JSP:Java Web开发的基石技术详解
【6月更文挑战第23天】Java Web的Servlet与JSP是动态网页的核心。Servlet是服务器端的Java应用,处理HTTP请求并响应;JSP则是结合HTML与Java代码的页面,用于动态内容生成。Servlet通过生命周期方法如`init()`、`service()`和`destroy()`工作,而JSP在执行时编译成Servlet。两者在MVC架构中分工,Servlet处理逻辑,JSP展示数据。尽管有Spring MVC等框架,Servlet和JSP仍是理解Web开发基础的关键。
111 12
|
6月前
|
存储 Java 关系型数据库
基于Servlet和JSP的Java Web应用开发指南
【6月更文挑战第23天】构建Java Web应用,Servlet与JSP携手打造在线图书管理系统,涵盖需求分析、设计、编码到测试。通过实例展示了Servlet如何处理用户登录(如`LoginServlet`),JSP负责页面展示(如`login.jsp`和`bookList.jsp`)。应用基于MySQL数据库,包含用户和图书表。登录失败显示错误信息,成功后展示图书列表。部署到Tomcat服务器测试功能。此基础教程为深入Java Web开发奠定了基础。
125 10
|
6月前
|
缓存 小程序 前端开发
Java服务器端技术探秘:Servlet与JSP的核心原理
【6月更文挑战第23天】Java Web开发中的Servlet和JSP详解:Servlet是服务器端的Java小程序,处理HTTP请求并响应。生命周期含初始化、服务和销毁。创建Servlet示例代码展示了`doGet()`方法的覆盖。JSP则侧重视图,动态HTML生成,通过JSP脚本元素、声明和表达式嵌入Java代码。Servlet常作为控制器,JSP处理视图,遵循MVC模式。优化策略涉及缓存、分页和安全措施。这些技术是Java服务器端开发的基础。
67 9