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类似

相关推荐
①个程序员13 分钟前
thinkphp 学习记录
学习
alfiy1 小时前
Elasticsearch学习笔记(四) Elasticsearch集群安全配置一
笔记·学习·elasticsearch
向上的车轮1 小时前
Django学习笔记十一:部署程序
笔记·学习·django
不灭锦鲤2 小时前
ssrf学习(ctfhub靶场)
网络·学习·安全
alfiy2 小时前
Elasticsearch学习笔记(五)Elastic stack安全配置二
笔记·学习·elasticsearch
权^2 小时前
MySQL--聚合查询、联合查询、子查询、合并查询(上万字超详解!!!)
大数据·数据库·学习·mysql
pumpkin845142 小时前
CXO、CRO、CMO、CDMO相关概念
笔记
冷静 包容2 小时前
C语言学习之 没有重复项数字的全排列
c语言·开发语言·学习
K3njuan2 小时前
《数据结构》学习系列
学习
结衣结衣.2 小时前
C++ 类和对象的初步介绍
java·开发语言·数据结构·c++·笔记·学习·算法