JavaWeb学习笔记
本文最后更新于 182 天前,其中的信息可能已经有所发展或是发生改变。

关于Tomcat

tomcat的组成结构

<Server>      顶层元素
    <Service>     
        <Connector />     和客户实时交互进行连接的组件
        <Engine>      处理同一个service中所有Connector接收到的客户请求
            <Host>        定义虚拟主机 其中包含一个或多个Javaweb应用
                <Context>     使用最频繁的元素,代表运行在虚拟主机上的单个javaweb应用
                </Context>
            </Host>
        </Engine>
    </Service>
</Server>

在以上XML代码中,每个元素都代表一种 Tomcat组件。这些元素可分为四类:

  • 顶层类元素

    包括< Server元素和< Service>元素,它们位于整个配置文件的顶层。

  • 连接器类元素

    为< Connector>元素,代表介于客户与服务器之间的通信接口,负责将客户的请求发送给服务器,并将服务器的响应结果发送给客户。

  • 容器类元素

    代表处理客户请求并生成响应结果的组件,有四种容器类元素,分别为< Engine>、、< Context>和< Cluster>元素。 Engine组件为特定的 Service组件处理所有客户请求, Host组件为特定的虚拟主机处理所有客户请求, Context组件为特定的Web应用处理所有客户请求。 Cluster 3组件负责为 Tomcat集群系统进行会话复制、 Context组件的属性的复制,以及集群范围内WAR文件的发布。本书第26章的26.5节( Tomat集群)对配置 Tomcat集群系统做了进一步介绍。

  • 嵌套类元素

    代表可以嵌入到容器中的组件,如元素和< Realm>元素等

    Tomcat各个组件之间的嵌套关系

    上图表明, Connector组件负责接收客户的请求并向客户返回响应结果,在同一个Service组件中,多个 Connector组件共享同一个 Engine组件。同一个 Engine组件中可以包含多个Host组件,同一个Host组件中可以包含多个 Context组件。

关于servlet

Servlet API中主要接口与类的框图

javax.servlet.Servlet接口

Servlet API的核心是 Javax.servlet.Servlet接口,所有的 Servlet类都必须实现这一接口。
在 Servlet接口中定义了5个方法, 其中有3个方法都由 Servlet容器来调用,容器会在 Servlet 的生命周期的不同阶段调用特定的方法

  • init(Servletconfig config)方法:该方法负责初始化 Servlet对象。容器在创建好 Servlet 对象后,就会调用该方法。
  • service( Servletrequest req, Servletresponse res)方法:负责响应客户的请求,为客户提供相应服务。容器接收到客户端要求访问特定 Servlet对象的请求时,就会调用该 Servlet对象的 service方法。
  • destroy()方法:负责释放 Servlet对象占用的资源。当 Servlet对象结東生命周期时容器会调用此方法。

Servlet接口还定义了以下两个返回 Servlet的相关信息的方法。 Java Web应用中的程序代码可以访问 Servlet I的这两个方法,从而获得 Servlet的配置信息以及其他相关信息:

  • getservlet Config():返回一个 Servletconfig对象,该对象中包含了 Servlet I的初始化参数信息。
  • getservletlnfo():返回一个字符串,该字符串中包含了 Servlet I的创建者、版本和版权等信息

GenericServlet 抽象类

这个抽象类是Servlet接口的通用实现,与任何网络应用层协议无关;这个类运用了装饰设计模式,为自己附加了ServletConfig身份(就是同时继承了ServletConfig接口)

HttpServlet 抽象类

这个抽象类是GenericServlet的子类,为Servlet接口提供了与HTTP协议相关的通用实现;开发Java web 应用时自定义的servlet类一般都继承自这个类

  • 在默认实现类中 默认的doGET(),doPOST等方法默认都是只报一个错,所以子类如果用到需要重写
  • 为了doXXX()方法能够被Servlet容器访问,应把访问权限设定为public。

转发、包含与重定向

WEB应用在响应客户端的一个请求时,有可能响应过程很复杂,需要多个Web组件共同协作,才能生成响应结果。尽管一个servlet对象无法直接调用另一个servlet对象的service()方法,但是servlet规范为Web之间的写作提供了两种途径,即转发与包含

转发与包含

  • 请求转发: Servlet(源组件)先对客户请求做一些预处理操作,然后把请求转发给其他Web组件(目标组件)来完成包括生成响应结果在内的后续操作
  • 包含: Servlet(源组件)把其他Web组件(目标组件)生成的响应结果包含到自身的响应结果中。
  • 请求转发与包含具有以下共同特点源组件和目标组件处理的都是同一个客户请求,源组件和目标组件共享同一个Servletrequest对象和 Servletresponse对象。
  • 目标组件都可以是 Servlet、JSP或HTML文档。
  • 都依赖 javax. servlet. RequestDispatcher接口。
javax.servlet.RequestDispatcher接口

这个接口是一个请求分发器,有两个方法:

  • forward(req, res)方法:把请求转发给目标组件
  • include(req, res)方法:包含目标组件的响应结果

Servlet可以通过两种方式得到RequestDispatcher对象:

  • 调用ServletContext的getRequestDispatcher(String path)方法,此处path指的是指定目标组件的绝对路径
  • 调用ServletRequest的getRequestDispatcher(String path)方法,此处path则可以绝对路径也可相对路径

此处的绝对路径指以"/"开头的路径,"/"代表当前Web应用的URL入口

而相对路径则是相对于当前源servlet的路径,不以"/"开头

转发的特点
  • forward()方法会先清空用于存放响应正文数据的缓冲区,所以源组件生成的响应结果不会被发送到客户端,只有目标组件的响应可以发送到客户端
  • 如果源组件中在请求转发之前提交了响应结果(如调用了ServletResponse的flushBuffer()方法,或者与ServletResponse关联的输出流的close()方法),则forward()方法会抛出IllegalStateException异常。

包含

  • 可以包含servlet或Jsp或HTML文件;
  • 如果目组件是JSP或servlet,就调用他们相应的service()方法,把该方法产生的正文响应添加到源组件的响应结果中;
  • 如果目标组件是HTML,就直接把文档的内容添加到源组件的响应结果之中。
  • 包含组件执行完毕之后会回到源组件继续执行后续代码块
  • 在目标组件中对响应状态代码或相应头的更改会被忽略

重定向

重定向与前两种有一定的区别,前两者属于服务器动作,对于浏览器端是完全不可见的,但是重定向是HTTP协议中规定的一种机制,是服务器与浏览器协作完成的;

运作流程
  1. 用户在浏览器端输入特定URL,请求访问服务器端的某个组件。
  2. 服务器端的组件返回一个状态代码为302的响应结果,该响应结果的含义为:让浏览器端再请求访问另一个Web组件。响应结果中提供了另一个Web组件的URL。另一个Web组件有可能在同一个Web服务器上,也有可能不在同一个Web服务器上。
  3. 浏览器端接收到这种响应结果后,再立即自动请求访问另一个Web组件。
  4. 浏览器端接收到来自另一个Web组件的响应结果。
特点
  • HttpServletResponse接口的sendRedirected(String location)方法用于重定向
  • Servlet源组件生成的响应结果不会被发送到客户端,只有重定向的目标组件生成的响应结果才会被发送到客户端。
  • 如果源组件在进行重定向之前,已经提交了响应结果(例如调用 ServletResponse 的 flushBuffe()方法,或者调用与 ServletResponse关联的输出流的 close()方法),那么 sendRedirecto方法会抛出 IllegalStateException异常。为了避免该异常,不应该在源组件中提交响应结果。
  • 源组件和目标组件不共享同一个 ServletRequest对象,因此不共享请求范围内的共享数据。
  • 对于 response. sendRedirect( String location)方法中的参数 location,如果以“/”开头, 表示相对于当前服务器根路径的URL,如果以“http//"开头,表示一个完整的URL 目标组件不必是同一个服务器上的同一个Web应用中的组件,它可以是 Internet上的任意一个有效的网页。

关于java web应用

新版 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"
         metadata-complete="true">

</web-app>

servlet的依赖包

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

编写servlet的映射

这部分内容也写在web.xml中

为什么要映射

我们写的是Java程序,而Javaweb需要浏览器来进行访问,而浏览器要链接的是web服务器,所以要在web服务器中注册我们所写的servlet,同时还需要给一个浏览器可以访问的路径(url)

<!--  注册servlet-->
<servlet>
  <servlet-name>hello</servlet-name>
  <servlet-class>cn.tars.servlet.HelloServlet</servlet-class>   
</servlet>
<!--  servlet的请求路径-->
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
<!--    此时输入hello就会走servlet-->
  </servlet-mapping>

servlet中的mapping

这个值是用于指定访问相应Java程序的URL的,可以使用通配符
所以,可以有多个url指向一个java程序等等花式操作;(这也是为什么要进行映射二不是直接在域名中使用.class文件名的原因之一)
同时,当通配符与精准域名冲突时(如/hello与/\
),默认会使用精确的域名(即/hello),也就是越精确优先级越高。

tomcat查找相应class文件的过程

  1. 当浏览器首次通过localhost:8080/XXXX/hello时,需要加载相应的servlet类
  2. 首先参考web.xml,找到 子元素的值为/hello的元素
  3. 读取元素的的子元素的值,由此确定Servlet的类名为hello
  4. 找到子元素的值为hello的元素
  5. 读取该元素的子元素的值,由此确定Servlet的类名为cn.tars.servlet.HelloServlet
  6. 去/WEB-INF/classes/cn.tars.servlet目录下查找HelloServlet.class文件

servlet元素的子元素

servlet元素的子元素

关于JSP

JSP声明

<%! 内容 %>

可以在此声明JSP对应的servlet类的成员变量和方法

图片alt

java程序片段(Scriptlet)

<% 内容 %>

可以在此处插入任何有效的Java程序代码;如果没有在jsp的page指令中指定method属性,那么这些程序片段默认就是属于对应servlet类中的service()方法中。
在这里甚至可以java代码与格式化文本穿插,格式化文本实际上就相当于out.println中意图打印在浏览器中的东西

图片alt

Java表达式

<%= 内容 %>

这里可以把java表达式的值输出到网页上,会自动调用表达式对象的tostring()方法。

隐含对象

Servlet容器提供的ServletContext、ServletRequest、ServletResponse等对象在JSP中使用固定的引用变量来引用这些对象

图片alt

图片alt

JSP请求转发

<jsp:forward page="转发的目标组件的绝对或相对URL" />

该标签之后的语句均不会被执行

包含

静待包含

<%@ include file="被包含组件的相对URL或绝对URL" %>

在JSP文件的解析过程中,被包含的目标文件中的内容会被原封不动地添加进源JSP组件中,然后Servlet容器再对JSP源组件进行翻译和编译;

静态包含的目标组件可以是HTML或者JSP文件,不能是servlet文件

动态包含

<jsp:include page = "被包含组件的绝对URL或相对URL"

动态包含发生在运行JSP源组件阶段,动态包含的目标组件可以为HTML 文件、JSP文件或者为 Servlet。如果目标组件为JSP, Servlet容器会在运行JSP源组件的过程中,运行与JSP目标组件对应的 Servlet的服务方法。JSP目标组件生成的响应结果被包含到JSP源组件的响应结果中。

  • Java包名是不允许有特殊符号的,idea会自动将不合法的包名视为普通文件夹且没有提示

    基础不牢地动山摇?

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇