JavaWeb学习笔记

web的基本概念

相对于htmlcss,javaweb具有动态能力

相较于静态页面,动态页面有以下优点:

1、可以动态更新页面,所有用户所看到的都不是同一个页面

2、可以连接数据库,对数据库进行操作


Tomcat的详解

tmocat的启动与关闭

在tomcat的bin文件目录下

服务器核心配置文件server.xml

tmocat服务器访问网站

将写好的网站放入webapps中的ROOT文件夹下

输入网址 http://localhost:8080/文件名 即可访问


Http

请求行

请求方式:GET,post......

-- get:请求能够携带少量参数,且大小有限制,会在浏览器的URL地址栏显示数据内容,步安全,但是高效

-- post:请求能够携带的参数,大小没有限制,不会在浏览器的URL地址栏显示数据内容,步安全,但不高效

消息头

响应体

响应状态码


IDEA中的Maven操作

在idea中创建maven

等待导入结束后能够看到以下文件


HelloServlet

servlet简介:

1、Servlet是sun公司开发动态web的一门技术

2、sun在这些API中提供一个接口叫做:Servlet,如果想要开发一个Serlvet程序,需要完成以下步骤

-- 编写一个类实现Servlet接口

-- 把开发好的Java类部署到web服务器中

实现了Servlet接口的Java程序叫做,Servlet

父子工程

如继承一样,子项目可以直接使用父项目中的java包

在父项目的pom文件中会出现modules展示子项目

子项目的pom文件中会出现parent展示父项目

servlet依赖项的导入

首先需要确定自己的maven本地库中有依赖项

然后在pom.xml文件中导入依赖项

复制代码
<dependencies>
    <!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2</version>
        <scope>provided</scope>
    </dependency>

</dependencies>

由<dependencies></dependencies>包裹依赖项<dependency></dependency>

依赖项有三项需要填写:

1、groupId

2、artifactId

3、version

以便于找到库中的依赖项并导入

配置tomcat

在编辑配置中找到tomcat本地,并部署工件,再启动即可搭建tomcat服务器

编写servlet映射

找到子项目中的web.xml,并打开在<web-app></web-app>中注册servlet,并写出servlet的请求路径

java 复制代码
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<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"
>
  <display-name>Archetype Created Web Application</display-name>
<!--  注册servlet-->
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>lesson.HelloServlet</servlet-class>
  </servlet>
<!--  Servlet的请求路径-->
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>

</web-app>

servlet-class 指定注册类

servlet-name 注册servlet的名字

url-pattern 访问的路径


Servlet原理

流程图

Mapping问题

url-pattern

1、一个Servlet可以指定一个映射路径

复制代码
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello</url-pattern>
</servlet-mapping>

2、一个Servlet可以指定多个映射路径

复制代码
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello2</url-pattern>
</servlet-mapping>
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello3</url-pattern>
</servlet-mapping>

3、一个Servlet可以指定通用映射路径

复制代码
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>

4、指定一些后缀或者前缀等等....

后缀形式:.+内容

在通配符*前方不能加任何项目映射路径

自写一个404页面

1、编写Servlet映射

复制代码
<!--  注册servlet-->
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>lesson.HelloServlet</servlet-class>
  </servlet>
<!--  Servlet的请求路径-->
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>error404</servlet-name>
    <servlet-class>lesson.error404</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>error404</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

2、写出类处理请求与响应

java 复制代码
package lesson;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class error404 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");

        PrintWriter writer = resp.getWriter();
        writer.print("<h1 style='color:red'>404</h1>");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

优先级问题

由上方的自制404页面引出一个问题:为什么/hello不会是404页面?

指定了固定的映射路径优先级高于未指定的(精确大于模糊)


ServletContext对象

ServletContext简介

web容器启动的时候会为每一个web程序创建一个对应的ServletContext对象,它代表了当前的Web应用;它有以下作用

共享数据

-- 在一个Servlet中保存的数据,可以被另外一个Servlet拿到

通过创建ServletContext对象,然后使用它的setAttribute方法将数据保存在ServletContext中

语法:ServletContext context = this.getServletContext();

为什么是this? 因为每一个web程序都会有一个ServletContext对象,我们保存到该对象中相当于保存到所有ServlerContext对象中

例子

1、设置数据

java 复制代码
package lesson;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class lesson extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //this.getInitParameter()   初始化参数
        //this.getServletConfig()   Servlet配置
        //this.getServletContext()  Servlet上下文
        ServletContext context = this.getServletContext();

        String username = "彭于晏";
        context.setAttribute("username",username); //将一个数据保存在ServletContext中,名字为:"username",值为 username
    }
}

2、获取数据

java 复制代码
package lesson;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();

        String username =(String)context.getAttribute("username");

        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("名字:"+username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

3、web.xml配置

java 复制代码
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<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">
         <display-name>Archetype Created Web Application</display-name>

        <servlet>
            <servlet-name>hello</servlet-name>
            <servlet-class>lesson.lesson</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello</url-pattern>
        </servlet-mapping>

        <servlet>
            <servlet-name>gec</servlet-name>
            <servlet-class>lesson.GetServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>gec</servlet-name>
            <url-pattern>/gec</url-pattern>
        </servlet-mapping>
</web-app>

我们想要在gec中得到"彭于晏",需要先访问hello来设置数据


ServletContext应用

转发

语法

java 复制代码
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); //请求转发的路径
requestDispatcher.forward(req,resp); //调用forward实现请求转发

一般简写成

java 复制代码
context.getRequestDispatcher("/gp").forward(req,resp)

properties应用

复制代码
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/lesson/db.properties");
Properties prop = new Properties();
prop.load(is);
String username = prop.getProperty("username");
String password = prop.getProperty("password");

首先要获取db.properties的数据流,找到文件的地址并使用getResourceAsStream找到

随后创建一个Properties对象接收properties数据

最后使用方法getProperty获得数据中指定内容


Response下载文件

java目录文件

java 复制代码
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取要下载文件的路径
        String realpath = "D:\\IDER\\javaweb\\Response\\target\\classes\\1.png";
        System.out.println("download path:"+realpath);
        //2.下载的文件名是什么
        String fileName = realpath.substring(realpath.lastIndexOf("\\")+1);
        //3.设置让浏览器能够支持(Context-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则可能乱码
        resp.setHeader("Context-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
        //4.获取下载文件的输入流
        FileInputStream in = new FileInputStream(realpath);
        //5.创建缓冲区
        int len = 0;
        byte[] buffer = new byte[1024];
        //6.获取OutputStream对象
        ServletOutputStream out = resp.getOutputStream();
        //7.将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输入到客户端
        while ((len=in.read(buffer))>0){
            out.write(buffer,0,len);
        }
        in.close();
        out.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

配置相关问题

创建新模块以后里面并没有web与facet需要我们主动配置

地址也需要更改,更改到src目录下的webapps中


Response验证码实现

java 复制代码
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

public class imageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // refresh 浏览器刷新    value值为时间间隔
        resp.setHeader("refresh","3");
        //在内存中创造一个图片
        BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
        //得到图片
        Graphics2D g = (Graphics2D) image.getGraphics();
        //设置背景颜色
        g.setColor(Color.white);
        g.fillRect(0,0,80,20);
        //给图片写数据
        g.setColor(Color.blue);
        g.setFont(new Font(null,Font.BOLD,20));
        g.drawString(makerandom(),0,20);
        //告诉浏览器,这个请求用浏览器打开
        resp.setContentType("image/png");
        //浏览器存在缓存控制,我们让浏览器不保存
        resp.setDateHeader("expires",-1);
        resp.setHeader("Cache-Control","no-cache");
        resp.setHeader("pragma","no-cache");
        //把图片写给浏览器
        imageIO.write(image,"jpg",resp.getOutputStream());


    }

    public String makerandom(){
        Random random = new Random();
        String num;
        num = random.toString();
        return num;
    }


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

Response重定向

重定向的定义:

重定向的状态码:302

重定向和转发的区别

相同点:

页面都会实现跳转

不同点

1、请求转发的时候,url不会发生变化

2、请求重定向时,url会发生变化

例:

复制代码
pageContext.request.contextPath

代表当前项目

getparameter("参数名")可以获取前端传来的参数

java 复制代码
package lesson;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class RequestTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理请求
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        System.out.println(username+" : "+password);

        resp.sendRedirect("success.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

index.jsp

java 复制代码
<html>
<body>
<h2>Hello World!</h2>
<form action="${pageContext.request.contextPath}/login" method="get">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit">

</form>
</body>
</html>

success.jsp

java 复制代码
<%--
  Created by IntelliJ IDEA.
  User: hp
  Date: 2024/3/18
  Time: 20:25
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>what can i say</h1>
</body>
</html>

Request应用

实现登录并收集信息:

java代码:

java 复制代码
package lesson;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("utf-8");
        req.setCharacterEncoding("utf-8");

        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbies = req.getParameterValues("hobbies");
        //后台接收中文乱码问题
        System.out.println("==============");
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbies));
        System.out.println("==============");

        req.getRequestDispatcher("/success.jsp").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

web.xml

java 复制代码
<?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">

<servlet>
  <servlet-name>login</servlet-name>
  <servlet-class>lesson.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>login</servlet-name>
  <url-pattern>/login</url-pattern>
</servlet-mapping>

</web-app>

index.jsp

html 复制代码
<%--
  Created by IntelliJ IDEA.
  User: hp
  Date: 2024/3/19
  Time: 12:12
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h1>登录</h1>

<div style="text-align: center">
<%--    以post的方式提交表单到login请求--%>
    <form action="${pageContext.request.contextPath}/login" method="post">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        爱好:
        <input type="checkbox" name="hobbies" value="女孩">女孩
        <input type="checkbox" name="hobbies" value="代码">代码
        <input type="checkbox" name="hobbies" value="唱歌">唱歌
        <input type="checkbox" name="hobbies" value="电影">电影
        <br>
        <input type="submit" value="提交">
    </form>
</div>

</body>
</html>

success.jsp

html 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1 style="color: dodgerblue;text-align: center" >登录成功</h1>
</body>
</html>

Cookie讲解

会话

定义:用户打开了一个浏览器,在其中点开了很多超连接访问了很多web资源,然后离开浏览器,这个过程称之为会话

Cookie与session,保存会话的两种技术

1、服务端给客户一个"信件",客户端下次访问时带上"信件"就可以直接访问;cookie

2、服务端登记我曾经来过,下次在登录表上匹配是否来过;sessoin

cookie

-- 客户端技术 (响应,请求)

session

-- 服务器技术,利用这个技术,可以保存用户的会话信息,我们可以把信息或者数据放在session中

Cookie[] cookies = req.getCookies() //获得cookie

cookie.getName(); //获得cookie的key

cookie.getValue(); //获得cookie的key的value

new cookie("key","value"); //创建一个新的cookie

cookie.setMaxAge(秒) //设置cookie的有效期

resp.addCookie(cookie) //响应给客户端一个cookie

细节问题

1、一个Cookie只能保存一个信息

2、一个Web站点可以给浏览器发送多个cookie,最多存放20个cookie

3、Cookie大小有限制

4、300个cookie为浏览器上限

删除cookie

1、不设置有效期,关闭浏览器,自动失效

2、设置有效时间为0

java

java 复制代码
package lesson;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

public class CookieDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决中文乱码
        //resp.setContentType("text/html;charset=utf-8");
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("utf-16");

        PrintWriter out = resp.getWriter();

        //Cookie,由服务端到客户端中获取
        Cookie[] cookies = req.getCookies();  //这里返回数组,说明cookie可能存在多个

        //判断cookie是否存在
        if (cookies!=null){
            //如果存在
            out.write("你上一次访问的时间是");

            for (int i=0;i < cookies.length;i++){
                Cookie cookie = cookies[i];
                //获取cookie名字
                if (cookie.getName().equals("lastLoginTime")){
                    //获取cookie中的值
                    long lastLoginTime = Long.parseLong(cookie.getValue());
                    Date date = new Date(lastLoginTime);
                    out.write(date.toLocaleString());
                }
            }

        }else {
            out.write("这是您第一次访问本站");
        }

        //服务端给客户端响应一个cookie
        Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");

        //给cookie设置有效期  单位秒  浏览器关闭后依然存在,除非过了有效期
        cookie.setMaxAge(24*60*60);
        resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

Session(重点)

什么是Session:

-- 服务器会给每一个用户(浏览器)创建一个Session对象

-- 一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在

-- 用户登录之后,整个网站它都可以访问 --> 保存了用户的信息

Session与Cookie的区别

-- Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)

-- Session是把用户的数据写到独占Session中,服务器保存(保存重要信息,减少服务器资源的浪费)

复制代码
//得到session
HttpSession session = req.getSession();
Person person = (Person) session.getAttribute("name");
复制代码
//手动注销session
session.invalidate();
复制代码
//得到session
HttpSession session = req.getSession();

//给session存东西
session.setAttribute("name",new Person("彭于晏",41));

//获得session的id
String sessionId = session.getId();

//判断session是不是新创建的
if(session.isNew()){
    resp.getWriter().write("session创建成功,ID:"+sessionId);
}else {
    resp.getWriter().write("session已经在服务器中存在了,ID:"+sessionId);
}
复制代码
   <session-config>
<!--        设置session自动失效,以分钟为单位-->
        <session-timeout>8</session-timeout>
    </session-config>   //在web.xml中设置

JSP原理剖析

什么是JSP

java Server Pages:java服务器端页面,也和Servlet一样,用于动态web技术

最大的特点:

1、写JSP就像再写HTML

区别:

1、HTML只给用户提供静态的数据

2、JSP页面中可以嵌入JAVA代码,为用户提供动态数据

JSP原理

浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet

jsp最终也会被转换成一个java类

JSP本质上就是一个Servlet(继承了servlet)

在JSP页面中只要是java语句就会原封不动的输出

如果是html语句就会转换为out.write("语句")形式输出


JSP

语法与指令

<%%> 表达式

<%=%> 表达式中嵌入值

<%!%> jsp声明

<%----%> 注释

el表达式:

${...} 中间可以插入变量等

<%@ include file="地址"%> 可以导入其他html文件

jsp的注释不会被客户端看到,HTML的注释能被客户端看到

<%@ page errorPage="发生错误后跳转的页面地址"%>

另外一种设计错误页面的方式:

在web.xml中配置

java 复制代码
    <error-page>
        <error-code>错误码</error-code>
        <location>发生后跳转的页面</location>
    </error-page>

jsp.include:

与<%@ include%>用法差不多

语法: <jsp.include page="地址">

差别:jsp.include是拼接页面,而<%@ include%>是将页面合成一个页面,在java文件中可以体现出来,合成的页面使用out.write()合成,拼接是导入了文件本质上还是多个


九大内置对象与作用域

复制代码
pageContext.setAttribute("name1","彭于晏01");  //保存的数据只在一个页面中生效
session.setAttribute("name2","彭于晏02");  //保存的数据只在一次会话中生效
request.setAttribute("name3","彭于晏03");  //保存的数据只在一次请求中生效,转发请求会携带这个数据
application.setAttribute("name4","彭于晏04");  //保存的数据只在服务器中生效,从打开服务器到关闭服务器

pageContext的转发:pageContext.forward("地址")


双亲委派机制

在使用一个类时,会先向上搜寻,直到根目录,如果没有才会使用自己定义的类


JSP、JSTL标签、EL表达式

EL表达式:
JSP标签:
JSTL标签:

JSTL标签是为了弥补HTML标签的不足

要先引入JSTL核心标签才能使用JSTL标签

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:if>

java 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
  <form action="coreif.jsp" method="get">
      <input type="text" name="username" value="${param.username}">
      <input type="submit" value="登录">
  </form>
<c:if test="${param.username=='admin'}" var="isAdmin">
    <c:out value="管理员欢迎您!"/>
</c:if>
<c:out value="${isAdmin}"/>
</body>
</html>

<c:when>

java 复制代码
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<c:set var="sorce" value="85"/>
<c:choose>
    <c:when test="${sorce>=90}">
        你的成绩为优秀
    </c:when>
    <c:when test="${sorce>=60 && sorce<90}">
        你的成绩为良好
    </c:when>
    <c:when test="${sorce<60}">
        你的成绩为不及格
    </c:when>
</c:choose>
</body>
</html>

<c:forEach>

java 复制代码
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
  ArrayList<String> people = new ArrayList<>();
  people.add(0,"天一");
  people.add(1,"小二");
  people.add(2,"老三");
  people.add(3,"李四");
  people.add(4,"王五");
  people.add(5,"吴六");
  request.setAttribute("list",people);
%>

<c:forEach var="people" items="${list}">
  <c:out value="${people}"/> <br>
</c:forEach>

<hr>

<c:forEach var="people" items="${list}" begin="1" end="5" step="2">
  <c:out value="${people}"/> <br>
</c:forEach>
</body>
</html>

JavaBean

|----|------|
| ID | Name |
| 1 | 彭于晏 |
| 2 | 吴彦祖 |

在javaBean中即类中有id与name两个私有属性,彭于晏和吴彦祖两个行记录就是java中的两个对象


过滤器Filter

即对数据进行处理的操作

在web.xml中配置filter

java 复制代码
<filter>
        <filter-name>filter</filter-name>
        <filter-class>filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filter</filter-name>
        <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>

监听器

java 复制代码
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class TestPanel {
    public static void main(String[] args) {
        Frame frame = new Frame("simple");  //新建一个窗体
        Panel panel = new Panel(null);  //面板
        frame.setLayout(null);  //设置窗体布局

        frame.setBounds(300,300,500,500);
        frame.setBackground(new Color(10,100,150));  //设置背景颜色

        panel.setBounds(50,50,300,300);
        panel.setBackground(new Color(30,100,30));  //设置背景颜色

        frame.add(panel);

        frame.setVisible(true);

        //监听事件,关闭事件
        frame.addWindowListener(new WindowListener() {
            public void windowOpened(WindowEvent e) {
                System.out.println("打开");
            }

            public void windowClosing(WindowEvent e) {
                System.out.println("关闭ing");
                System.exit(0);
            }

            public void windowClosed(WindowEvent e) {
                System.out.println("关闭ed");
            }

            public void windowIconified(WindowEvent e) {

            }

            public void windowDeiconified(WindowEvent e) {

            }

            public void windowActivated(WindowEvent e) {
                System.out.println("激活");
            }

            public void windowDeactivated(WindowEvent e) {
                System.out.println("未激活");
            }
        });
    }
}

Filter实现权限拦截

总体思路:利用session设置atrribute来验证访问者否有权限,没有属性直接访问时利用过滤器直接让其回到登录页面

过滤器:

java 复制代码
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class sysFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request1 = (HttpServletRequest) request;
        HttpServletResponse response1 = (HttpServletResponse) response;

        if (request1.getSession().getAttribute("USER_SESSION")==null){
            response1.sendRedirect("/error.jsp");
        }

        chain.doFilter(request,response);
    }

    public void destroy() {
    }
}

java代码获取登录权限

java 复制代码
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取前端请求的数据
        String username = req.getParameter("username");

        if(username.equals("admin")){
            req.getSession().setAttribute("USER_SESSION",req.getSession().getId());
            resp.sendRedirect( "/success.jsp");
        }else {
            resp.sendRedirect("/error.jsp");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

web.xml配置过滤器

java 复制代码
<filter>
        <filter-name>sysfilter</filter-name>
        <filter-class>Servlet.sysFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>sysfilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

smbms项目

项目搭建的思路

smbms项目搭建

1、搭建一个maven web项目

2、配置tomcat

3、测试项目是否能够跑动

4、导入项目中需要的Jar包

5、创建项目包结构

6、编写实体类

ORM映射,表-类映射(表的字段、类的成员变量)

7、编写基础公共类

一、数据库配置文件

java 复制代码
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306?useUnicode=true&characterEncoding=utf-8
username=root
password=????

二、编写数据库的公共类

java 复制代码
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

//操作数据库的公共类
public class BaseDao {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;

    //静态代码块,类加载的时候就初始化了
    static {
        Properties properties = new Properties();
        //通过类加载器读取对应的资源
        InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");

        try {
            properties.load(is);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        driver = properties.getProperty("diver");
        url = properties.getProperty("url");
        username = properties.getProperty("username");
        password = properties.getProperty("password");
    }

    //获取数据库的连接
    public static Connection getConnection(){
        Connection connection = null;
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }

    //编写查询类
    public static ResultSet executeQuery(Connection connection,String sql,Object[] param,ResultSet resultSet,PreparedStatement preparedStatement) throws Exception{
        preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < param.length; i++) {
            preparedStatement.setObject(i+1,param[i]);
        }
        resultSet = preparedStatement.executeQuery();
        return resultSet;
    }

    //编写增删改公共方法
    public static int execute(Connection connection,String sql,Object[] param,PreparedStatement preparedStatement) throws Exception{
        preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < param.length; i++) {
            preparedStatement.setObject(i+1,param[i]);
        }
        int updateRows= preparedStatement.executeUpdate();
        return updateRows;
    }

    //释放资源
    public static Boolean x(Connection connection,PreparedStatement preparedStatement,ResultSet resultSet){
        Boolean flag = true;

        try {
            resultSet.close();
            //回收
            resultSet = null;
        } catch (SQLException e) {
            e.printStackTrace();
            flag = false;
        }

        try {
            preparedStatement.close();
            //回收
            preparedStatement = null;
        } catch (SQLException e) {
            e.printStackTrace();
            flag = false;
        }
        try {
            connection.close();
            //回收
            connection = null;
        } catch (SQLException e) {
            e.printStackTrace();
            flag = false;
        }
        return flag;
    }


}

三、编写字符编码过滤器

java 复制代码
import javax.servlet.*;
import java.io.IOException;

public class characterEncodingFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");

        chain.doFilter(request,response);
    }

    public void destroy() {
    }
}

8、导入静态资源


smbms登录流程的实现

1、编写前端页面

2、设置欢迎页面

java 复制代码
<!--  设置欢迎页面   -->
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>

3、编写dao层用户登录接口

java 复制代码
public interface UserDao{
    public User getLoginUser(Connection connection,String userCode);
}

4、编写dao层用户登录接口实现类

java 复制代码
import com.wu.dao.BaseDao;
import com.wu.pojo.User;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class UserDaoImpl implements UserDao{
    public User getLoginUser(Connection connection, String userCode) {
        PreparedStatement prpm = null;
        ResultSet rs = null;
        User user = null;

        if(connection!=null){
            try {
                Object[] param = null;
                String sql = "select * from smbms_user where userCode=?";

                rs = BaseDao.executeQuery(connection, prpm, rs, sql, param);
                if(rs.next()){
                    user = new User();
                    user.setId(rs.getInt("id"));
                    user.setUserCode(rs.getString("userCode"));
                    user.setUserName(rs.getString("userName"));
                    user.setUserPassword(rs.getString("password"));
                    user.setGender(rs.getInt("gender"));
                    user.setBirthday(rs.getDate("birthday"));
                    user.setPhone(rs.getString("phone"));
                    user.setAddress(rs.getString("address"));
                    user.setUserRole(rs.getInt("userRole"));
                    user.setCreatedBy(rs.getInt("createBy"));
                    user.setCreationDate(rs.getDate("creationDate"));
                    user.setModifyBy(rs.getInt("modifyBy"));
                    user.setModifyDate(rs.getDate("modifydate"));
                }
                BaseDao.closeResource(null,prpm,rs);
            } catch (Exception e) {
                e.printStackTrace();
            }

        return user;
    }
}

5、业务层接口

java 复制代码
public interface UserService {
    //用户登录
    public User Login(String UserCode,String password);
}

6、业务层接口实现

java 复制代码
import com.wu.dao.BaseDao;
import com.wu.dao.user.UserDao;
import com.wu.dao.user.UserDaoImpl;
import com.wu.pojo.User;

import java.sql.Connection;
import java.sql.SQLException;

public class UserServiceIpml implements UserService{

    //业务层都要用到dao层,所以我们需要引入dao层
    private UserDao userDao;

    public UserServiceIpml(){
        userDao = new UserDaoImpl();
    }

    public User Login(String userCode, String password){
        Connection connection = null;
        User user = null;

        try {
            connection = BaseDao.getConnection();
            //通过业务层调用数据库相应操作
            user = userDao.getLoginUser(connection, userCode);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            BaseDao.closeResource(connection,null,null);
        }
        return user;
    }

}

7、编写servlet

java 复制代码
package com.wu.servlet.user;

import com.wu.pojo.User;
import com.wu.service.user.UserServiceIpml;
import com.wu.util.Constants;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LoginServlet extends HttpServlet {

    //Servlet:控制层调用业务层代码
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("LoginServlet is starting ....");

        String userCode = req.getParameter("userCode");
        String userPassword = req.getParameter("userPassword");

        //和数据库中的密码进行对比
        UserServiceIpml userService = new UserServiceIpml();
        User user = userService.Login(userCode,userPassword);

        if (user!=null){
            //将用户信息存储到session中
            req.getSession().setAttribute(Constants.USER_SESSION,user);
            resp.sendRedirect("jsp/frame.jsp");
        }else {
            req.setAttribute("error","密码输入错误或用户名错误");
            req.getRequestDispatcher("login.jsp").forward(req,resp);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

8、注册Servlet

java 复制代码
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.wu.servlet.user.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/login.do</url-pattern>
    </servlet-mapping>

9、测试访问,确保成功


smbms注销及权限过滤

注销功能

移除session

java 复制代码
package com.wu.servlet.user;

import com.wu.util.Constants;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //移除用户
        req.getSession().removeAttribute(Constants.USER_SESSION);
        resp.sendRedirect("/login.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

注册xml

java 复制代码
<servlet>
        <servlet-name>LogoutServlet</servlet-name>
        <servlet-class>com.wu.servlet.user.LogoutServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LogoutServlet</servlet-name>
        <url-pattern>/jsp/logout.do</url-pattern>
    </servlet-mapping>
登录拦截优化

编写一个过滤器并注册

java 复制代码
import com.wu.pojo.User;
import com.wu.util.Constants;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class SysFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        User user =(User) ((HttpServletRequest) req).getSession().getAttribute(Constants.USER_SESSION);
        if (user==null){  //已注销或未登录
            ((HttpServletResponse) resp).sendRedirect("/smbms/error.jsp");
        }else {
            chain.doFilter(req,resp);
        }
    }

    public void destroy() {

    }
}

注册

java 复制代码
    <filter>
        <filter-name>SysFilter</filter-name>
        <filter-class>com.wu.filter.SysFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SysFilter</filter-name>
        <url-pattern>/jsp/*</url-pattern>
    </filter-mapping>

smbms密码修改实现

密码修改

UserDao接口

java 复制代码
int updatePwd(Connection connection,int id,int password) throws SQLException;

UserDao接口实现类

java 复制代码
public int updatePwd(Connection connection, int id, int password) throws SQLException {
        PreparedStatement pstm = null;
        int execute = 0;
        if(connection!=null){
            String sql = "update smbms_user set userPassword = ? where id = ?";
            Object params[] = {password,id};
            execute = BaseDao.execute(connection,pstm,sql,params);
            BaseDao.closeResource(connection,pstm,null);
        }
        return execute;
    }

UserService接口

java 复制代码
    boolean updatePwd(Connection connection, int id, int password);

UserService实现类

java 复制代码
public boolean updatePwd(Connection connection, int id, int password){
        connection = null;
        boolean flag = false;
        //修改密码
        try {
            connection = BaseDao.getConnection();
            if(userDao.updatePwd(connection,id,password)>0){
                flag = true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            BaseDao.closeResource(connection,null,null);
        }
        return flag;
    }

Servlet的复用(需要提取方法)

java 复制代码
//实现Servlet复用
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getParameter("method");
        if (method.equals("savepwd") && method!=null){
            this.updatePwd(req,resp);
        }
    }

验证旧密码

java 复制代码
//验证旧密码,session中有用户旧密码
    public void pwdModify(HttpServletRequest req, HttpServletResponse resp){
        //从session中拿id
        Object o = req.getSession().getAttribute(Constants.USER_SESSION);
        String oldpassword = req.getParameter("oldpassword");

        //万能Map,结果集
        Map<String,String> resultMap = new HashMap<String, String>();

        if(o==null){   //session失效了
            resultMap.put("result","sessionerror");
        }else if(StringUtils.isNullOrEmpty(oldpassword)){
            resultMap.put("result","true");
        }else {
            resultMap.put("result","false");
        }

        try {
            resp.setContentType("application/json");
            PrintWriter writer = resp.getWriter();
            writer.write(JSONArray.toJSONString(resultMap));
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
Map结果集
java 复制代码
 //万能Map,结果集
 Map<String,String> resultMap = new HashMap<String, String>();

可以将一对数据保留在map结果集之中,最终呈现形式为[String,String]与json类似

相关推荐
虾球xz1 小时前
游戏引擎学习第55天
学习·游戏引擎
oneouto1 小时前
selenium学习笔记(二)
笔记·学习·selenium
sealaugh321 小时前
aws(学习笔记第十九课) 使用ECS和Fargate进行容器开发
笔记·学习·aws
炭烤玛卡巴卡2 小时前
学习postman工具使用
学习·测试工具·postman
thesky1234562 小时前
活着就好20241224
学习·算法
蜗牛hb2 小时前
VMware Workstation虚拟机网络模式
开发语言·学习·php
汤姆和杰瑞在瑞士吃糯米粑粑3 小时前
【C++学习篇】AVL树
开发语言·c++·学习
虾球xz3 小时前
游戏引擎学习第58天
学习·游戏引擎
LuH11243 小时前
【论文阅读笔记】Scalable, Detailed and Mask-Free Universal Photometric Stereo
论文阅读·笔记
奶香臭豆腐4 小时前
C++ —— 模板类具体化
开发语言·c++·学习