当前位置: 首页 > news >正文

Servlet、HttpServletRequest、HttpServletResponse、静态与动态网页、jsp、重定向与转发

DAY15.2 Java核心基础

JavaWeb

要想通过浏览器或者客户端来访问java程序,必须通过Servlet来处理

没有Servlet,java是无法处理web请求的

Web交互:

  • 接收请求HttpServletRequest:可以获取到请求的信息,比如uri,url,访问的方法…
  • 返回请求HttpServletResponse:可以获取Writer,来封装信息返回给浏览器

代码示例:

@WebServlet("/test")
public class MyHttpServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("重写的doGet方法,下面是业务逻辑");
        resp.getWriter().write("hello");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("重写的doPost方法,下面是业务逻辑");
    }
}

但是返回的类型是字符串

image-20250321214229253

但是前端都是网页的形式,如何返回网页的形式呢?

可以返回html格式的代码

image-20250321214341367

网页就可以渲染上去了

如果要返回一个写好的网页呢?

之前在Tomcat章节说过我们可以直接通过链接访问到对应的网页,那为什么还需要先访问Servlet再返回HTML呢?

因为我们需要拿到数据渲染到静态网页

静态网页:写死了的网页,无法更新数据

动态网页:我们可以渲染数据到网页上面

真正的网页:静态页面(HTML)+业务数据(后端处理)

但是处理不能在write的时候处理撒

resp.getWriter().write("<h1>Hello World</h1>");

比如要改这个h1标签里面的内容,我们不能直接在这里改,如果这个页面很大很长那咋办?是吧

如果要加一、十行…代码怎么办?

就像

writer.write("<h1>Hello World</h1>");
writer.write("<h1>Hello World2</h1>");
writer.write("<h1>Hello World3</h1>");
writer.write("<h1>Hello World4</h1>");

要是这个页面有上百行,不可能在这写一百行write吧

Java 这时候出现了 JSP 通过 JSP 的机制来解决这个问题

JSP :Java Server Page – Java服务页面

一套前端HTML的动态模板,就好像HTML和Java的混合体,可以动态拼接HTML代码,并且可以嵌入Java代码

手动拼接HTML代码太麻烦

可以直接在JSP中编写java代码,JSP会自动转化为一个Servlet,自动将所有的代码生成对应的write输出

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%
        String name ="张三";
    %>
    <h1>Hello</h1>
    <h1>I</h1>
    <h1>am</h1>
    <h1><%=name%></h1>
</body>
</html>

image-20250321220032857

嵌入java代码可以渲染数据

前端看到的是经过JSP加工后的代码

image-20250321220223346

JSP 内置对象

内置对象是jsp引擎自动创建的,开发者无需创建即可使用

  • request:HttpServletRequest 的一个对象,接收用户请求

  • response:HttpServletResponse 的一个对象,客户端做出响应

  • pageContext:PagaContext 的一个对象,页面上下文,获取页面信息

  • session:HttpSession 的一个对象,代表浏览器和服务器的一次会话,保存一个用户信息

  • application:ServletContext 的一个对象,表示当前 WEB 应用,全局对象,保存所有用户的共享数据

  • config:当前 JSP 对应的 Servlet 的 ServletConfig 对象,可以获取当前 Servlet 的信息

  • out:JspWriter 对象,向客户端输出打印信息

  • page:指当前 JSP 对应的 Servlet 对象

  • exception:表示 JSP 页面发送的异常信息

常用的就request、response、session三个内置对象

request常用方法

  • String getParameter(String name) :获取前端传来的参数

  • void setAttribute(String name,Object value) :通过键值对的形式来保存数据

  • Object getAttribute(String name) :通过 key 值获取数据

  • RequestDispatch getRequestDispatch(String path) :返回一个 RequestDispatch 对象,forward() 用于转发请求

doGet的重写业务代码逻辑

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("重写的doGet方法,下面是业务逻辑");
    // 获取到url中的query参数
    String id = req.getParameter("id");
    // 设置request的参数,以便jsp可以找到
    req.setAttribute("id",id);
    // 设置请求转发路径,转发到page.jsp
    RequestDispatcher requestDispatcher = req.getRequestDispatcher("/page.jsp");
    // 请求转发
    requestDispatcher.forward(req,resp);
}

jsp代码:

通过request.getAttribute(“id”)获取到id的值,然后渲染到网页上面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%
        String name ="张三";
        String id = (String) request.getAttribute("id");
    %>
    <h1>Hello</h1>
    <h1>I</h1>
    <h1>am</h1>
    <h1><%=name%></h1>
    <h1><%=id%></h1>
</body>
</html>

访问网页:

传递的id值为1,渲染到了这个网页上面

image-20250322225115116

response 的常用方法

  • sendRedirect(String path) //重定向
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("重写的doGet方法,下面是业务逻辑");
        String id = req.getParameter("id");
        // 获取到url中的query参数
        req.setAttribute("id",id);
        // 设置请求转发路径,跳转到page.jsp
//        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/page.jsp");
        // 请求转发
//        requestDispatcher.forward(req,resp);
        resp.sendRedirect("/page.jsp");
    }

如果用sendRedirect(String path) //重定向,则无法取出request的数据

同样都是重定向,为什么sendRedirect(String path) 不能获取request保存的数据呢?(面试考题)

其实是因为sendRedirect(String path) 是重新发送了一个请求,会创建一个新的request对象,则该对象是没有携带id属性参数的

转发和重定向都是进行页面跳转的,区别在哪?

重定向:两次请求

转发:一次请求

比如刚刚那个请求,先进入的是Servlet

如果是转发的话,则进入Servlet和jsp的请求是同一个请求,那么jsp可能可以获取到servlet里面处理过有id参数的request对象,那么肯定可以获取到这个对象的属性参数了

如果是重定向的话,进入Servlet和jsp的请求不是同一个请求,第一个请求是进入Servlet,重定向就相当于让浏览器重新发送一个请求来访问 JSP,第一个请求在 Servlet 中已经结束了它的生命周期,第二次方法 JSP 的请求相当于从浏览器发送的一个全新的请求

但是我们非要用重定向来传递数据呢,那么怎么实现呢?

那么我们需要使用生命周期更长的对象来存储数据

比如session存储,就算是两次不同的请求也可以获取到session存储的数据

session的作用域大于request,都是用来存储数据的

只要不关闭浏览器,我们都可以获取到session里面的数据

HttpSession session = req.getSession();
session.setAttribute("id",id);

在代码中用session存储数据

<%
    String name ="张三";
    String id = (String) request.getSession().getAttribute("id");
%>

在jsp读取session数据

image-20250322230924119

可以看见虽然重定向了,但是还是获取到了id的数据

<%
    String name ="张三";
    String id = (String) request.getSession().getAttribute("id");
%>
<h1>Hello</h1>
<h1>I</h1>
<h1>am</h1>
<h1><%=name%></h1>
<h1><%=id%></h1>
虽然可以实现数据的传输,但是步骤较为繁琐,效率较低,如何来解决呢?

使用 EL 表达式

EL 表达式有什么作用?

替换 JSP 页面中访问数据时的复杂编码

简化 JSP 页面的取值操作

语法:${key}

JSP 取值的特点是先要存值,才能取值

<body>
    <h1>Hello</h1>
    <h1>I</h1>
    <h1>am</h1>
    <h1>${id}</h1>
</body>

比之前的取值方便多了

EL 表达式 ${id} 会依次从以下作用域查找变量:
  • Page Scope(页面作用域)
  • Request Scope(请求作用域)
  • Session Scope(会话作用域)
  • Application Scope(应用作用域)

image-20250322232340656

如果设置没问题,还是出现了${id}的话,有可能EL表达式被忽略了,我们可以手动在 jsp文件 顶部启用

<%@ page isELIgnored="false" %>

相关文章:

  • 旋转编码器
  • 医学交互作用分析步骤和目的(R语言)
  • @Validated 使用介绍
  • Android开源库——Glide
  • Java主流开发框架之请求响应常用注释
  • 【LeetCode】大厂面试算法真题回忆(36)--相同数字的积木游戏
  • FFmpeg + ‌Qt‌ 简单视频播放器代码
  • 【算法笔记】图论基础(一):建图、存图、树和图的遍历、拓扑排序、最小生成树
  • 如何在 Bash 中不依赖 curl 或 wget 发出 HTTP 请求并实现文件传输——/dev/tcp的妙用
  • illustrate:一款蛋白/核酸结构快速渲染为“卡通风格”的小工具
  • Ciura序列
  • 弱网测试:全链路实战、高阶策略与自动化落地
  • 多线程14(哈希表与文件操作IO)
  • CPU架构和微架构
  • 中颖SH366000介绍和使用全解
  • Web安全策略CSP详解与实践
  • HTTP请求过程详解
  • 构建自定义MCP天气服务器:集成Claude for Desktop与实时天气数据
  • /2要求:定义一个方法,根据id查找对应的用户信息 //如果存在,返回id //如果不存在,返回-1
  • 蓝桥杯 小球反弹
  • 暗蓝评《性别打结》丨拆解性别之结需要几步?
  • “不意外”和“不遗余力”,直击上海商超对接外贸企业
  • 第五届全国医院人文管理路演在昆山举办:患者体验才是温度计
  • 淮安四韵·名城新章: 网络名人领略“运河之都”魅力
  • 四川邻水县县长石国平拟任县(市、区)党委书记
  • 委员呼吁提高政府机构电话号码准确性,辽宁阜新回应