JavaWeb

使用Java开发Web服务的技术,统称为JavaWeb。

B/S与C/S模式

  • B/S:Browser/Server 浏览器/服务器模式
  • 用户只需要一个浏览器即可访问服务器
  • C/S:Clint/Server 客户端/服务器模式

Maven

用于结构化管理jar文件的工具。

通过在Maven项目中加入某个jar文件的依赖,让其自动从Maven云仓库中下载对应的jar文件。

HTTP状态码

用特定数字表示状态。https://http.cat/

常见状态码

含义

200

成功

404

资源未找到

500

服务器内部错误

405

方法不允许

Servlet

Server+Applet 运行在服务器上的程序

三层架构

在软件开发中,并不是将所有功能都交给一个类去实现,而是要将其进行分层,从而达到"高内聚、低耦合"的目的。

低耦合是指降低各个模块之间的关联程度,这样便于开发和维护,每个模块各司其职。

高内聚是指每个模块内的功能不可再分。

比如要用积木拼出来一辆车,不要把所有积木放在一起拼,这样其中一部分出现问题,就会影响到其他地方。

最好的做法是先将车的各个组件拼接完成(解耦),每个组件都是完整的不可再分的整体(高内聚),最终再把各个组件拼接到一起。

这样便于发现问题解决问题,不影响其他模块。

通常所说的三层架构中的三层,是指“数据访问层、业务逻辑层和视图表现层

  • 数据访问层,用于连接数据库,对数据做增删改查的操作
  • 业务逻辑层,用于处理业务逻辑,在适当的情况下调用数据访问层中的方法
  • 视图表现层,用于展示数据和提供用户输入数据的渠道,在适当的情况下调用业务逻辑层中的方法

Servlet的生命周期

构造方法**–>init()–>service()/doGet()/doPost()–>**destory()

在访问某servlet时

1.执行构造方法一次

2.初始化一次,调用init()方法

3.调用service()方法,之后每次访问都会调用该方法。有该方法时,doGet和doPost失效。

如果没有该方法,会根据请求方式试图调用doGet或doPost,如果没有相应的方法,会出现405状态码,表示请求方式不允许

4.在当前servlet所在项目从tomcat中停止时,销毁一次,调用destory()方法

使用注解开发Servlet

/*
 * 使用注解开发Servlet
 * 注解:@特定单词  如@Override
 *
 * 定义且配置Servlet的注解:@WebServlet("/请求映射")
 * */
@WebServlet("/sysAdmin")
public class SysAdminServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)  {
        //访问该Servlet时要执行的内容
    }
}
//@WebServlet("/sysAdmin")相当于在web.xml中进行配置servlet映射

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">

    <!--设置项目启动的欢迎页-->
    <welcome-file-list>
        <welcome-file>login.html</welcome-file>
    </welcome-file-list>

    <!--设置错误页面-->
    <error-page>
        <!--错误码-->
        <error-code>404</error-code>
        <!--页面路径-->
        <location>/404.html</location>
    </error-page>
    <error-page>
        <!--异常类型-->
        <exception-type>java.lang.NullPointerException</exception-type>
        <location>/error.html</location>
    </error-page>

    <!--上下文参数-->
    <context-param>
        <!--参数名-->
        <param-name>contentParam</param-name>
        <!--参数值-->
        <param-value>全局参数</param-value>
    </context-param>

    <!--servlet标签-->
    <!--servlet-mapping标签-->


    <!--filter标签-->
    <!--filter-mapping标签-->

    <!--session-config标签-->

</web-app>

绝对路径

<a href="localhost:8080/system/pages/hello.html">跳转</a>

相对路径问题

  • /
    表示从根目录(域名+ip)出发
  • ./
    表示从当前位置出发
  • …/
    表示跳向上一层
如有index页面所在路径为
localhost:8080/system/pages/index.html

<a href="/hello.html">跳转</a>
这种方式,从根目录(localhost:8080)出发,会跳转到localhost:8080/hello.html

<a href="./hello.html">跳转</a>
这种方式,从当前位置(localhost:8080/system/pages)出发,会跳转到localhost:8080/system/pages/hello.html

<a href="../hello.html">跳转</a>
这种方式,从当前位置跳向上一层,会跳转到localhost:8080/system/hello.html
  • 在jsp页面中,可以使用**${pageContex.request.contextPath}**表示页面上下文路径。

如项目默认上下文访问路径为localhost:8080/system

<a href="${pageContex.request.contextPath}/pages/hello.html">跳转</a>

以上路径相当于/system/pages/hello.html,即从根目录出发localhost:8080/system/pages/hello.html

如果在jsp页面中无法识别${},在<%@ page%>中加入isELIgnored=“false”

<%@ page contentType="text/html;charset=UTF-8" language="java"  isELIgnored="false" %>

四大作用域对象

作用域:共享数据的区域

pageContext

当前页面对象。共享数据区域范围为当前页面。

如果不在同一个页面,数据无法读取。

request

请求对象。共享数据区域范围为一次请求。

如果跳转中途使用了重定向,数据无法读取。

session

会话对象。会话是用户访问服务器时的某个时间段。

共享数据区域范围在这个时间段内,默认30分钟。

如果在指定时间内没有操作或销毁会话时,数据无法读取。

application

项目对象。共享数据区域范围为整个项目。

作用域范围

application > session > request > pageContext

以上四个作用域对象,都有这几个方法

//将某个对象obj保存到作用域中,命名为str
作用域对象.setAttribute(String str,Object obj);
//从某个作用域中获取保存的某个对象
Object obj = 作用域对象.getAttribute(String str);
//从某个作用域中移除某个保存的对象
作用域对象.removeAttribute(String str);

作用域对象的使用

在JSP页面中

作用域对象也称为内置对象,直接通过对应的单词使用

p1.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    //在jsp中使用pageContext页面上下文对象,跳转到p2时不能使用
    pageContext.setAttribute("str","保存在pageContext作用域中的字符串");
    //在jsp中使用request请求对象,请求转发到p2时可以使用,重定向到p2时不能使用
    request.setAttribute("str","保存在request中的字符串");
    //在jsp中使用session会话对象,在默认的30分钟内,没有销毁,哪种跳转都能在p2中使用
    session.setAttribute("str","保存在session中的字符串");
    //在jsp中使用application应用程序对象,整个项目中任何页面都能使用
    application.setAttribute("str","保存在application中的字符串");
    //以上四个作用域对象,也是jsp中的内置对象,无需定义

    //销毁会话
    //session.invalidate();

    //使用请求转发跳转到p2.jsp
    //request.getRequestDispatcher("p2.jsp").forward(request,response);
    //使用重定向跳转到p2.jsp
    response.sendRedirect("p2.jsp");
%>
<h1><%=pageContext.getAttribute("str")%></h1>

</body>
</html>

p2.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <h3><%=pageContext.getAttribute("str")%></h3>
        <h3><%=request.getAttribute("str")%></h3>
        <h3><%=session.getAttribute("str")%></h3>
        <h3><%=application.getAttribute("str")%></h3>
    </body>
</html>

在servlet中使用

  • pageContext
    servlet本身就是一个java类,在类中定义成员变量,就能在当前类中使用。
    所以在servlet中不会使用pageContext对象
  • request
    使用doGet/doPost/service方法中的HttpServletRequest参数req
  • session
//在servlet中使用session,需要通过请求对象request调用getSession()方法
HttpSession session= req.getSession();
  • application
//通过getServletContext()方法获取的ServletContext类型对象,就是当前项目对象
ServletContext application = getServletContext();

总结

  • 在jsp页面中使用pageContext保存的数据,只能共享于当前页面
  • 通常在servlet中查询后的数据保存在request中,使用请求转发跳转到其他页面,在对应的页面中数据数据
  • 通常在登录后,将登录的用户保存在session中,无论用哪种方式跳转,都能从session中获取当时登录的用户。
  • 在application中保存一些共享于整个项目中的数据

servlet依赖

如果要使用servlet、filter、listener、request、response都需要该依赖

<!--servlet-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

web.xml中的相关配置

  • servlet
<!-- 声明servlet -->
<servlet>
    <servlet-name>自定义servlet名</servlet-name>
    <servlet-class>servlet全限定名</servlet-class>
    <!-- servlet初始化参数 -->
    <init-param>
        <param-name>参数名</param-name>
        <param-value>参数值</param-value>
    </init-param>
</servlet>

<!-- 配置servlet请求映射 -->
<servlet-mapping>
    <servlet-name>自定义servlet名</servlet-name>
    <url-patten>/映射名</url-patten>
</servlet-mapping>
  • filter
<!-- 声明filter -->
<filter>
    <filter-name>自定义filter名</filter-name>
    <filter-class>filter全限定名</filter-class>
</filter>
<!-- 配置filter请求映射 -->
<filter-mapping>
    <filter-name>自定义filter名</filter-name>
    <!--过滤器通常用于解决中文乱码,要过滤所有请求-->
    <url-patten>/*</url-patten>
</filter-mapping>
  • listener
<listener>
    <listener-class>监听器的全限定名</listener-class>
</listener>
  • session
<!--设置全局session配置-->
<session-config>
    <session-timeout>session有效时长,单位为分钟</session-timeout>
</session-config>
  • 全局参数
<!--设置全局参数-->
<context-param>
    <param-name>参数名</param-name>
    <param-value>参数值</param-value>
</context-param>

数据访问层(Dao)

现在使用JDBC实现查询,框架部分会使用MyBatis、MyBatisPlus或JPA,简化该层的写法。

跳转

请求转发forward

保存在request中的数据会一直存在

request.getRequestDispatcher("目的路径").forward(request,response);

重定向redirect

保存在request中的数据会丢失(不是同一个请求)

response.sendRedirect("目的路径");

JSP

由控制层保存数据到作用域中,跳转到Jsp中展示数据。

作用域对象

pageContext request session application

内置对象

request response page pageContext session application out config exception

EL

表达式语言。替换jsp中的输出<%=%>部分。

  • 从作用域中获取对象,通过.或[]获取属性,该属性必须存在且有get方法
    java 后台服务 学习路线 java后端服务_java 后台服务 学习路线{指定作用域.对象名[“属性名”]}
  • 从请求中获取参数,表单的name或?后的数据
    ${param.参数名}
  • 逻辑判断、计算
  • 非空判断 ${empty 对象}
  • 计算 ${xx + yy}
  • 获取当前项目上下文路径
${pageContext.request.contextPath}

JSTL

<!--jstl标签库-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

先导入依赖,在jsp页面中引入标签库

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  • 判断
<c:if test="条件">
    html内容
</c:if>
  • 遍历
<c:forEach items="要遍历的集合" var="遍历出的对象">
    html内容
</c:if>

Session

通常用session保存登录时的用户信息,实现在各个页面中共享信息或防止未登录的情况下访问。

使用session时,会创建一个JSESSIONID,保存在cookie中,在浏览器开启状态下,该JSESSIONID默认会有30分钟的有效期,

如果在30分钟内没有对session进行操作或关闭浏览器,该cookie就会销毁,对应的session就会失效。

Ajax

Asynchronous Javascript And XML

异步JavaScript和XML

一种数据交互方式,请求和响应是异步的。

使用ajax能实现在整个页面不重新加载的情况下,更新局部内容。

使用

浏览器都是支持异步提交,原生的JavaScript就能实现ajax,但使用极不方便,所以都是使用jquery封装后的**java 后台服务 学习路线 java后端服务_java_02.get() $.post()等函数。

1.在页面中导入jquery文件

<!--使用Ajax,需要导入jquery-->
<script src="jquery文件路径"></script>

2.在script标签中写ajax

<script>
    某个节点.事件(function(){
        //使用ajax异步提交数据
        $.ajax({
            //访问的URL地址
            url:"servlet映射或具体url",
            //提交的数据
            data:{
                //键:值
                "形参":值,
                "形参":值
            },
            //提交方式
            type:"get/post/put/delete",
            //成功访问URL后的回调函数
            success:function(res){//res表示访问URL后返回的数据

            },
            //访问URL失败时的回调函数
            error:function(){

            }
        });
    });
</script>

Session和Cookie

这两个都是用于保存数据的对象。

session是一个作用域对象,在servlet中通过request.getSession()获取,在JSP中直接使用内置对象session获取。

cookie是一个对象,也是一个文件,保存在本地。

Cookie

cookie通常用于更长时间地保存一些信息,即便关闭浏览器,也能保存。

cookie的创建

//创建cookie
Cookie cookie = new Cookie("username", "保存在cookie中的用户名");
//设置有效时长,单位为秒,这里表示7天有效
cookie.setMaxAge(60*60*24*7);
//通过响应对象response保存cookie对象到本地
response.addCookie(cookie);

cookie的获取

//读取cookie时是获取当前站点的所有cookie数组
Cookie[] cks = request.getCookies();
//遍历
for(Cookie ck :cks){
    System.out.println( ck.getName()+"--"+ck.getValue());
}

Session

session是一个作用域对象,在访问任意jsp页面时,默认就会创建一个session对象(可以通过设置取消自动创建)。

通常使用session保存一些信息,用于在同一站点的各个页面之间共享数据。

原理:

  • 1.当访问的jsp页面或servlet中使用了session,会创建一个JSESSIONID(session编号),这是一个字符串,保存在一个cookie中。
  • 默认访问某个jsp页面时,该页面中没有使用session,也会自动创建session,因为
<%--默认每个jsp页面都有这句话,表示访问该页面时,自动使用session--%>
<%@ page session="true"%>

如果将其设置为false,访问该jsp时则不会自动创建session。

  • 2.再次访问该页面时,会查询该JSESSIONID是否存在,如果存在,直接使用,如果不存在,创建新的JSESSIONID
  • 3.保存该JSESSIONID的cookie会随着浏览器的关闭自动销毁,所以关闭浏览器,session就会失效。

session对象的常用方法

常用方法

作用

session.setAttribute(String str,Object obj)

将obj对象保存在session中,命名为str

session.getAttribute(String str)

获取保存在session中的对象

session.removeAttribute(String str)

移除保存在session中的对象

session.invalidate()

销毁session

session.getCreationTime()

获取session创建时间对应的毫秒数

session.getId()

获取JSESSIONID

session.getMaxInactiveInterval()

获取session有效时长(默认1800秒)

session.setMaxInactiveInterval(int seconds)

设置session有效时长,参数为秒

ServletContext app = session.getServletContext();

获取当前application对象

监听器Listener

对于项目的某个操作进行监听,这个操作可以是创建或销毁application、session,发送请求、得到响应。

用于在执行某个操作时,通过监听器同时再执行其他操作,如记录日志、统计站点人数等。

常用的三个监听器接口

ServletContextListener        application监听器
HttpSessionListener            session监听器
ServletRequestListener        request监听器

实现一个监听器

1.创建一个类,实现某个监听器接口

2.重写某个监听器接口中方法

  • 初始化的方法
  • 销毁的方法

3.在web.xml中配置监听器或通过注解配置

  • 如果在web.xml中配置
<!--配置监听器-->
<listener>
    <!--设置监听器的全限定名-->
    <listener-class>com.hqyj.bookShop.listener.MyListener</listener-class>
</listener>
  • 如果通过注解配置,在自定义的监听器类上,加入@Web
package com.hqyj.bookShop.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/*
* 监听器
* 1.创建一个类,实现某个或多个监听器接口
* 2.重写方法
* 3.在该类上加入@WebListener注解或在web.xml中配置监听器
* */
@WebListener
public class MyListener implements ServletContextListener,HttpSessionListener, ServletRequestListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("监听到项目初始化");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("监听到项目销毁");
    }

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("监听到请求销毁");
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("监听到发送请求");
    }

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("监听到session创建");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("监听到session销毁");
    }
}

过滤器Filter

使用

1.创建一个类,继承HttpFilter

2.重写其中受保护的doFilter的方法

3.在web.xml中配置过滤器或使用注解配置

  • 在web.xml中配置的话
<!--声明过滤器-->
<filter>
    <filter-name>myFilter</filter-name>
    <filter-class>com.hqyj.filter.MyFilter</filter-class>
</filter>
<!--设置什么请求要经过该过滤器,通常过滤所有请求-->
<filter-mapping>
    <filter-name>myFilter</filter-name>
    <!--/*表示过滤所有请求-->
    <url-pattern>/*</url-pattern>
</filter-mapping>
  • 使用@WebFilter(“/*”)注解配置的话
package com.hqyj.filter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/*
 * 自定义一个过滤器
 * 1.继承HttpFilter
 * 2.重写受保护的doFilter方法
 * 3.web.xml中配置该过滤器
 * */
//@WebFilter("/*")
public class MyFilter extends HttpFilter {
    @Override
    protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
        //由于设置了过滤所有请求,所以在这里设置请求的编码格式
        req.setCharacterEncoding("utf-8");
        //获取请求的地址后,决定是否放行
        String uri = req.getRequestURI();
        System.out.println(uri+"试图访问");
        //判断地址中是否包含登录页或登录页相关的servlet映射或资源路径
        if (uri.contains("login")|| uri.contains("customer")||uri.contains("jquery")) {
            //允许放行
            chain.doFilter(req,res);
            return;
        }
        //如果登录成功,会在session中保存customer,所以在这里判断session中是否存在customer,如果存在,放行一切请求
        if(req.getSession().getAttribute("customer")==null){
            res.sendRedirect("http://localhost:8080/Web03/pages/login.html");
        }else{
            //允许放行
            chain.doFilter(req,res);
        }
    }
}