发布时间:2023-04-22 文章分类:WEB开发, 电脑百科 投稿人:赵颖 字号: 默认 | | 超大 打印

概述

web 服务器、项目、资源概述

web 服务器:可以被浏览器访问到的服务器

常见的 web 服务器:

web 项目: 部署在 web 服务器上面,可以被浏览器直接访问到的项目,特点:项目的结构得按照指定规则

web 资源

软件的架构

网络中有很多的计算机,它们直接的信息交流,称之为:交互。

在互联网交互的过程的有两个非常典型的交互方式 —— B/S 交互模型和 C/S 交互模型。

相同点: 都需要和服务器进行数据交互,都是先有请求,后给响应,一定是请求和响应成双成对

Tomcat 服务器

Tomcat 的目录结构

bin		里面存放的都是tomcat的二进制命令  关注点:开启服务: startup.bat   关闭服务:shutdown.bat
conf	里面存放的都是tomcat的配置文件   关注点:server.xml(配置端口) web.xml
lib		里面存放的都是tomcat运行过程中提供支撑的jar包
logs	里面存放的都是日志文件  关注点:错误信息的日志文件查看 catalina.2020-xx-xx.log
temp	里面存放的是tomcat运行过程中创建的临时文件 由tomcat维护
work	里面存放的内容和jsp相关
webapps(核心)	用来存放web项目 存放在这个里面的项目可以被浏览器直接访问到 http://localhost:8080 --> webapps文件夹下

虚拟路径发布项目

方式1:配置独立xml文件

  1. 在 tomcat/conf 目录下新建一个 Catalina 目录(如果已经存在无需创建)

  2. 在 Catalina 目录下创建 localhost 目录(如果已经存在无需创建)

  3. 在 localhost 中创建 xml 配置文件,名称为:xxx.xml(xxx名就是项目的浏览器访问别名)

    xxx.xml中代码如下:

    <Context docBase="项目所在的硬盘位置" />
    

好处:使用配置文件对项目的部署和卸载不用重启 tomcat 了,也不影响 tomcat 整体的配置文件

方式2:配置 server.xml,添加 context 标签

在 server.xml 配置文件的最后加上如下代码:

<Context path="项目的浏览器访问别名" docBase="项目所在的硬盘位置" />

注意:谨慎使用(最好单独独立出来一个配置文件)

电脑安装 Tomcat(了解)

在电脑安装一个 tomcat 软件,将电脑变成 web 服务器,步骤:

  1. 下载一个 tomcat 服务器软件,官网地址 http://tomcat.apache.org
  2. 解压下载好的 tomcat。注意:将解压后的文件 copy 到一个没有中文和空格的路径下
  3. 启动 tomcat 服务:进入 bin 路径,双击 startup.bat 服务器就可以启动(默认占用电脑的8080端口)
  4. 测试:在页面输入地址访问 http://localhost:8080
  5. 关闭 tomcat 服务:直接关闭 或者去 bin 路径双击 shutdown.bat

Tomcat启动的常见问题总结

1、一闪而过
原因:没有配置环境变量JAVA_HOME 或者配置错误
解决:配置环境变量JAVA_HOME,因为tomcat在启动的时候会去找环境变量JAVA_HOME
Tomcat的底层需要JDK的支撑
	JAVA_HOME=jdk的安装路径(不要加bin目录)
	path=%JAVA_HOME%\bin
2、报错 java.net.BindException:  Address already in use: bind
原因:端口号被占用
解决:
	方式1:结束正在占用端口的进程
		1) netstat -ano 查看端口对应的pid
		2) 打开任务管理器 结束pid对应的进程
    方式2:改变自己的端口号
    	修改conf文件夹中的server.xml  大概在69行的位置
    	或者修改端口号为80: 80是默认端口号.可以不写

idea 集成 Tomcat 环境(了解)

idea 自动用的是虚拟路径的方式给 tomcat 管理的

idea集成tomcat步骤:

Java Web 项目入门指南(http、Servlet、Request、Response、ServletContext、会话技术[cookie、session]、Filter、Listener)

Java Web 项目入门指南(http、Servlet、Request、Response、ServletContext、会话技术[cookie、session]、Filter、Listener)

idea创建web项目:

Java Web 项目入门指南(http、Servlet、Request、Response、ServletContext、会话技术[cookie、session]、Filter、Listener)

idea发布项目:

Java Web 项目入门指南(http、Servlet、Request、Response、ServletContext、会话技术[cookie、session]、Filter、Listener)

Http协议

概念及作用

概念

协议:规定了被约束对象都需要去遵守的规则

http协议:

作用:

Java Web 项目入门指南(http、Servlet、Request、Response、ServletContext、会话技术[cookie、session]、Filter、Listener)

请求内容:请求行 请求头 请求体

请求内容分为:

响应内容:响应行 响应头 响应体

响应内容分为:

get 提交和 post 提交的区别

Java web 项目

项目的结构

在 JavaEE 规范中,WEB 项目存在一定的目录结构,具体结构如

   web项目(myweb)
	|| ------ 静态资源(如html、css、js、img等)、二级目录等
	||
	|| 
	|| ------ WEB-INF目录(放在该目录下的资源浏览器是不能直接访问到)
		|| ------ classess目录:放的都是java代码的 .class
		|| ------ lib目录:放入项目需要的jar
		|| ------ web.xml:配置文件(配置的是项目的内容) 是tomcat首先会去加载的配置文件
				    servlet如果是2.5的版本这个web.xml文件必须有
				    servlet如果是3.0的版本这个web.xml文件可以不要  用注解代替

三大技术:Servlet、Filter、Listener

java web 项目服务器有三大技术:Servlet、Filter、Listener

Servlet

概述

Servlet 运行在服务端的 Java 小程序,是 sun 公司提供一套规范,用来处理客户端请求、响应给浏览器的动态资源。

servlet 的实质就是 java 代码,通过 java 的 API 动态的向客户端输出内容。

servlet 的作用

servlet 与普通的 java 程序的区别:

快速入门

**servlet2.5 的方式:**必须有 web.xml 配置文件

三个步骤创建一个 servlet:

  1. 创建一个类实现 servlet 接口

  2. 重写 service 方法

  3. 在 web.xml 文件中配置创建的类(将请求路径和 java 程序的对应关系建立起来)

    tomcat 只要一启动,就会去加载 web.xml 文件,只加载一次

    只要这个 web.xml 配置文件修改了任何一处,都要重新 tomcat 重新加载

    servlet 的创建和服务方法、service 的执行都是由 tomcat 自动完成

servlet3.0 的方式:没有web.xml配置文件

步骤:

  1. 创建 JavaEE6(含6) 以上的工程

  2. 创建一个类实现 servlet 接口,并在实现类上标注 @WebServle 注解

    @WebServlet 注解的属性:

    • name 属性:servlet名称,相当于web.xml中的<servlet‐name>
    • urlPatterns 属性:请求路径

    示例:@WebServlet(name = “HelloServlet”, urlPatterns = “/hello”)

servlet 的生命周期

一个对象从创建到消亡的过程,就是生命周期。

和 servlet 的生命周期相关的 3 个方法:

// Servlet对象只要一创建出来就会调用的方法  
void init(ServletConfig var1)
// 处理浏览器交互的方法  
void service(ServletRequest var1, ServletResponse var2)
// 销毁的方法
void destroy()

Servlet 的生命周期:

Java Web 项目入门指南(http、Servlet、Request、Response、ServletContext、会话技术[cookie、session]、Filter、Listener)

servlet 的体系结构

Servlet 的配置

url-pattern(路径规则)配置

在创建 servlet 后,如果想要这个 servlet 可以被访问到,必须在 web.xml 文件中对其进行配置。

url-pattern 标签就是用于确定访问一个 servlet 的路径

示例:

 <servlet>
        <servlet-name>ServletDemo1</servlet-name>
        <servlet-class>cn.itcast.web.ServletDemo1</servlet-class>
 </servlet>
 <servlet-mapping>
        <servlet-name>ServletDemo1</servlet-name>
        <url-pattern>/sd1</url-pattern>
        <url-pattern>/sd2</url-pattern>
        <url-pattern>/sd3</url-pattern>
        <url-pattern>/sd</url-pattern>
</servlet-mapping>
<servlet-mapping>
      <servlet-name>ServletDemo2</servlet-name>
      <!-- 完全匹配 -->
      <url-pattern>/aaa</url-pattern> 
</servlet-mapping>
<servlet-mapping>
      <servlet-name>ServletDemo3</servlet-name>
      <!-- 扩展名匹配 -->
      <url-pattern>*.do</url-pattern>
</servlet-mapping>

注:

load-on-startup(优先级)配置

load-on-startup 标签可以设置 servlet 的加载优先级别和容器是否在启动时加载该 servlet

示例:

<servlet>
        <servlet-name>ServletDemo1</servlet-name>
        <servlet-class>cn.itcast.web.ServletDemo1</servlet-class>
        <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
        <servlet-name>ServletDemo1</servlet-name>
        <url-pattern>/*</url-pattern>
</servlet-mapping>

注:

Servlet 的路径

servlet 的访问路径分为 2 种:

Servlet 相关对象

HttpServletRequest 请求对象

概述

HttpServletRequest 对象代表浏览器端的请求,当浏览器端通过 HTTP 协议访问服务器时,HTTP 请求中的所有信息都封装在这个对象中,开发人员通过这个对象的 api,可以获得客户通过浏览器传递过来的数据。

HttpServletRequest 对象的作用:封装浏览器的请求数据(请求行、请求头 、请求体)

Java Web 项目入门指南(http、Servlet、Request、Response、ServletContext、会话技术[cookie、session]、Filter、Listener)

API

HttpServletRequest extends ServletRequest

获取请求行数据(请求方式、访问的资源、协议版本)

// 获取请求方式
String getMethod()
// 获取请求行中的资源名部分
String getRequestURI()
// 获取客户端请求完整URL
StringBuffer getRequestURL()
// 获取请求协议和版本
String getProtocol()
// 获取端口
int getLocalPort()
// 获取请求者的ip地址
String getRemoteAddr()
// 获取当前的项目名路径
String getContextPath()

获取请求头数据(键值对 key/value 的数据)

// 根据请求头的key获取value
String getHeader(String key)
	// 例如:Referer可以获取到来源地址(没有来源为null:直接访问) --防盗链
	// 例如:User-Agent可以获取用户的浏览器版本信息  --下载必备、处理下载乱码的
// 返回此请求包含的所有头名称 
Enumeration getHeaderNames()

获取请求体数据(所有浏览器提交的表单数据)

// 获取单一name对应的value值
String getParameter(String name)  
// 获取多个name对应的多个value值
String[]  getParameterValues(String name)  
// 获取页面所有的value值
Map<String,String[]>  getParameterMap() 
	// 注意:key:对应的是表单中name属性名,value对应的的是表单的name属性的value值
// 设置编码。一般设置为 utf-8,否则请求中中文可能会乱码
void setCharacterEncoding(String var1)

作为容器数据存取删(request 也被称为域对象)

// 存储数据
void setAttribute(String name, Object o)
// 获取数据
Object getAttribute(String name)
// 移除数据
void removeAttribute(String name)

注意:若想要在多个 servlet 之间的使用 request 传递数据,则需要保证多个 servlet 之间使用的是同一个 request 对象,可以使用请求转发。

request.getRequestDispatcher("/servlet的地址").forward(request, response);

HttpServletResponse 对象

概述

HttpServletResponse 对象:服务器用来给浏览器写内容的一个对象

服务器有数据如果想给浏览器:只能按照 http 协议的规定通过3个方向给:响应行、响应头、响应体

API

ServletContext 对象

概述

ServletContext:servlet 的上下文对象(全局管理者对象),是一个全局的储存信息的空间。

一个 web 项目只有一个全局管理者(SevletContext对象)

API

原生获取 ServletContext 对象

在继承 HttpServlet 或 GenericServlet 的自定义类中,直接通过父类方法 getServletContext() 获取 ServletContext 对象

public ServletContext getServletContext()

Spring 项目获取 ServletContext 对象

操作 ServletContext 对象

数据存取操作:保存在 ServletContext 中的数据是项目全局共享的数据,可以用来在多个 servlet 之间传递信息数据

// 存。特点:可以存多对 但是存在key值覆盖
void setAttribute(String name, Object value)
// 取。特点: \没取到返回null  
Object getAttribute(String name)
// 删
void removeAttribute(String name)

读取项目资源的方法

// 获取WEB项目的磁盘路径。场景:上传
String getRealPath(String path)   
// 根据WEB项目的磁盘资源获取流。场景:下载
InputStream getResourceAsStream(String path)
// 获取web.xml中<context>标签的参数内容 
String getInitParameter(String name)

会话技术:cookie、session

概述

会话技术的作用:是用来存储会话过程中,浏览器和服务器交互产生的N多数据的

会话技术的分类:

使用 cookie 或 session 去存储浏览器和服务器交互中产生的数据的场景:

cookie:客户端的会话技术

概述

作用:存储数据进行传递的

特点:

cookie 的整个使用过程(完成私人数据在多个 servlet 之间进行数据传递):

  1. 服务器创建 cookie 存储数据 ==> 把整个 cookie 传递给浏览器 ==> 浏览器端自动保存 cookie(key值会覆盖)
  2. 再次访问:浏览器会自动将保存的 cookie 传递服务器资源 ==> 服务器获取传递的 cookie 数据 ==> 使用 cookie 数据

cookie的应用场景

注意:

常用方法

Cookie

// 创建cookie对象
Cookie(String name, String value)
// 获取cookie的名称
String getName()
// 获取cookie的值
String getValue()
// 设置cookie的最大生存时间(单位:秒),超过了该时间后Cookie会自动销毁
void setMaxAge(int expiry) 
// 设置cookie的有效路径。浏览器根据这个路径判断在访问哪些资源时携带该cookie给服务器
void setPath(String uri) 

HttpServletResponse

// 将cookie发送给浏览器。注意:服务器可以给浏览器传递多个cookie,浏览器都会保存,但存在key值覆盖
void addCookie(Cookie cookie)

HttpServletRequest

// 获取浏览器发送的cookie
Cookie[] getCookies()

注意:

cookie 技术原理分析

Java Web 项目入门指南(http、Servlet、Request、Response、ServletContext、会话技术[cookie、session]、Filter、Listener)

Cookie 的生命周期、有效路径

Cookie 的生命周期

Cookie 的有效路径

// 设置cookie的有效路径。浏览器根据这个路径判断在访问哪些资源时携带该cookie给服务器
void setPath(String uri) 

session:服务器端的会话技术

概述

session 是保存在服务器端的会话技术,当通常情况下,Session 是借助 Cookie 技术来传递 ID 属性的。

session 的作用:为了保存会话中产生的数据

特点:

作用范围:

生命周期:

session 的与 cookie 的区别

cookie session
会话数据保存的位置 浏览器 服务器
数据的安全性 不安全 安全
存储数据是否有限制 有。4kb,且只能字符串

存储数据与获取数据 API

session 的剖析

在一次会话中,使用的都是同一个 session 对象剖析:

Filter:过滤器

概述

过滤器的使用场景:

Filter:是 Java 中预先定义好了的接口,可以过滤不同的内容,具体怎么过滤,需要使用者定义一个实现类,然后实现接口中的过滤方法,在方法中书写过滤的条件。filter 是对客户端访问资源的过滤,符合条件放行,不符合条件不放行

主要作用:对浏览器的请求进行拦截过滤的

filter 的使用

Filter 接口 API

// 过滤器的初始化方法
void init(FilterConfig filterConfig)
// 过滤器的核心过滤方法。写具体的过滤逻辑
void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
// 过滤器的销毁方法
void destroy()

使用步骤

  1. 创建一个 java 类,实现 filter 的接口,并实现方法 doFilter()

    //@WebFilter(filterName = "MyFilter1",urlPatterns = "/sd1")
    public class MyFilter implements Filter{
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {}
        //核心过滤方法
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("MyFilter进行服务器资源的过滤了...");
            //默认是拦截不放行的   手动放行(固定代码)
            filterChain.doFilter(servletRequest,servletResponse);
        }
        @Override
        public void destroy() {}
    }
    
  2. 注册 filter

    方式1:在自定义的 filter 类上添加 @WebFilter 注解:

    @WebFilter(filterName = "MyFilter1", urlPatterns = "/sd1")
    
    • filterName 属性:过滤器名称

    • urlPatterns 属性:过滤器生效的接口路径

      路径配置规则与 servlet 相同(完全匹配、目录匹配、拓展名匹配)

    方式2:在 web.xml 中配置 filter 要拦截的资源

    	<!--配置filter要拦截的服务器资源-->
        <filter>
            <!--filter的名称-->
            <filter-name>MyFilter</filter-name>
            <!--全限定名  包名+类名-->
            <filter-class>cn.itcast.filter.MyFilter</filter-class>
        </filter>
        <filter-mapping>
            <!--filter的名称-->
            <filter-name>MyFilter</filter-name>
            <!--要拦截的服务器资源路径-->
            <url-pattern>/sd1</url-pattern>
        </filter-mapping>
    

filter 的执行顺序、执行流程、生命周期

过滤器链:需要对同一个请求,进行多次不同业务的过滤时,可以配置多个过滤器,只有所有的过滤器都对请求进行了放行,请求才能访问到目标资源,只要多个过滤器中只有一个过滤器不放行请求,那么这个请求都不能够访问到目标资源。多个过滤器组成的一个整体称为过滤器链。而且,过滤器链中的过滤器是一个一个的执行的,一个过滤器执行完毕之后,会执行下一个过滤器,后面没有过滤器了,才会访问到目标资源。只要其中一个过滤器没有放行,那么这个过滤器后面的过滤器也都不会执行了。

过滤器链中多个过滤器的执行顺序:

filter 的执行流程

Java Web 项目入门指南(http、Servlet、Request、Response、ServletContext、会话技术[cookie、session]、Filter、Listener)

filter 的生命周期

从 filter 的出生到 filter 的死亡,有3个方法:

filter 的拦截方式

filter 默认只拦截 Request(浏览器过来的请求,包括重定向),不拦截 Forward(服务器内部的请求,即请求转发)

如果想让filter拦截服务器内部的请求:

使用案例

解决全站乱码

浏览器发出的任何请求,通过过滤器统一处理中文乱码。

@WebFilter(filterName = "EnCodingFilter",urlPatterns = "/*")
public class EnCodingFilter implements Filter {
     @Override
    public void init(FilterConfig filterConfig) throws ServletException {}
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        // 在执行servlet获取数据和响应数据之前执行该代码
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        // 放行之前 处理中文乱码
        chain.doFilter(req, resp);
    }
    @Override
    public void destroy() {}

非法字符的拦截

@WebFilter(filterName = "FeifaFilter",urlPatterns = "/sd3")
public class FeifaFilter implements Filter {
    private List<String> list;
    //服务器启动就执行 且只执行一次
    @Override
    public void init(FilterConfig config) throws ServletException {
        // 加载一个非法字符的文档(properties)
        	//底层:会自动去src下加载后缀名为properties的文件
        ResourceBundle bundle = ResourceBundle.getBundle("feifa");
        String value = bundle.getString("feifa"); 
        // 读取文档中的数据,放入到集合中
        String[] arr = value.split(",");
        list = Arrays.asList(arr);
    }
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
       // 获取用户发表的言论
        HttpServletRequest request=(HttpServletRequest)req;
        HttpServletResponse response=(HttpServletResponse)resp;
        String info = request.getParameter("info");
        // 判断言论是否合法
        	// 遍历循环集合,将集合的非法字符和接受到的数据做包含
			// 包含上:就是非法  没包含上:就是合法
        for(String value:list){
             if(info.contains(value)){
                 // 不合法--不放行 直接给浏览器响应信息
                 // 包含上:就是非法
                 response.getWriter().print("你发表的言论有非法行为,请思考后再发表...");
                 return;
             }
        }
        //合法--直接放行
        chain.doFilter(request, resp);
    }
    @Override
    public void destroy() {}

Listener:监听器

概述

web 监听器是一种 Servlet 中的特殊的类,可以帮助开发者监听web中的特定事件,比如 ServletContext, HttpSession, ServletRequest 的创建和销毁等。可以在某些动作前后增加处理,实现监控。

Listener 的作用:监听 ServletContext, HttpSession, ServletRequest 三大域对象的状态变化(三个域对象的创建和销毁)

使用场景:

java 提供了监听器规范,不同的监听器规范要监听的内容不一样

常见监听器:

listener 的使用

API

使用步骤(以 ServletContextListenner 监听器为例)

  1. 创建一个类实现 ServletContextListenner 接口,并实现方法 contextInitialized() 和contextDestroyed()

    // 监听servletContext对象的创建和销毁。需实现java提供的监听器规范(ServletContextListener)
    //@WebListener
    public class ServletContextLoaderListener implements ServletContextListener {
        // 当servletContext对象被创建了,监听器触发,该方法执行
        @Override
        public void contextInitialized(ServletContextEvent servletContextEvent) {
            System.out.println("servletContext对象被创建了...");
            // 让服务器一加载,就读取框架的配置信息,进行加载
            ServletContext servletContext = servletContextEvent.getServletContext();
            String value = servletContext.getInitParameter("spring");
            System.out.println("就可以正式根据获取到的配置文件名,对该文件的内容进行加载了:"+value);
            System.out.println("正在加载该配置文件中....");
        }
        @Override //当servletContext对象被销毁了 监听器触发 该方法执行
        public void contextDestroyed(ServletContextEvent servletContextEvent) {
            System.out.println("servletContext对象被销毁了...");
        }
    }
    
  2. 注册监听器

    • 方式1:在实现类上添加注解 @WebListene

    • 方式2:在 xml 中配置

      <listener>
          <listener‐class>com.itheima.listenner.MyServletContextListenner1</listener‐class> </listener>
      

案例

统计网站当前在线人数 HttpSessionListener

session 监听器,统计 session 个数

import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener()
public class MyHttpSession implements HttpSessionListener { 
    //当前在线人数的属性名称 
    private static final String NUMBER = "NUMBER";
    /* 
     * session 创建时触发 
     */ 
    @Override 
    public void sessionCreated(HttpSessionEvent event) { 
        //会话创建了,有新用户访问网站
        HttpSession session = event.getSession();
        //新创建的会话对象 
        ServletContext servletContext = session.getServletContext();
        //获取当前项目环境对象 
        System.out.println("session创建了" + session.getId()); 
        Integer n = (Integer) servletContext.getAttribute(NUMBER);
        //当前在线人数 
        if( n== null){
            //如果 n==null 说明是第一个用户 ,直接设置n=1 
            servletContext.setAttribute(NUMBER, 1); 
        }else{
            //如果n != null 直接累加 
            servletContext.setAttribute(NUMBER, ++n); 
        }
        //如果 n==null 说明是第一个用户 ,直接设置n=1 
        //如果 n != null 直接累加 
    }
    /* 
    * session销毁时触发 
    */ 
    @Override 
    public void sessionDestroyed(HttpSessionEvent event) { 
        //会话销毁了,有用户的会话对象销毁了 
        HttpSession session = event.getSession();
        //新创建的会话对象 
        ServletContext servletContext = session.getServletContext();
        //获取当前项目环境对象 
        System.out.println("session销毁了" + session.getId()); 
        Integer n = (Integer) servletContext.getAttribute(NUMBER);
        //当前在线人数 //直接减1 
        servletContext.setAttribute(NUMBER, ‐‐n);
    }
}

拓展

浏览器和服务器交互中文乱码处理

请求转发和重定向的区别

域对象的总结

域对象可以在多个 servlet/jsp 之间进行数据传递

java 后端的域对象有 3 个:

域对象操作的 API

// 存放数据
void setAttribute(String name, Object value)
// 获得数据
Object getAttribute(String name)
// 删除数据
void removeAttribute(String name)