JavaWeb学习回顾

JavaWeb学习回顾

  • JavaWeb开发
    • 3、Tomcat
      • **3.1 安装**
      • 3.2 启动和安装
      • 3.3 核心配置
      • 3.4 发布一个网站
    • 4、http
      • 4.1 什么是HTTP?
      • 4.2 两个
      • 4.3 http请求
      • 4.4 HTTP响应
    • 5、Maven
      • 5.1、Maven 项目架构管理工具
      • 5.2、下载安装Maven
      • 5.3、配置环境变量
      • 5.4 阿里云镜像
      • 5.5、本地仓库
      • 5.6、在IDEA中使用Maven
      • 5.7、创建一个普通的Maven项目
      • 5.8、在IDEA中标记文件夹的功能
      • 5.9、在IDEA中配置Tomcat
      • 5.10、pom文件
      • 5.12 IDEA操作
      • 5.13、解决遇到的问题
    • 6、Servlet
      • 6.1、Servlet简介
      • 6.2、HelloServlet
      • 6.3、运行原理
      • 6.4、mapping问题
      • 6.5、ServletContext
        • 1、实现共享数据
          • 测试结果
        • 2、获取初始化参数
        • 3、请求重定向
        • 4、读取资源文件
      • 6.6、HttpServletResponse
        • 1、简单分类
        • 2、下载文件
        • 3、写验证码
        • 4、重定向
        • 5、jsp定位
    • 8、JSP
      • 8.1、什么是JSP
      • 8.2、JSP原理
      • 8.3、JSP基础语法
      • 8.4、JSP指令
      • 8.5、9大内置对象
      • 8.6、JSP标签、JSTL标签、EL表达式
    • 9、JavaBean
    • 10、MVC三层架构
      • 10.1、早些年
      • 10.2、MVC三层架构
    • 11、Filter(重要)
    • 12、监听器
    • 13、过滤器、监听器常见应用
    • 14、JDBC
  • SMBMS
    • 1、项目搭建准备工作
    • **2、登陆功能实现**
    • 3、登陆功能优化
    • 密码修改
    • 实现文件上传
    • 邮件发送

直接将自己观看视频学习做的笔记贴上去,以下所有笔记均来自下面的教学视频

【狂神说Java】JavaWeb入门到实战 https://www.bilibili.com/video/BV12J411M7Sj

JavaWeb开发

3、Tomcat

3.1 安装

JavaWeb学习回顾_第1张图片

3.2 启动和安装

JavaWeb学习回顾_第2张图片

3.3 核心配置

JavaWeb学习回顾_第3张图片

可以配置端口号

  • Tomcat默认端口为8080
  • mysql为3306
  • http 80
  • https 443
 <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

可以配置主机名称

  • 默认的主机名 localhost ->127.0.0.1
  • 默认的网站应用存放位置 webapps
  <Host name="www.syk.com"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

高难度面试题:

请你谈一谈网站是如何进行访问的?

JavaWeb学习回顾_第4张图片

3.4 发布一个网站

--webapps:Tomcat服务器的web目录
	-Root
		-WEB-INF 
			-classes:java文件
			-lib:web应用所依赖的jar包
			-web.xml:网站配置文件
		-index.jsp/index.html 默认访问的首页
		-statics
			-css
				-style.css
			-js
			-img
		-...
		

HTTP协议:面试

Maven:构建工具

  • Maven安装包

Servlet 入门

  • Hello world
  • Servlet配置
  • 原理

4、http

4.1 什么是HTTP?

4.2 两个

4.3 http请求

4.4 HTTP响应

常见面试题

当你的浏览器地址栏中输入地址并回车的一瞬间到页面能够展示回来,经历了什么?

5、Maven

5.1、Maven 项目架构管理工具

我们的目的就是用来方便导入jar包的

Maven的核心思想:约定大于配置

  • 有约束不要去违反

Maven会规定好你该如何去编写我们的java代码,必须按照这个规范来

5.2、下载安装Maven

https://maven.apache.org/download.cgi

JavaWeb学习回顾_第5张图片

5.3、配置环境变量

在我们的系统环境变量中

配置如下的配置:

  • M2_HOME maven目录下的bin目录
  • MAVEN_HOME maven的目录

JavaWeb学习回顾_第6张图片

  • 在系统的path中配置 %MAVEN_HOME%\bin
    使用cmd命令
mvn -version 

来检查环境是否正确
JavaWeb学习回顾_第7张图片

测试Maven是否安装成功,保证必须配置成功

5.4 阿里云镜像

  • 镜像:mirrors

    • 作用:加速我们的下载
  • 国内建议使用阿里云的镜像

    <mirror>
          <id>nexus-aliyunid>
          <name>nexus aliyunname>
          <url>http://maven.aliyun.com/nexus/content/groups/public/url>
          <mirrorOf>*,!jeecg,!jeecg-snapshotsmirrorOf>        
        mirror>
    

    注:直接按照狂神java中的配置手动敲写的

5.5、本地仓库

建立一个本地仓库,远程仓库;

建立一个本地仓库 localRepository

<localRepository>D:\JAVA\apache-maven-3.6.3\maven-repolocalRepository>

5.6、在IDEA中使用Maven

  1. 启动IDEA
  2. 创建一个MAVEN web项目
    JavaWeb学习回顾_第8张图片

JavaWeb学习回顾_第9张图片

  1. 等待项目导入包
    JavaWeb学习回顾_第10张图片

  2. 观察本地仓库中多了什么?

  3. 在IDEA中的Maven配置

    IDEA项目创建成功后,看一眼Maven配置

JavaWeb学习回顾_第11张图片

  1. 到这里,Maven在IDEA中的配置和使用就OK了。

5.7、创建一个普通的Maven项目

直接下一步,选择不使用模板

JavaWeb学习回顾_第12张图片

这个只有在web应用下才有:

JavaWeb学习回顾_第13张图片

5.8、在IDEA中标记文件夹的功能

JavaWeb学习回顾_第14张图片

项目结构配置

JavaWeb学习回顾_第15张图片

5.9、在IDEA中配置Tomcat

选择并找到Tomcat

JavaWeb学习回顾_第16张图片

JavaWeb学习回顾_第17张图片

解决警告问题

必须要的配置为什么会有这个问题:我们潍坊潍一个网站,需要指定一个文件夹名字;

JavaWeb学习回顾_第18张图片
JavaWeb学习回顾_第19张图片
JavaWeb学习回顾_第20张图片
JavaWeb学习回顾_第21张图片

5.10、pom文件

pom.xml是maven的核心配置文件



<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0modelVersion>


  <groupId>com.sykgroupId>
  <artifactId>javaweb-01-mavenartifactId>
  <version>1.0-SNAPSHOTversion>

  <packaging>warpackaging>

  <properties>

    <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>

    <maven.compiler.source>1.7maven.compiler.source>
    <maven.compiler.target>1.7maven.compiler.target>
  properties>


  <dependencies>

    <dependency>
      <groupId>junitgroupId>
      <artifactId>junitartifactId>
      <version>4.11version>
      <scope>testscope>
    dependency>
  dependencies>


  <build>
    <finalName>javaweb-01-mavenfinalName>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-clean-pluginartifactId>
          <version>3.1.0version>
        plugin>
        
        <plugin>
          <artifactId>maven-resources-pluginartifactId>
          <version>3.0.2version>
        plugin>
        <plugin>
          <artifactId>maven-compiler-pluginartifactId>
          <version>3.8.0version>
        plugin>
        <plugin>
          <artifactId>maven-surefire-pluginartifactId>
          <version>2.22.1version>
        plugin>
        <plugin>
          <artifactId>maven-war-pluginartifactId>
          <version>3.2.2version>
        plugin>
        <plugin>
          <artifactId>maven-install-pluginartifactId>
          <version>2.5.2version>
        plugin>
        <plugin>
          <artifactId>maven-deploy-pluginartifactId>
          <version>2.8.2version>
        plugin>
      plugins>
    pluginManagement>
  build>
project>

JavaWeb学习回顾_第22张图片

maven由于他的约定大于配置,我们之后可能遇到我们写的配置文件,无法导出或者生效的问题,

 
    <build>
        <resources>
            <resource>
                <directory>src/main/resourcesdirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                includes>
                <filtering>falsefiltering>
            resource>
            <resource>
                <directory>src/main/javadirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                includes>
                <filtering>falsefiltering>
            resource>
        resources>
    build>

5.12 IDEA操作

JavaWeb学习回顾_第23张图片

5.13、解决遇到的问题

  1. Maven 3.6.2

  2. Tomcat闪退

  3. IDEA中每次都要发重复配置Maven

    在IDEA中的全局默认配置中去配置

    JavaWeb学习回顾_第24张图片

  4. Maven项目中Tomcat无法配置

  5. maven默认web项目中的web.xml版本问题

JavaWeb学习回顾_第25张图片

  1. 替换为webapp4.0版本和tomcat一致

    
    
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                          http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0"
             metadata-complete="true">
    web-app>
    
    
    1. maven仓库的使用

      地址:https://mvnrepository.com/

6、Servlet

配置



    <servlet>
        <servlet-name>helloServletservlet-name>
        <servlet-class>com.syk.servlet.HelloServletservlet-class>
    servlet>

    <servlet-mapping>
        <servlet-name>helloServletservlet-name>

        <url-pattern>/sykurl-pattern>
    servlet-mapping>

6.1、Servlet简介

  • Servlet就是sun公司开发的动态web的技术
  • Sun在这些API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
    • 编写一个类,实现Servlet接口
    • 把开发好的Java类部署到web服务器中

把实现了Servlet类的Java程序叫做,Servlet

6.2、HelloServlet

Servlet接口Sun公司有两个默认的实现类:HttpServletGenericServlet

  1. 构建一个Maven项目,删掉里面的src目录,以后我们的学习就在这个项目里面建立Moudle,这个空的工程就是Maven的主工程;

  2. 关于Maven父子工程的理解:

    父项目中会有

      <modules>
            <module>servlet-01module>
        modules>
    

    子项目会有

       <parent>
            <artifactId>javaweb-02-maven01artifactId>
            <groupId>com.sykgroupId>
            <version>1.0-SNAPSHOTversion>
        parent>
    

    父项目中的Java子项目可以直接使用

    类似于 子类继承父类
    
  3. Maven环境优化

    1. 修改web.xml为最新的
    2. 将maven的结构搭建完整
  4. 编写一个Servlet程序

    1. 编写一个普通类

    2. 实现Servlet接口,这里直接继承HttpServlet

      package com.syk.servlet;
      
      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 HelloServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              PrintWriter writer = resp.getWriter();
              writer.print("Hello Servlet");// 响应流
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req, resp);
          }
      }
      
      
  5. 编写Servlet的映射

    为什么需要映射;我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器。所以我们需要在服务器中注册我们写的Servlet,还需要给他一个浏览器能够访问的路径;

    
    <servlet>
        <servlet-name>helloservlet-name>
        <servlet-class>com.syk.servlet.HelloServletservlet-class>
    servlet>
    
    <servlet-mapping>
        <servlet-name>helloservlet-name>
        <url-pattern>/hellourl-pattern>
    servlet-mapping>
    
  6. 配置Tomcat

    注意:配置项目的发布路径就可以了

  7. 启动测试

  8. 遇到的问题

    JavaWeb学习回顾_第26张图片

    解决方法:

JavaWeb学习回顾_第27张图片
JavaWeb学习回顾_第28张图片
JavaWeb学习回顾_第29张图片
完成:

原因:
因为maven依赖中配置的jar包只存在在项目中,并不存在在tomcat中,所以运行时在tomcat中找不到相应的jar包,故报错。
    所以需要将jar包引用到tomcat中

扩展 intellij idea module设置 dependencies的export

export 会改变当前module的依赖架包的共享范围:
例如有module A 配置依赖了jdbc.jar ,module B 又依赖 module A,但是如果你不在module A里的dependencies 里面把 JDBC。jar 
前面的 export 勾上,module B是无法用到 JDBC的内容的,编译无法通过。
前面所说的都是通过IDE配置的 依赖,但是 如果整个module之间的依赖都是通过maven 管理的,那就没有这么多事情,默认就是scope 全局共享,
现在用maven gradle的越来越多,可能这些ide 配置会再以后的版本中删除都有可能

原为链接: https://blog.csdn.net/langzi7758521/java/article/details/51804086

6.3、运行原理

Servlet是由Web服务器调用,Web服务器在收到浏览器请求址后,会:

JavaWeb学习回顾_第30张图片

6.4、mapping问题

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

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

     
        <servlet-mapping>
            <servlet-name>helloservlet-name>
            <url-pattern>/hellourl-pattern>
        servlet-mapping>
        
        <servlet-mapping>
            <servlet-name>helloservlet-name>
            <url-pattern>/hello2url-pattern>
        servlet-mapping>
    
  3. 一个Servlet可以指定通用映射路径

      
        <servlet-mapping>
            <servlet-name>helloservlet-name>
            <url-pattern>/*url-pattern>
        servlet-mapping>
    
  4. 指定一些后缀或者前缀等等。

    
        <servlet-mapping>
            <servlet-name>helloservlet-name>
            <url-pattern>*.dourl-pattern>
        servlet-mapping>
    
  5. 优先级问题

    制定了固有的映射路径优先级最高,如果找不到才会走默认的处理请求(即通配符处理)

6.5、ServletContext

web容器在启动的时候,它会为每个web程序都创建一个相应的ServletContext对象,它代表了当前的web应用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TVBlfkXB-1589261528401)(JavaWeb.assets/image-20200505100002467.png)]

1、实现共享数据

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

package com.syk.servlet;

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 ServletSet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        ServletContext context = this.getServletContext();
        String value="2020-05-05测试Servlet";
        context.setAttribute("key",value);

    }

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

package com.syk.servlet;

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 ServletGet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        ServletContext context = this.getServletContext();
        String value = (String) context.getAttribute("key");

        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html");

        resp.getWriter().print("key的值为:"+value);
    }

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

<servlet>
        <servlet-name>testsetservlet-name>
        <servlet-class>com.syk.servlet.ServletSetservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>testsetservlet-name>
        <url-pattern>/setkeyurl-pattern>
    servlet-mapping>

    <servlet>
        <servlet-name>testgetservlet-name>
        <servlet-class>com.syk.servlet.ServletGetservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>testgetservlet-name>
        <url-pattern>/getvalurl-pattern>
    servlet-mapping>
  • 测试结果

    在 “http://localhost:8080/s2/getval” 中可以取到 在 "http://localhost:8080/s2/setkey"中的值。
    但是有个问题,就是切换了不同的浏览器之后,依然可以取到在其他浏览器中输入的值。?这个是Tomcat服务器为每一个请求IP配置了同一个ServletContext,还是Tomcat为一个网站全局只配置了一个ServletContext??

  • 以下测试 session

    package com.syk.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    
    public class SessionSet  extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            HttpSession session = req.getSession();
            String value="2020-05-05测试Session";
            session.setAttribute("key",value);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.doPost(req, resp);
        }
    }
    
    
    package com.syk.servlet;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    
    public class SessionGet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            HttpSession session = req.getSession();
            String value = (String) session.getAttribute("key");
    
            resp.setCharacterEncoding("utf-8");
            resp.setContentType("text/html");
    
            resp.getWriter().print("key的值为:"+value);
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.doPost(req, resp);
        }
    }
    
    
                    <servlet>
                    <servlet-name>sessionsetservlet-name>
                    <servlet-class>com.syk.servlet.SessionSetservlet-class>
                    servlet>
                    <servlet-mapping>
                    <servlet-name>sessionsetservlet-name>
                    <url-pattern>/setskurl-pattern>
                    servlet-mapping>
    
                    <servlet>
                    <servlet-name>sessiongetservlet-name>
                    <servlet-class>com.syk.servlet.SessionGetservlet-class>
                    servlet>
                    <servlet-mapping>
                    <servlet-name>sessiongetservlet-name>
                    <url-pattern>/getsvurl-pattern>
                    servlet-mapping>
    
    
  • session结果:

    tomcat服务器会为每一个浏览器请求配置同一个 session,会为不同的浏览器请求配置不同的session,因此可以将每个登陆网站的用户的数据添加到session会话中,以此来保证数据响应的正确。也可以将所有的所有的统计信息,比如当前在线用户数 等信息存入 ServletContext中。ServletContext类似于类中的类变量。

2、获取初始化参数

 
    <context-param>
        <param-name>urlparam-name>
        <param-value>jdbc:mysql//localhost:3306/mybatisparam-value>
    context-param>
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String initParameter = context.getInitParameter("url");
        resp.getWriter().print(initParameter);
    }

3、请求重定向

   ServletContext context = this.getServletContext();
        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/sd05");// “/”代表当前web项目下
        System.out.println("进入ServletDemo06-doGet");
        requestDispatcher.forward(req,resp);

重定向与请求转发的区别

JavaWeb学习回顾_第31张图片

4、读取资源文件

Properties 【属性】[import java.util.Properties;]

  • 在java目录下新建properties文件
  • 在resources目录下新建properties文件

发现:都被打包到了同一个路径下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H3xKg9d1-1589261528403)(JavaWeb.assets/image-20200505145203903.png)]

都在WEB-INF下的classes路径下,我们俗称这个路径为classpath;

思路:需要一个文件流去读取新建的properties文件

[db.properties]

username=root
password=123456789
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties");
    Properties properties = new Properties();
    properties.load(is);
    String name = properties.getProperty("username");
    String pwd = properties.getProperty("password");
    resp.getWriter().print(name+":"+pwd);
}

测试结果:

root:123456789

总结:这个Properties类好像就是专门为了从流中读取这种键值对形式的值写的类下面是该类的详细使用说明

https://www.iteye.com/blog/gimgen1026-152023

6.6、HttpServletResponse

1、简单分类

2、下载文件

  1. 向浏览器输出消息

  2. 下载文件

    1. 要获取下载文件的路径
    2. 下载的文件名是啥
    3. 设置想办法让浏览器能够支持下载我们需要的东西
    4. 获取下载文件的输入流
    5. 创建缓冲区
    6. 获取OutputStream对象
    7. 将FileOutputStream流写入到buffer缓冲区
    8. 使用OutputStream将缓冲区的数据输出到客户端!
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 下载文件
    /*
    1、找到文件路径
    2、创建文件流FileInputStream
    3、将流存入ResponseOutputStream中输出到前端
    */
        ServletContext context = this.getServletContext();
        String path = context.getRealPath("WEB-INF/classes/测试.png");
        FileInputStream inputStream = new FileInputStream(path);
    
        String filename=path.substring(path.lastIndexOf('\\')+1);
        //resp.setHeader("Content-Disposition","attachment;filename="+filename);
        resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(filename,"utf-8"));
        ServletOutputStream outputStream = resp.getOutputStream();
        int len=0;
        byte[] buffer=new byte[1024];
        while  ((len=inputStream.read(buffer))!=-1){
            outputStream.write(buffer,0,len);
        }
        outputStream.flush();
        outputStream.close();
        inputStream.close();
    }
    

3、写验证码

使用BufferedImage 类、ImageIO去实现一个图片验证码

疑问:StringBuffer与StringBuilder

 @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    BufferedImage bImg = new BufferedImage(100, 40, BufferedImage.TYPE_INT_RGB);
//        Graphics2D graphics = bImg.getGraphics();
    Graphics2D g = (Graphics2D) bImg.getGraphics();
    // 画背景
    g.setColor(Color.blue);
    g.fillRect(0,0,100,40);
    // 画数字
    g.setColor(Color.white);
    g.setFont(new Font(null,Font.BOLD,20));
    g.drawString(createNum(),0,20);
    // 画两条线.用于干扰
    g.setColor(Color.white);   		                     
    g.drawLine(getRandomInt(0,10),getRandomInt(5,35),getRandomInt(90,200),getRandomInt(5,35));
    g.setColor(Color.yellow);
  g.drawLine(getRandomInt(0,10),getRandomInt(5,35),getRandomInt(90,200),getRandomInt(5,35));

    resp.setHeader("refresh","3"); // 自动刷新
    resp.setHeader("content-type","image/jpeg");// 配置内容
    resp.setHeader("Expires","-1");// 不缓存
    resp.setHeader("Pragma","no-cache");// 不缓存
    resp.setHeader("Cache-Control","no-cache");// 不缓存

    ImageIO.write(bImg,"jpg",resp.getOutputStream());

}

/**
 * 获取7位数字的验证码
 * @return
 */
private String createNum() {
    Random random = new Random();
    String num = random.nextInt(9999999)+"";
    StringBuffer buffer = new StringBuffer();
    for(int i=0;i<7-num.length();i++){
        buffer.append("0");
    }
    return buffer.toString()+num;
}

private int getRandomInt(int bound1,int bound2){
    Random random = new Random();
    return random.nextInt(bound2-bound1)+bound1;
}

支持和StringBuilder所有相同的操作,不同的是StringBuffer是线程安全的,在声明的方法中使用synchronized关键字进行修饰,因此单线程中一般要比StringBuilder效率低

4、重定向

resp.sendRedirect("/s2/img01");// 需要加上项目路径
// resp.setStatus(302);
// resp.setHeader("Location","/s2/img01");
两者完全等价

JavaWeb学习回顾_第32张图片

面试题:请你聊聊重定向和转发的区别?

相同点

  • 页面都会跳转

不同点

  • 请求转发的时候,url不会跳转
  • 重定向时候,url地址栏会发生变化

5、jsp定位




<%--${pageContext.request.contextPath}代表当前的项目--%>
<%--${pageContext.servletContext.contextPath} 实测,路径等价--%>
用户名:
密码:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String username = req.getParameter("username");
    String pwd = req.getParameter("password");
    System.out.println(username+":"+pwd);
    resp.sendRedirect("/s2/Success.jsp");
}

if (session.isNew()) {
    resp.getWriter().write("新创建的会话,Session:" + id);
} else {
    resp.getWriter().write("已经存在的会话,Session:" + id);
}

}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding(“utf-8”);
resp.setContentType(“text/html”);
HttpSession session = req.getSession();

String id1 = session.getId();
Person p1=(Person)session.getAttribute("user");

resp.getWriter().write("旧的Session,Session:" + id1);
resp.getWriter().write("person:" + p1.toString());

session.invalidate();
// 第二次
HttpSession session2 = req.getSession();
String id2 = session2.getId();
Person p2=(Person)session2.getAttribute("user");

resp.getWriter().write("注销后的Session,Session:" + id2);
resp.getWriter().write("注销后的person:" + p2.toString());

}


**会话自动过期:web.xml配置**

​~~~xml
 
        
        15
    

Cookie原理

JavaWeb学习回顾_第33张图片

Session原理

JavaWeb学习回顾_第34张图片

ServletContext和applicationContext都是获取作用域,此处可以存储一些共有的信息

JavaWeb学习回顾_第35张图片

8、JSP

8.1、什么是JSP

Java Server Pages

8.2、JSP原理

本机jsp编译后的地址

C:\Users\Sun\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Unnamed_javaweb-02-maven01\work\Catalina\localhost\jstl\org\apache\jsp

8.3、JSP基础语法

任何语言都有自己的语法。JSP作为java技术的一种应用,它拥有自己扩充的语法(了解、知道即可!),Java所有语法都支持

JSP表达式

作用:用来将程序的输出、输出到客户端
<%= 变量或者表达式 %>
<%= new java.util.Date() %>

JSP脚本片段

<%
        String username = request.getParameter("name");
        String userpwd = request.getParameter("pwd");
        if (username!=null&&userpwd!=null){
            if ("admin".equals(username)&&"123456".equals(userpwd)){
                out.print("管理员登陆成功");
                out.print("当前输入 ->"+username+":"+userpwd);
            }else   {
                out.print("账号或者密码不对");
                out.print("当前输入2 ->"+username+":"+userpwd);
            }
        }
    %>

JSP声明

<%! public void kuang(){System.out.println("123");} %>

jsp声明:会被编译到 JSP 生成 java 的类中!其它的,就会被生成到 _jspService 方法中!

JSP的注释不会在客户端显示,html的注释则会在客户端显示

8.4、JSP指令

<%@ page args...%>
<%@ include file="footer.jsp"%>   // 会将两个网页正真的从源码程度上 “和二为一”
    
jsp标签
<jsp:include page="/footer.jsp">  // 拼接页面,本质还是两个页面
    

8.5、9大内置对象

final javax.servlet.http.HttpServletRequest request, 
final javax.servlet.http.HttpServletResponse response
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
  • pageContext;
  • request,
  • response
  • session
  • application 【ServletContext】
  • config 【ServletConfig】
  • out
  • page
  • exception

四大作用域

pageContext.setAttribute("name1", "1号"); // 保存的数据只在一个页面中有效
request.setAttribute("name2", "2号"); // 保存的数据只在一次请求中有效,使用转发会携带该数据
session.setAttribute("name3", "3号");// 保存的数据只在一次会话中有效
application.setAttribute("name4", "4号");// 保存的数据在服务器中有效,从打开服务器到关闭服务器

JavaWeb学习回顾_第36张图片

8.6、JSP标签、JSTL标签、EL表达式

<dependencies>
    <dependency>
        <groupId>javax.servlet.jsp.jstlgroupId>
        <artifactId>jstl-apiartifactId>
        <version>1.2version>
    dependency>
    <dependency>
        <groupId>taglibsgroupId>
        <artifactId>standardartifactId>
        <version>1.1.2version>
    dependency>
dependencies>

EL表达式: ${}

JavaWeb学习回顾_第37张图片

9、JavaBean

实体类

JavaBean有特定的写法:

  • 必须有一个无参构造

  • 属性必须私有化

  • 必须有对应的get/set方法;

一般用来和数据库的字段做映射 ORM;

ORM:对象关系映射

  • 表----->类
  • 字段 -> 属性
  • 行记录 -> 对象

people表

id name age address
1 张三1号 3 西安国际大酒店
2 张三2号 18 西安国际大酒店
3 张三3号 100 西安国际大酒店
class People{
    private int id;
    private String name;
    private String age;
    private String address
}

class A{
    new People(1,"张三1号",3,"西安");
    new People(1,"张三1号",3,"西安");
    new People(1,"张三1号",3,"西安");
}

建议存放实体类的包名: pojo,entity,dto,vo

新建数据库

JavaWeb学习回顾_第38张图片

jsp标签中使用 标签

JavaWeb学习回顾_第39张图片

10、MVC三层架构

什么是MVC: Model view Controller 模型、视图、控制器

10.1、早些年

JavaWeb学习回顾_第40张图片

用户直接访问控制层,控制层就可以直接操作数据库:

servlet--CRUD-->数据库
弊端:程序十分臃肿,不利于维护
servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码

架构:没有什么是加一层解决不了的
程序员调用
|
JDBC
|
MySql Oracle SqlServer ....

10.2、MVC三层架构

JavaWeb学习回顾_第41张图片

Model

  • 业务处理:业务逻辑(Service)
  • 数据持久层:CRUD (Dao)

View

  • 展示数据
  • 提供链接发起Servlet请求(a,form,img…)

Controller

  • 接收用户的请求:(req、请求参数、Session…)

  • 交给业务层处理对应的代码

  • 控制视图的跳转

    登陆-->接收用户的登陆请求--->处理用户的请求(获取用户登陆的参数,username,password)--->交给业务层处理登陆业务(判断用户名、密码是否正确  事务)---->Dao层查询用户名和密码是否正确---->查数据库
    

11、Filter(重要)

统一过滤乱码等问题

package com.syk.filter;

import javax.servlet.*;
import java.io.IOException;

public class CharaterFilter implements Filter {

public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("初始化过滤器CharaterFilter");
}

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    System.out.println("进入CharaterFilter doFilter");
    // 过滤乱码等情况
    servletRequest.setCharacterEncoding("utf-8");
    servletResponse.setCharacterEncoding("utf-8");
    servletResponse.setContentType("text/html;charset=UTF-8");
    filterChain.doFilter(servletRequest,servletResponse);
}

public void destroy() {
    System.out.println("销毁过滤器CharaterFilter");
}
}

<filter>
    <filter-name>CharaterFilterfilter-name>
    <filter-class>com.syk.filter.CharaterFilterfilter-class>
filter>
<filter-mapping>
    <filter-name>CharaterFilterfilter-name>
    <url-pattern>/*url-pattern>
filter-mapping>

12、监听器

13、过滤器、监听器常见应用

14、JDBC

jdbc驱动

JavaWeb学习回顾_第42张图片

需要jar包支持:

  • java.sql
  • javax.sql
  • mysql-connecter-java… 连接驱动(必须要导入)

视眼环境搭配

导入数据库依赖

<dependencies>
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
        <version>5.1.47version>
    dependency>
dependencies>

IDEA中连接数据库

JavaWeb学习回顾_第43张图片

JDBC固定步骤

  1. 加载驱动
  2. 连接数据库,代表数据库
  3. 向数据库发送SQL的对象Statement:CRUD
  4. 编写SQL(根据业务)
  5. 执行SQL
  6. 关闭连接
public static void main(String[] args) throws ClassNotFoundException, SQLException {
    // 配置信息
    // useUnicode=true&characterEncoding=utf-8 解决中文乱码问题
    String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
    String username = "root";
    String password = "123456";

    // 1、加载驱动
    Class.forName("com.mysql.jdbc.Driver");
    // 2、连接数据库,代表数据库
    Connection connection = DriverManager.getConnection(url, username, password);
    // 3、相关数据库发送sql的对象Statement 、PreparedStatement :CRUD   Statement:普通的sql;PreparedStatement:预编译,安全的sql
    Statement statement = connection.createStatement();
    // PreparedStatement

    // 4、编写sql
    String sql = " select * from users ";

    // 5、执行查询SQL,返回一个ResultSet
    ResultSet rs = statement.executeQuery(sql);

    while (rs.next()) {
        System.out.println("id:"+rs.getObject("id"));
        System.out.println("name:"+rs.getObject("name"));
        System.out.println("password:"+rs.getObject("password"));
        System.out.println("birthday:"+rs.getObject("birthday"));
        System.out.println("email:"+rs.getObject("email"));
    }
    // 6、关闭连接,释放资源(一定要做) 先开后关
    rs.close();
    statement.close();
    connection.close();
}

预编译SQL

public static void main(String[] args) throws ClassNotFoundException, SQLException {
    // 使用安全的预编译的sql

    Class.forName("com.mysql.jdbc.Driver");

    String url="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
    String username="root";
    String password="123456";
    Connection connection = DriverManager.getConnection(url, username, password);

    String sql=" insert into users(id, name, password, birthday, email) VALUE (?,?,?,?,?) ";
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    preparedStatement.setInt(1,5);
    preparedStatement.setString(2,"狂神说Java");
    preparedStatement.setString(3,"12345678");
    preparedStatement.setDate(4,new Date(new java.util.Date().getTime()));
    preparedStatement.setString(5,"[email protected]");

    int i = preparedStatement.executeUpdate();
    if (i>0){
        System.out.println("数据插入成功");
    }
    preparedStatement.close();
    connection.close();
}

事物

要么都成功,要么都失败!

ACID原则:保证数据的安全

开启事物
事物提交 commit()
事物回滚 rollback()
关闭事物
    
转账:
A:1000
B:1000
    
A(900) --100--> B(1100)     

Junit 单元测试

依赖

<dependency>
    <groupId>junitgroupId>
    <artifactId>junitartifactId>
    <version>4.12version>
    <scope>testscope>
dependency>

简单使用

@Test 注解只在方法上有效,只要加了这个注解的方法,就可以直接运行

@Test
public void ss(){
    System.out.println("123");
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ywK1jjr1-1589261528420)(JavaWeb.assets/image-20200509200130044.png)]

失败的时候是红色:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N87b0IoH-1589261528420)(JavaWeb.assets/image-20200509200156734.png)]

搭建一个环境:

事物

start transaction ;

commit ;
rollback ;
// 通知数据库开启事物,false开启
connection.setAutoCommit(false);
// 提交事务
connection.commit();
// 事物回滚
connection.rollback();

SMBMS

说明: 超市订单管理系统,,使用jsp+servlet项目,新手学习的例子,简单好用
(Supermarket order management system, the use of jsp+servlet project, novice learning examples, simple and easy to use)

架构

JavaWeb学习回顾_第44张图片

数据库

JavaWeb学习回顾_第45张图片

项目如何搭建?

考虑使用bushiyongmaven?依赖,jar包

1、项目搭建准备工作

  1. 搭建一个maven web项目

  2. 配置Tomcat

  3. 测试项目是否能够运行起来

  4. 导入项目中会遇到的jar包

    jsp,servlet,mysql驱动,jstl,stand

    <dependencies>
    <dependency>
      <groupId>javax.servletgroupId>
      <artifactId>servlet-apiartifactId>
      <version>2.5version>
    dependency>
    <dependency>
      <groupId>javax.servlet.jspgroupId>
      <artifactId>jsp-apiartifactId>
      <version>2.2version>
    dependency>
    <dependency>
      <groupId>javax.servlet.jsp.jstlgroupId>
      <artifactId>jstl-apiartifactId>
      <version>1.2version>
    dependency>
    <dependency>
      <groupId>taglibsgroupId>
      <artifactId>standardartifactId>
      <version>1.1.2version>
    dependency>
    
    <dependency>
      <groupId>junitgroupId>
      <artifactId>junitartifactId>
      <version>4.11version>
      <scope>testscope>
    dependency>
    dependencies>
    
  5. 创建项目包结构

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y6vyoDbM-1589261528423)(JavaWeb.assets/image-20200509214752272.png)]

  6. 编写实体类

    ORM映射:表-实体类

  7. 编写基础公共类

    1. 数据库配置文件

      driver=com.mysql.jdbc.Driver
      url=jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=utf-8
      username=root
      pawword=123456
      
    2. 编写数据库的公共类

      package com.syk.dao;
      
      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) {
                  e.printStackTrace();
              }
              driver=properties.getProperty("driver");
              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 execute(Connection connection,String sql,Object[] params,ResultSet resultSet,PreparedStatement preparedStatement) throws SQLException {
              preparedStatement = connection.prepareStatement(sql);
              for (int i = 0; i < params.length; i++) {
                  preparedStatement.setObject((i+1),params[i]);
              }
              resultSet = preparedStatement.executeQuery();
              return resultSet;
          }
      
          // 编写增删改公共方法
          public static int execute(Connection connection,String sql,Object[] params,PreparedStatement preparedStatement) throws SQLException {
              preparedStatement = connection.prepareStatement(sql);
              for (int i = 0; i < params.length; i++) {
                  preparedStatement.setObject((i+1),params[i]);
              }
              int updateRows = preparedStatement.executeUpdate();
              return updateRows;
          }
      
          // 释放资源
          public static boolean closeResource(Connection connection,PreparedStatement preparedStatement,ResultSet resultSet){
              boolean flag=true;
              if (resultSet!=null){
                  try {
                      resultSet.close();
                      // gc回收
                      resultSet=null;
                  } catch (SQLException throwables) {
                      throwables.printStackTrace();
                      flag=false;
                  }
              }
              if (preparedStatement!=null){
                  try {
                      preparedStatement.close();
                      // gc回收
                      preparedStatement=null;
                  } catch (SQLException throwables) {
                      throwables.printStackTrace();
                      flag=false;
                  }
              }
              if (connection!=null){
                  try {
                      connection.close();
                      connection=null;
                      // gc回收
                  } catch (SQLException throwables) {
                      throwables.printStackTrace();
                      flag=false;
                  }
              }
              return flag;
          }
      }
      
    3. 编写字符编码过滤器

  8. 导入静态资源

2、登陆功能实现

JavaWeb学习回顾_第46张图片

  1. 编写前端页面

  2. 设置欢迎页

    <welcome-file-list>
        <welcome-file>login.jspwelcome-file>
    welcome-file-list>
    
  3. 编写dao层登陆的接口

    public interface UserDao {
        public User getLoginUser(Connection connection, String userCode) throws SQLException;
    }
    
  4. 编写dao的实现类

    public class UserDaoImpl implements UserDao {
        public User getLoginUser(Connection connection, String userCode) throws SQLException {
    
            PreparedStatement pstm=null;
            ResultSet rs = null;
            User user = null;
    
            if (connection != null) {
                String sql = " select * from smbms_user where userCode=? ";
                Object[] params = {userCode};
    
                rs = BaseDao.execute(connection, pstm, rs, sql, params);
                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("userPassword"));
                    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("createdBy"));
                    user.setCreationDate(rs.getDate("creationDate"));
                    user.setModifyBy(rs.getInt("modifyBy"));
                    user.setModifyDate(rs.getDate("modifyDate"));
                }
    
                BaseDao.closeResource(null,pstm,rs);
            }
            return user;
        }
    }
    
  5. 业务层接口

    public interface UserService {
        //用户登陆
        public User login(String userCode,String password);
    }
    
  6. 业务层实现类

    // 业务层都会调用dao层,所以我们要引用Dao层
    private UserDao userDao;
    public UserServiceImpl(){
        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;
    }
    
    1. 编写servlet

      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          System.out.println("进入LoginServlet");
          // 调用service层
          String userCode = req.getParameter("userCode");
          String userPassword = req.getParameter("userPassword");
      
          UserService service=new UserServiceImpl();
          User user = service.login(userCode, userPassword);
      
          if (user!=null){
              // 登陆成功
              req.getSession().setAttribute(Constants.USER_SESSION,user);
              resp.sendRedirect("jsp/frame.jsp");
          }else   {
              req.setAttribute("error","登陆失败了,小可爱 O,O");
              req.getRequestDispatcher("login.jsp").forward(req,resp);// 转发
          }
      }
      
    2. 注册Servlet

      <servlet>
              <servlet-name>LoginServlet</servlet-name>
              <servlet-class>com.syk.servlet.user.LoginServlet</servlet-class>
          </servlet>
          <servlet-mapping>
              <servlet-name>LoginServlet</servlet-name>
              <url-pattern>/login.do</url-pattern>
          </servlet-mapping>
      
    3. 测试能够访问

3、登陆功能优化

注销功能:

思路:移除Session,返回登陆页

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

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

注册xml

<servlet>
    <servlet-name>LogoutServletservlet-name>
    <servlet-class>com.syk.servlet.user.LogoutServletservlet-class>
servlet>
<servlet-mapping>
    <servlet-name>LogoutServletservlet-name>
    <url-pattern>/jsp/logout.dourl-pattern>
servlet-mapping>

登陆拦截优化

编写过滤器,并注册

public class SysFilter implements Filter {

public void init(FilterConfig filterConfig) throws ServletException {

}

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request= (HttpServletRequest) servletRequest;
    HttpServletResponse response= (HttpServletResponse) servletResponse;

    User user = (User)request.getSession().getAttribute(Constants.USER_SESSION);
    if (user==null){
        response.sendRedirect(request.getServletContext().getContextPath()+"/error.jsp");
    }else{
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

public void destroy() {

}
}

密码修改

  1. 导入前端素材

  2. 写项目,建议从底层向上写

    JavaWeb学习回顾_第47张图片

  3. UserDao 接口

  4. UserDao 接口实现类

实现文件上传

JavaWeb学习回顾_第48张图片
JavaWeb学习回顾_第49张图片
实现代码:

**尚未收录**

邮件发送

JavaWeb学习回顾_第50张图片

实现代码:

**尚未收录**

你可能感兴趣的:(JAVA,基础知识)