Link狂神说

这是课代表的Javaweb笔记:
https://blog.csdn.net/qq_36188127/article/details/109370717

Link楠哥

https://pan.baidu.com/s/1MDbbNKqC5mgUGg2yUiM9cg 提取码: zmpi

p30:源码和静态资源
链接:https://pan.baidu.com/s/1uod9b5enrMK1r9t3yqHROA
提取码:ro6p
—来自百度网盘超级会员V4的分享

1、基本概念

1.1、前言

Java Web即web开发,web就是网页的意思。包括静态网页和动态网页,即静态web和动态web。

  • 静态web
    • html,css
    • 提供给所有人看的数据都不会发生变化
  • 动态web
    • 几乎所有的网站
    • 个性化显示页面
    • 技术栈:Servlet/JSP,ASP,PHP

在Java中,动态web资源开发的技术称为JavaWeb。

1.2、web应用程序

本义就是可以提供浏览器访问的程序。比如xxx.html,多个这样的文件组成的web资源可被外界访问,对外界提供服务。这个统一的web资源会被放在同一个文件夹下,这个文件夹就是web应用程序即Tomcat服务器。一个web应用程序由多部份组成,比如:

  • html,css,js
  • jsp,servlet
  • java程序包
  • jar包
  • 配置文件

web应用程序编写完毕,若想提供给外界访问,则需要一个服务器来统一管理。

1.3、静态web

  • .html,.htm这些都是网页后缀,如果服务器上一直存在这些东西,我们就可以直接进行读取。
  • 静态web存在的缺点:
    • web页面无法动态更新,所有用户看到的都是同一个页面
      • 轮播图,点击特效:伪动态
      • js,动态效果
      • VBScript,动态效果
    • 它无法和数据库交互(意味着数据无法持久化,用户无法交互)

1.4、动态web

动态展示会因人而异。
image.png
缺点

  • 加入服务器的动态web资源出现了错误,我们需要重新编写后台程序并重新发布;

优点

  • web页面可以动态更新,所有用户看到的都不是同一个页面
  • 它可以和数据库交互(意味着数据可以持久化,用户可以交互)

    2、web服务器

    2.1、技术解读

    ASP,JSP,PHP
    ASP:是微软开发的服务器,它是在HTML中嵌入了VB脚本,ASP+COM,基本每个页面都有几千行的业务代码, 页面极其混乱。
    PHP:开发速度快,功能很强大,跨平台,代码简单,但无法承载大量访问的情况
    JSP/Servlet:
    B/S:浏览器、服务器架构
    C/S:客户端和服务器架构

  • Sun公司主推的B/S架构

  • 基于Java语言
  • 可承载三高:高并发、高可用、高性能
  • 语法像ASP,ASP->JSP,加强市场强度。

    2.2、web服务器

    服务器是一种被动操作,用来处理用户的一些请求和给用户响应一些信息。常见的包括Tomcat、Jboos、Weblogin、Jetty等。
    Tomcat因为技术先进、性能稳定而且免费,所以深受Java爱好者的喜欢。Tomcat实际上运行JSP页面和Servlet。工作3-5年之后,可以尝试手写Tomcat服务器。

3.Tomcat

3.1、 安装 Tomcat

Tomcat官网:http://tomcat.apache.org/
image.png
image.png

3.2、 Tomcat 启动和配置

文件夹:
image.png

注:temp文件就是上传下载用的,webapps是存放客户端能访问到的资源,而work是存放tomcat将JSP转换之后的Servlet文件。

启动和关闭 Tomcat

image.png
访问测试:http://localhost:8080/

可能遇到的问题

  • Java 环境变量没有配置导致闪退(需配置兼容性)
  • 乱码问题:可在配置文件中配置

    3.3、 配置

    核心配置

    服务器核心配置文件目录如下:
    image.png
    可以配置启动的端口号

  • tomcat的默认端口号为:8080

  • mysql:3306
  • http:80
  • https:443

    1. <Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000"
    2. redirectPort="8443" /> 123

    可配置主机名称

  • 默认的主机名为:localhost->127.0.0.1

  • 默认网站应用存放的位置为:webapps
    1. <Host name="www.qinjiang.com" appBase="webapps" unpackWARs="true" autoDeploy="true">

    面试题:网站访问过程

  1. 在浏览器输入一个域名,回车;
  2. 本机查看 C:\Windows\System32\drivers\etc\hosts 配置文件是否有相应域名的映射。

case1: 若有,则直接映射到对应的 IP 地址,进行访问。
case2: 若无,则去 DNS 服务器上查找对应的 IP ,找到就返回相应的 IP,找不到就不返回。
image.png
image.png

3.4、 发布一个 Web 网站

网站程序的结构:

  1. --webapps :Tomcat服务器的web目录
  2. -ROOT
  3. -kuangstudy :网站的目录名
  4. - WEB-INF
  5. -classes : java程序
  6. -lib:web应用所依赖的jar包
  7. -web.xml :网站配置文件
  8. - index.html 默认的首页
  9. - static
  10. -css
  11. -style.css
  12. -js
  13. -img
  14. -.....

本质上,我们可以通过…apache-tomcat-10.0.12\bin下的bin目录中的启停命令来开启服务器,然后将需要给客户展示的资源存放到webapps目录中,通过一些映射机制,使客户键入准确域名、ip和应用名时能看到想要看到的效果。然而,这样存在一个问题,就是当所部署的文件需要大量、多次修改时,以上操作并不明智。因此,这个问题的解决可以是IDEA集成Tomcat:

  • 创建一个Java Web工程

image.png

  • Java Web应用组件展示

image.png
具体做法:
首先,我们再index.jsp文件中写一个标签:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>我的标题</title>
  5. </head>
  6. <body>
  7. <h1>等等我,夫人</h1>
  8. </body>
  9. </html>

但此时并不能直接被浏览器访问到,因为还没有部署到应用中。在IDEA中的Tomcat添加方式是:
image.png
image.png
但其实,光添加了Tomcat还不行,我们只有服务器,用户就只能访问到服务器。用户想要访问我们所显示的页面怎么办?就需要部署目录了,即把我们自己写的工程打包放到Tomcat服务器中,放到如下:
image.png

点击启动,效果如下:
image.png
image.png找到应用的三要素:域名+IP+应用名

停掉服务器,效果如下:
image.png
image.png

4、Servlet

Servlet是Java Web开发的基石,与平台无关的服务器组件,它是运行在Servlet容器(或者叫Web应用服务器,这里也即是Tomcat),负责与客户端进行通信。
Servlet有2个功能,创建并返回基于客户端请求的动态HTML页面(根据选择动态返回不同页面)以及与数据库进行通信,是一个类似桥梁的作用。
Servlet本身是一组接口,位于javax.servlet包下。使用时自定义一个类实现Servlet接口,这样的类就具备了接受客户端请求并作出相应的功能。
我们在src下写了个MyServlet类实现了Servlet接口,但是与index.jsp不同,用户并不能直接访问到,因为,用户访问的数据实际上是在target目录下,如果浏览器地址栏直接键入localhost:8080/mt/,实际上就是默认打开该目录下的index.jsp页面。对于外部访问来说,web-inf下的文件都是不可见的(即不能通过url获得web-info下的任何文件),所以,直接访问jsp是不可能的。
image.png

  1. package com.example.mytomcat001;
  2. import javax.servlet.*;
  3. import java.io.IOException;
  4. public class MyServlet implements Servlet {
  5. @Override
  6. public void init(ServletConfig servletConfig) throws ServletException {
  7. System.out.println("init method...");
  8. }
  9. @Override
  10. public ServletConfig getServletConfig() {
  11. return null;
  12. }
  13. @Override
  14. public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
  15. System.out.println("service method...");
  16. }
  17. @Override
  18. public String getServletInfo() {
  19. return null;
  20. }
  21. @Override
  22. public void destroy() {
  23. System.out.println("destory method...");
  24. }
  25. }

因此,正由于浏览器不能直接访问Servlet文件,只能通过映射的方式间接访问Servlet,映射需要开发者手动配置,有两种配置方式:

xml映射的方式

通过在src目录下的WEB-INF下的web.xml配置Java文件的映射,注意只是针对Java文件。如下:

image.png
image.png

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  5. version="4.0">
  6. <servlet>
  7. <servlet-name>MyServlet</servlet-name>
  8. <servlet-class>com.simon.MyServlet</servlet-class>
  9. </servlet>
  10. <servlet-mapping>
  11. <servlet-name>MyServlet</servlet-name>
  12. <url-pattern>/myservlet</url-pattern>
  13. </servlet-mapping>
  14. </web-app>
  15. 注意:这里<servlet>是Java文件的全类名以及简称,这个简称是为了与下面的映射Servlet
  16. <servlet-mapping>一致。而<servlet-mapping>servlet映射是用户所要输入的应用名。
  17. 这样就保护了真正的Java文件不被发现而修改,却还能被访问到。
  18. 还有一点,当IDEA启动以后,浏览器默认的打开页面实际上是web目录。如果需要指定页面,
  19. 就需要手动输入更具体的应用。

对用户的响应如下:

  1. @Override
  2. public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
  3. System.out.println("service method...");
  4. servletResponse.setContentType("text/html;charset=UTF-8");
  5. servletResponse.getWriter().println("你好,这是我对你的响应");
  6. }

有个疑问

既然WEB-INF目录是不可访问的,那么当用户键入http://localhost:8080/eedemo_war_exploded/myservlet时,为什么可以通过WEB-INF/web.xml来访问到我写的Java类?
image.png

注解的方式

只需要在需要被访问类的头上加上注解,参数就是用户访问的应用名。
标准代码块A

  1. package com.simon;
  2. import javax.servlet.*;
  3. import javax.servlet.annotation.WebServlet;
  4. import java.io.IOException;
  5. @WebServlet("/myservlet")
  6. public class MyServlet implements Servlet {
  7. @Override
  8. public void init(ServletConfig servletConfig) throws ServletException {
  9. System.out.println("init method...");
  10. }
  11. @Override
  12. public ServletConfig getServletConfig() {
  13. return null;
  14. }
  15. @Override
  16. public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
  17. System.out.println("service method...");
  18. servletResponse.setContentType("text/html;charset=UTF-8");
  19. servletResponse.getWriter().println("你好,这是我对你的响应");
  20. }
  21. @Override
  22. public String getServletInfo() {
  23. return null;
  24. }
  25. @Override
  26. public void destroy() {
  27. System.out.println("destory method...");
  28. }
  29. }

上述两种配置方式结果完全一致,将myservlet与MyServlet全类名进行映射,即在浏览器的地址栏中间接访问demo就可以映射到MyServlet。

Servlet的生命周期

一次初始化,可以多次业务,然后一次销毁。

原理

参考标准代码块A,思考:我们如何调用service()方法的?MyServlet有没有创建对象?如果没有创建对象,那么它是如何调用MyServlet类中的方法的?
其实,答案就在Servlet的映射方式里。以xml映射方式为例,/myservlet需要映射的是MyServlet的全类名,这个全类名可以通过反射读取到构造器,它通过构造器创建对象,通过对象再去调用service方法,进而显示出来。
下面来证明这个答案是正确的:

  • 首先编写一个无参构造器,就是用来创建对象。既然是实例方法,那么无参构造器肯定是先执行
  • 执行完后再根据生命周期执行接下来的初始化、业务方法、销毁方法。当然业务方法可以执行多次。 ```java package com.simon;

import javax.servlet.*; import javax.servlet.annotation.WebServlet; import java.io.IOException;

@WebServlet(“/myservlet”) public class MyServlet implements Servlet {

  1. public MyServlet(){
  2. System.out.println("创建了Servlet对象");
  3. }
  4. @Override
  5. public void init(ServletConfig servletConfig) throws ServletException {
  6. System.out.println("init method...");
  7. }
  8. @Override
  9. public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
  10. System.out.println("service method...");
  11. servletResponse.setContentType("text/html;charset=UTF-8");
  12. servletResponse.getWriter().println("你好,这是我对你的响应");
  13. }
  14. @Override
  15. public void destroy() {
  16. System.out.println("destory method...");
  17. }

}

  1. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/22352513/1635947680873-cfd02b0d-adc5-42a3-971a-aadfd802e1d0.png#clientId=udeb96da1-78a3-4&from=paste&height=254&id=ua39b2eec&margin=%5Bobject%20Object%5D&name=image.png&originHeight=507&originWidth=1436&originalType=binary&ratio=1&size=142461&status=done&style=none&taskId=ua7be5e4b-a2f9-49cf-aabd-319cd3169fc&width=718)
  2. <a name="tpaUs"></a>
  3. ### 步骤
  4. - 当浏览器访问Servlet的时候,Tomcat会查询当前Servlet的实例化对象是否存在,如果存在,直接执行第三步;如果不存在,就通过反射机制动态创建对象。
  5. - 调用init方法完成初始化操作,这些操作包括写死用户名、密码,这样就可以不用去数据库中找;
  6. - 调用service方法完成业务逻辑操作
  7. - 关闭Tomcat时,会调用destory()方法,释放当前对象占用的资源。
  8. <a name="s6FJE"></a>
  9. ## 关于Servlet接口
  10. ```java
  11. public interface Servlet {
  12. void init(ServletConfig var1) throws ServletException;
  13. ServletConfig getServletConfig();
  14. void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
  15. String getServletInfo();
  16. void destroy();
  17. }

其中,ServletConfig是Servlet的基础配置信息相关的接口:

  1. public interface ServletConfig {
  2. String getServletName();//返回Servlet的全类名
  3. ServletContext getServletContext();//非常重要,重中之重
  4. String getInitParameter(String var1);//实际上是读取xml映射方式中init-parameter的参数
  5. Enumeration<String> getInitParameterNames();//取key-value的keySet,无序
  6. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  5. version="4.0">
  6. <context-param>
  7. <param-name>username</param-name>
  8. <param-value>all</param-value>
  9. </context-param>
  10. <servlet>
  11. <servlet-name>MyServlet</servlet-name>
  12. <servlet-class>com.simon.MyServlet</servlet-class>
  13. <init-param>
  14. <param-name>username</param-name>
  15. <param-value>admin</param-value>
  16. </init-param>
  17. <init-param>
  18. <param-name>password</param-name>
  19. <param-value>123456</param-value>
  20. </init-param>
  21. </servlet>
  22. <servlet-mapping>
  23. <servlet-name>MyServlet</servlet-name>
  24. <url-pattern>/myservlet</url-pattern>
  25. </servlet-mapping>
  26. </web-app>
  1. package com.simon;
  2. import javax.servlet.*;
  3. import java.io.IOException;
  4. import java.util.Enumeration;
  5. public class MyServlet implements Servlet {
  6. @Override
  7. public void init(ServletConfig servletConfig) throws ServletException {
  8. String sn = servletConfig.getServletName();
  9. System.out.println(sn); //com.simon.MyServlet
  10. //注意:这个参数是程序初始化的时候我们在xml映射文件中指定的参数
  11. //有啥用?可做校验
  12. String username = servletConfig.getInitParameter("username");
  13. System.out.println(username); //admin
  14. Enumeration<String> ipns = servletConfig.getInitParameterNames();
  15. while (ipns.hasMoreElements()){
  16. String s = ipns.nextElement();
  17. System.out.println(s);//password username,无序集合
  18. }
  19. //返回ServletContext对象,他是Servlet的上下文,整个Servlet的管理者,通过它可以拿到Servlet的所有信息
  20. ServletContext sc = servletConfig.getServletContext();
  21. String scn = sc.getServletContextName();
  22. System.out.println(scn); //null,当前应用的名称,在部署根目录下
  23. String cp = sc.getContextPath();
  24. System.out.println(cp); //eedemo_war_exploded,部署根目录的路径,即初始显示在哪
  25. String si = sc.getServerInfo();
  26. System.out.println(si); //Apache Tomcat/8.5.37,服务器信息
  27. String un = sc.getInitParameter("username");
  28. System.out.println(un); //all
  29. }
  30. @Override
  31. public ServletConfig getServletConfig() {
  32. return null;
  33. }
  34. @Override
  35. public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
  36. System.out.println("service method...");
  37. servletResponse.setContentType("text/html;charset=UTF-8");
  38. servletResponse.getWriter().println("你好,这是我对你的响应");
  39. }
  40. @Override
  41. public String getServletInfo() {
  42. return null;
  43. }
  44. @Override
  45. public void destroy() {
  46. }
  47. }

关于ServletConfig与ServletContext的区别

ServletConfig作用于某个Servlet实例,每个Servlet都有对应的ServletConfig;ServletContext作用于整个Web应用,一个Web应用对应于一个ServletContext,多个Servlet实例对应一个ServletContext。总之,可以理解为一个全局对象,一个局部对象。

Servlet的层次结构

Servlet是最顶层的抽象接口,我们日常开发中使用最多的是HttpServlet类,体系是:Servlet—>GenericServlet—>HttpServlet,Http请求类型有很多种,常用四种:

  • GET
  • POST
  • PUT
  • DELETE

由于日常业务也就是增删改查,这四种请求分别是读取、保存、修改、删除,恰好满足日常开发所需请求。

  1. package com.example.mytomcat001;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.annotation.WebServlet;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. @WebServlet("/hs")
  9. public class TestServlet extends HttpServlet {
  10. @Override
  11. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  12. resp.getWriter().write("my httpServlet...");
  13. }
  14. @Override
  15. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  16. super.doPost(req, resp);
  17. }
  18. }

这里HttpServlet相对于Servlet的好处:
①省去了大量不必要重写的方法,比如init()、getServletConfig()、getServletInfo()、destroy()
②由于使用最多的是service()方法,具体到HttpServlet类,将service方法又具体进一步拆解,子类可根据请求方式的不同继承自己需要的方法,颗粒度更细。
由于我们在地址栏输入的请求是属于Get请求,并且是使用频率最高的一种请求了。实际上,日常开发中为了便于模拟请求,我们可以用Postman工具来模仿客户端发送请求。
https://zhuanlan.zhihu.com/p/30266849)接口文档管理工具。

模拟HttpServlet的实现过程

总的思路就是,GenericServlet实现了Servlet接口,同时为它的子类屏蔽了不常用的方法,子类只需要重写service方法即可。HttpServlet继承GenericServlet,根据请求类型进行分发处理,Get进入DoGet方法,Post进入doPost方法,开发者自定义的Servlet类只需要继承HttpServlet即可,重写doGet和doPost。

第一层,实现Servlet接口

  1. package com.example.achServlet;
  2. import javax.servlet.*;
  3. import java.io.IOException;
  4. public class MyGenericServlet implements Servlet {
  5. @Override
  6. public void init(ServletConfig config) throws ServletException {
  7. }
  8. @Override
  9. public ServletConfig getServletConfig() {
  10. return null;
  11. }
  12. @Override
  13. public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
  14. }
  15. @Override
  16. public String getServletInfo() {
  17. return null;
  18. }
  19. @Override
  20. public void destroy() {
  21. }
  22. }

第二层,只继承父类的service方法

  1. package com.example.achServlet;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.ServletRequest;
  4. import javax.servlet.ServletResponse;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. //通过继承的方式,把我们不需要的四个父类方法全部屏蔽掉了
  9. public class MyHttpServlet extends MyGenericServlet{
  10. @Override
  11. public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
  12. HttpServletRequest request = (HttpServletRequest) req;
  13. HttpServletResponse response = (HttpServletResponse) res;
  14. //获取请求类型
  15. //可以通过打断点方式,知道请求方式有get、put、delete、post等
  16. String method = request.getMethod();
  17. //根据请求类型完成分发
  18. switch (method){
  19. case "Get":
  20. this.doGet(request,response);
  21. break;
  22. case "Post":
  23. this.doPost(request,response);
  24. break;
  25. }
  26. }
  27. public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException {
  28. }
  29. public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException {
  30. }
  31. }

第三层,实现自定义业务

  1. package com.example.achServlet;
  2. import javax.servlet.annotation.WebServlet;
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5. import java.io.IOException;
  6. @WebServlet("/test")
  7. public class MyTestServlet extends MyHttpServlet{
  8. @Override
  9. public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
  10. response.getWriter().write("TestGet");
  11. }
  12. @Override
  13. public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
  14. response.getWriter().write("TestPost");
  15. }
  16. }

5、JSP

简述

在做开发中,有两个组件非常重要,一个Servlet,一个JSP。
JSP本质上就是一个Servlet。JSP主要负责与用户交互,将最终的页面呈现给用户,是HTML+JS+CSS+JAVA的混合文件。
image.png
image.png
如果要显示一个“Hello,World”的页面,用Servlet方式如上,但是这样做代码显得非常繁杂,并不实际。正是由于这样的需求,导致JSP的诞生。下面截图是JSP转成Servlet的方法:
image.png
image.png

本质

本质上,我们通过JSP能看到页面的原因是,JSP并不是HTML代码,我们只是把HTML代码写到JSP文件里,最终把JSP转成Servlet,Servlet再通过它的write方法把HTML写好的代码一行一行输出,最终看到结果。虽然我们在index.jsp同级目录下随便写一个a.html,客户端也能访问到,但这并不意味着HTML的胜利,因为HTML并不能写Java代码,也就意味着不能传输数据。所以,JSP是不可被替代的。
当服务器接到一个后缀是jsp的请求时,将该请求交给jsp引擎去处理,每一个jsp页面第一次被访问的时候,jsp引擎会将其翻译成一个Servlet文件,由Web容器来调用Servlet完成响应。单纯从开发角度讲,JSP就是在HTML中嵌入Java程序。具体的嵌入方式有三种:

1、JSP脚本

执行Java逻辑代码。

  1. <% Java代码 %>
  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <%
  8. String name = "Hello,World!";
  9. System.out.println(name);
  10. %>
  11. </body>
  12. </html>

2、JSP声明

定义Java方法。

  1. <% !
  2. 声明 Java方法
  3. %>
  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <%!
  8. public String test(){
  9. return "HelloWorld";
  10. }
  11. %>
  12. <%
  13. test();
  14. %>
  15. </body>
  16. </html>

3、JSP表达式

把Java对象直接输出到HTML页面中。

  1. < % = Java 变量 %>
  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <%!
  8. public String test(){
  9. return "HelloWorld";
  10. }
  11. %>
  12. <%
  13. String str = test();
  14. %>
  15. <%=str%>
  16. </body>
  17. </html>

JSP内置对象

9个。对应常见数据类型:

  • request 表示一次请求,由HttpServletRequest产生
  • response 表示一次响应,由HttpServletResponse产生
  • pageContext 页面上下文,获取页面信息,来自PageContext类
  • session 表示一次会话,保存用户信息,HTTPSession。例如打一次电话(可有多个request和response)
  • application 表示当前Web应用,全局对象,保存所有用户共享信息,来自ServletContext类
  • config 当前JSP对应的Servlet的ServletConfig对象,获取当前Servlet的信息。
  • out 来自JspWriter类,向浏览器输出数据
  • page 当前JSP对应的Servlet对象,Servlet
  • exception 表示JSP页面发生的异常

常用的是:request、response、session、application、pageContext

request常用方法

1、String getParameter( String ); //获取请求参数(浏览器—>服务端)

  1. package com.example.exer;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.http.HttpServlet;
  4. import javax.servlet.http.HttpServletRequest;
  5. import javax.servlet.http.HttpServletResponse;
  6. import java.io.IOException;
  7. public class HelloServlet extends HttpServlet {
  8. @Override
  9. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  10. String id = req.getParameter("id");
  11. int i = Integer.parseInt(id);
  12. System.out.println(i);
  13. }
  14. }
  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <%
  8. String id = request.getParameter("id");
  9. %>>
  10. <%=id%>
  11. </body>
  12. </html>

2、void setAttribute(String key,Object value) //通过键值对来保存数据(服务端A—>服务端B)

3、void getAttribute(String key) //通过key来取出value

传递参数为:localhost:8080/test1.jsp?id=1

  1. //test1.jsp文件
  2. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  3. <html>
  4. <head>
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <%
  9. String idStr = request.getParameter("id");
  10. int id = Integer.parseInt(idStr);
  11. id++;
  12. //将数据存入request中
  13. request.setAttribute("number",id);
  14. //将请求转发给test2.jsp
  15. request.getRequestDispatcher("test2.jsp").forward(request,response);
  16. %>
  17. <%=id%>
  18. </body>
  19. </html>
  1. //test2.jsp文件
  2. <%--
  3. Created by IntelliJ IDEA.
  4. User: Simon
  5. Date: 2021/11/4
  6. Time: 14:53
  7. To change this template use File | Settings | File Templates.
  8. --%>
  9. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  10. <html>
  11. <head>
  12. <title>Title</title>
  13. </head>
  14. <body>
  15. <%
  16. Integer number = (Integer) request.getAttribute("number");
  17. System.out.println(number); //2
  18. %>
  19. </body>
  20. </html>

image.png

4、RequestDispatcher getRequestDispatcher(String path) //返回一个RequestDispatcher对象,该对象的forward方法用于转发请求

5、String[ ] getParameterValues() //获取客户端传来的多个同名参数

请求参数是:localhost:8080/test1.jsp?name=zs&name=ls&name=ww

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <%
  8. request.setCharacterEncoding("UTF-8");
  9. String[] names = request.getParameterValues("names");
  10. %>>
  11. <%=Arrays.toString(names)%> //[zs,ls,ww]
  12. </body>
  13. </html>

6、void setCharacterEncoding(String charset) //指定每个请求的编码

见5.

Http请求状态码

  • 200 正常
  • 404 资源找不到
  • 400 请求类型不匹配
  • 500 Java程序抛出异常

response常用方法(有杂音)

1、sendRedirect(String path) //重定向

与RequestDispatcher getRequestDispatcher(String path) 类似,都是将数据从一个页面传递到另一个页面,但不同的是,转发是将同一个请求传给下一个页面, 重定向是创建一个新的请求给下一个页面(可能会报空指针异常)之前的页面请求会结束生命周期。
转发:同一请求在服务器之间传递,地址栏不变,也叫服务器跳转。
重定向:由客户端发送一次新的请求来访问跳转后的目标资源,地址栏改变,也叫客户端跳转。
如果两个页面之间需要通过request来传值,则必须使用转发,不能使用重定向。

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <h1>Forward</h1>
  8. <%
  9. request.setAttribute("name","tom");
  10. request.getRequestDispatcher("target.jsp").forward(request,response);
  11. response.sendRedirect("target.jsp");
  12. %>
  13. </body>
  14. </html>
  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <h1>Target</h1>
  8. <%
  9. String name = (String)request.getAttribute("name");
  10. out.write(name);
  11. %>
  12. <%=name%>
  13. </body>
  14. </html>

一个登录案例

用户登录,如果用户名和密码都正确,则跳转到首页(转发),并且展示用户名,否则重新回到登录页面(重定向)。注:地址栏:localhost:8080//username=admin&password=123123

  1. //login.jsp文件
  2. <%--
  3. Created by IntelliJ IDEA.
  4. User: Simon
  5. Date: 2021/11/4
  6. Time: 15:40
  7. To change this template use File | Settings | File Templates.
  8. --%>
  9. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  10. <html>
  11. <head>
  12. <title>Title</title>
  13. </head>
  14. <body>
  15. <form action="/check.jsp" method="post">
  16. 用户名:<input type="text" name="username"><br>
  17. 密码:<input type="password" name="password"><br>
  18. <input type="submit" value="登录">
  19. </form>
  20. </body>
  21. </html>
  1. //check.jsp文件
  2. <%--
  3. Created by IntelliJ IDEA.
  4. User: Simon
  5. Date: 2021/11/4
  6. Time: 15:42
  7. To change this template use File | Settings | File Templates.
  8. --%>
  9. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  10. <html>
  11. <head>
  12. <title>Title</title>
  13. </head>
  14. <body>
  15. <%
  16. String username = request.getParameter("username");
  17. String password = request.getParameter("password");
  18. if ("admin".equals(username)&&"123123".equals(password)){
  19. request.setAttribute("name",username);
  20. request.getRequestDispatcher("welcome.jsp").forward(request,response);//欢迎回来!admin
  21. // response.sendRedirect("welcome.jsp"); //欢迎回来!null
  22. }else {
  23. response.sendRedirect("login.jsp");
  24. }
  25. %>
  26. </body>
  27. </html>
  1. //welcom.jsp文件
  2. <%--
  3. Created by IntelliJ IDEA.
  4. User: Simon
  5. Date: 2021/11/4
  6. Time: 15:47
  7. To change this template use File | Settings | File Templates.
  8. --%>
  9. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  10. <html>
  11. <head>
  12. <title>Title</title>
  13. </head>
  14. <body>
  15. <%
  16. String name = (String) request.getAttribute("name")
  17. %>
  18. 欢迎回来!
  19. </body>
  20. </html>