JavaEE-WEB

Javaweb (狂神说)

我的maven常用配置

<?xml version="1.0" encoding="UTF-8"?>

<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.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>testa</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>testa Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>
  <dependencies>
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.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/javax.servlet.jsp-api -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.3</version>
      <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.19</version>
    </dependency>
  </dependencies>
</project>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入jstl标签--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

1.Tomcat安装

环境配置

1.下载和安装

Apache Tomcat® - Apache Tomcat 10 Software Downloads

image-20211115164351268

2.启动和配置

启动/关闭tomcat

image-20211115164547959

闪退原因:

java环境未配置;

环境冲突兼容性问题。

核心配置文件

修改端口号入口:

image-20211115172118397

image-20211115172330950

此处可以修改端口号

查询主页面详情

image-20211115173558420

image-20211115173617190

添加域名操作

image-20211115174300743

修改后浏览器搜索修改的域名:8080,发现访问不了

需要在hosts文件中进行添加新的域名

C:\Windows\System32\drivers\etc\hosts

image-20211115174706415

之后重启服务器startup.bat

默认端口号:

tomcat:8080

mysql:3306

http:80

https:443

tomcat默认主机名:localhost

默认网站存放的位置为:webapps

image-20211115175832709

3.面试题

网站是怎么被访问的

1.输入一个域名,回车

2.检查本机是否存在该域名的映射

C:\Windows\System32\drivers\etc\hosts

(1)有,直接返回对应的ip地址,在该地址中若有需要访问的web程序,可以直接访问

(2)没有,访问DNS(全世界的域名管理系统),找到域名则返回

image-20211115182449488

4.自建web网站

在webapps中,重写root文件夹(命名为newWeb),保存

保留一个web-inf文件夹,其中编写一个index.html(存放默认页面)

访问:localhost:8080/newWeb

自学:localhost:8080/examples 存放实例

5.网站应有的结构

--webapps:tomcat服务器的web目录

-root

-newWeb 网站的目录名

​ -WEB-INF

​ -classes java程序

​ -lib web应用所依赖的jar包

​ -web.xml 网站的配置文件

​ -index.html 默认的首页

​ -static

​ -css

​ -style.css

​ -js

​ -img

2.HTTP

1.什么是http

HTTP(超文本传输协议)是一个简单的请求-响应协议,它通常运行在TCP之上。端口:80

文本:html,字符串....

超文本:图片,音乐,视频,定位....

HTTPS,端口:443,安全

2.两个时代

http1.0(http/1.0)客户端与web服务器连接后,只能获得一个web资源,然后断开连接

http2.0(http/1.1)客户端与web服务器连接后,可以获得多个web资源

3.http请求

客户端---发请求---服务器

百度:

1. 请求 URL: 

   https://www.baidu.com/

2. 请求方法: 

   GET

3. 状态代码: 

   200 OK

4. 远程地址: 

   163.177.151.109:443
Accept: text/html
application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6   语言
Connection: keep-alive

1.请求行

请求方式:get/post

get:请求能携带的参数较少,大小有限制,会在url地址栏显示数据内容,不安全,但高效

post:请求能携带的参数没有限制,大小也没有限制,不会在url地址栏显示数据内容,安全

2.消息头

Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding 支持编码格式
Accept-Language 支持语言环境
Cache-Control 缓存控制
Connection 告诉浏览器,请求完成是断开还是连接
HOST 主机
4.http响应

服务器---响应---客户端

百度:

Cache-Control: private  缓存控制
Connection: keep-alive  连接:保持活跃
Content-Encoding: gzip  编码
Content-Type: text/html;charset=utf-8  类型

1.响应体

Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding 支持编码格式
Accept-Language 支持语言环境
Cache-Control 缓存控制
Connection 告诉浏览器,请求完成是断开还是连接
HOST 主机
REFLUSH 告诉服务端多久刷新一次
Location 让网页重新定位

2.响应状态码

200 请求响应成功

3** 请求重定向,重新到我给你的新位置

4** 找不到资源

5** 服务器代码错误 502网关错误

面试题

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

3.Maven

1.maven项目架构管理工具

核心思想:约定大于配置(有约束不要超越)

2.阿里云镜像

D:\环境配置\apache-maven-3.8.3\conf\settings.xml

<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/
</url>
<!--<mirrorOf>central</mirrorOf> -->
<mirrorOf>*</mirrorOf>
</mirror>
3.本地仓库建立
 <localRepository>D:\环境配置\apache-maven-3.8.3\maven-repo</localRepository>
4.创建Maven项目

image-20211115205411423

image-20211115205400396

image-20211115205343018

image-20211115205616722

设置idea默认maven路径

image-20211115205824542

idea的maven环境设置完成

5.Tomcat配置

image-20211115210818898

添加配置

image-20211115210833413

image-20211115210851939

image-20211115211114457

image-20211115211801416

image-20211115211829153

6.pom文件

pom.xml是maven项目的设置源文件

<?xml version="1.0" encoding="UTF-8"?>

<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.0</modelVersion>
<!--配置的GAV-->
  <groupId>com.Jmin</groupId>
  <artifactId>javaweb</artifactId>
  <version>1.0-SNAPSHOT</version>
<!--  项目打包方式
jar java应用
war javaweb应用-->
  <packaging>war</packaging>

  <name>javaweb Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

<!--  配置-->
  <properties>
<!--    默认的构建编码-->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
<!--    依赖项目-->
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
<!--项目构建需要的东西-->
  <build>
    <finalName>javaweb</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>
7.资源导出问题

maven由于约定大于配置,之后可能遇到编写的配置文件无法导出或者生效的问题,解决方法:

<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <excludes>
        <exclude>**/*.properties</exclude>
        <exclude>**/*.xml</exclude>
      </excludes>
      <filtering>false</filtering>
    </resource>
    <resource>
      <directory>src/main/java</directory>
      <includes>
        <include>**/*.properties</include>
        <include>**/*.xml</include>
      </includes>
      <filtering>false</filtering>
    </resource>
  </resources>
</build>
8.生成目录树

ctrl+alt+u

image-20211115213330148

9.建立映射
<!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>
  <display-name>Archetype Created Web Application</display-name>
<!--  注册servlet-->
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>helloServlet</servlet-class>
  </servlet>
<!--  一个servlet对应一个mapping映射-->
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
<!--    映射的请求路径-->
    <url-pattern>/Jmin</url-pattern>
  </servlet-mapping>
</web-app>

4.Servlet

1. 什么是servlet

sun公司开发的动态web的一门技术

1.在这些api中提供了一个接口叫做servlet,

2.把开发好的java类部署到web服务器中.

所以,把实现了servlet接口的java程序叫做servlet

2.HelloServlet

1.创建项目,删除里面的src目录,以后的学习就在这个项目中建立Moudel,空的工程叫做maven的主工程.

需要删除依赖包中的是scope标签

2.关于maven父子工程的对比理解

父项目:

<modules>
    <module>myServlet</module>
</modules>

子项目:

<parent>
  <artifactId>servlettest</artifactId>
  <groupId>org.example</groupId>
  <version>1.0-SNAPSHOT</version>
</parent>

3.Maven环境优化

修改web.xml为最新

maven结构搭建完整

4.编写一个servlet程序

1.编写一个普通类

2.实现servlet接口,直接继承HttpServlet

package org.example.myservlet;

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.println("hello,myservlet");
    }

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

5.编写servlet的映射

为什么需要映射?

​ java程序需要通过浏览器访问,而浏览器需要连接web服务器,因此需要我们在web服务器中注册编写的Servlet,同时提供浏览器能够访问的路径。

webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>org.example.myservlet.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>

</web-app>
        

映像设置完毕

6.开启服务器(需要tomcat9版本,10会报500错误)

image-20211116013216675

成功撒花

3.Servlet原理
4.Mapping问题(多项目爆红问题)

避免多个不同servlet项目于同一个web-app中爆红

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

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>/hello/*</url-pattern>
  </servlet-mapping>

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

<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/www.hello.com</url-pattern>
</servlet-mapping>

5.重写404页面

注意,号前面不可以加映射路径,例如abc/

<servlet>
  <servlet-name>error</servlet-name>
  <servlet-class>org.example.myservlet.ERROR</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>error</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>
5.ServletContext对象

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

1.java共享数据

可以从java中共享数据

在servlet中保存的数据,可以在另外一个servlet中得到。

同一个目录下的java项目

java1

package org;

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 context extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String h = "你好世界";
        ServletContext context = this.getServletContext();
        context.setAttribute("hello",h);
    }

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

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.BufferedWriter;
import java.io.IOException;

public class context2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String hello = (String) context.getAttribute("hello");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        resp.getWriter().print("i would like to say:"+hello);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
<!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"
>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>test1</servlet-name>
    <servlet-class>org.context</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>test1</servlet-name>
    <url-pattern>/hello1</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>test2</servlet-name>
    <servlet-class>org.context2</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>test2</servlet-name>
    <url-pattern>/hello2</url-pattern>
  </servlet-mapping>
</web-app>
2.web.xml中共享数据

初始化web中的应用参数

<context-param>
  <param-name>url</param-name>
  <param-value>jdbc:mysql://localhost:3306/meeting</param-value>
</context-param>
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 test extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        String url = servletContext.getInitParameter("url");
        resp.getWriter().print(url);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
3.转发数据
public class transtor extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
//        实现转发,即跳转其他页面
        context.getRequestDispatcher("/其他页面的路径").forward(req,resp);

    }

转发路径不发生改变

image-20211119170702220

4.读取资源文件

Properties

在Java目录下新建properties

在resources目录下欣建properties项目

discovered:都被打包在同一个路径下:classes,俗称classpath

image-20211120155014600

image-20211120155053351

package page;

import javax.print.DocFlavor;
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.InputStream;
import java.io.PrintWriter;
import java.util.Properties;

public class test3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html");
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/res.properties");
//        需要从target中提取路径/WEB-INF/classes/res.properties
        Properties properties = new Properties();
        properties.load(is);
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        PrintWriter writer = resp.getWriter();
        writer.println("通过读取properties数据得到:\n");
        writer.println("用户名为:" + user + "\n");
        writer.println("密码为:" + password + "\n");


    }

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

web服务器接受客户端的http请求,针对这个请求,分别创建一个代表请求的该对象

获取客户端请求传来的数据,用HttpServletRequest

要给客户端响应一些信息,用HttpServletResponse

1.状态码定义

int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;

2.常见应用

1.向浏览器输出信息

2.下载文件

  1. 获取下载文件的路径

  2. 下载的文件名

  3. 设置让浏览器能够支持下载我们需要的东西

  4. 获取下载文件的输入流

  5. 创建缓冲区

  6. 获取OutputSteam对象

  7. 将FileOutputStream流写入到buffer缓冲区

  8. 使用OutputStream将缓冲区的数据输出到客户端

    package page;
    
    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.BufferedInputStream;
    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 = "C:\\Users\\29522\\Desktop\\学习资料2.0\\servletContext\\project\\target\\classes\\picture.png";
            System.out.println("下载文件的路径:"+realPath);
    //2. 下载的文件名
    //        可以截取/号后面
            String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
    //3. 设置让浏览器能够支持下载我们需要的东西,重点,用URLEncoder.encode(fileName,"UTF-8"))进行编码,确保文件名可为中文名
            resp.setHeader("Content-disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
    //4. 获取下载文件的输入流
            FileInputStream fis = new FileInputStream(realPath);
    //5. 创建缓冲区
    //        BufferedInputStream bis = new BufferedInputStream(fis);错误写法,该写法只支持文本文件
            int len;
            byte[] buffer = new byte[1024];
    //6. 获取OutputSteam对象
            ServletOutputStream outputStream = resp.getOutputStream();
    //7. 将FileIntputStream流写入到buffer缓冲区
            while ((len = fis.read(buffer))>0){
                outputStream.write(buffer,0,len);
            }
            outputStream.close();
            fis.close();
    //8. 使用OutputStream将缓冲区的数据输出到客户端
    
    //##### 6.2HttpServletRequest
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req,resp);
        }
    }
    

    3.验证码实现

package page;

import javax.imageio.ImageIO;
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.BufferedInputStream;
import java.io.IOException;
import java.util.Random;

public class identifyingCode extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        让浏览器3秒刷新一次
        resp.setHeader("refress","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.setFont(new Font(null,Font.BOLD,20));
        g.drawString(makeNum(),0,20);
//        命令浏览器用图片打开
        resp.setContentType("image/jgep");
//        避免存在缓存
        resp.setDateHeader("expires",-1);
        resp.setHeader("Cache-Control","no-cache");
        resp.setHeader("Pragma","no-cache");
//        写给浏览器
        boolean jpg = ImageIO.write(image, "jpg", resp.getOutputStream());
    }
//    随机数为7位数
    private String makeNum(){
        Random random = new Random();
        String num = random.nextInt(9999999) + "";
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < 7 - num.length(); i++) {
            stringBuffer.append("0");
        }
        num = stringBuffer.toString() + num;
        return num;
    }

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

4.重定向

测试:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.sendRedirect("wudi/four");
}

问题:区别重定向和转发

6.2HttpServletRequest

5.Cookie

1.添加Cookie操作
//        添加Cookie操作,以List形式存储
        Cookie cookie = new Cookie("key", "value");
        resp.addCookie(cookie);
2.查找Cookie操作
//        查找cookie操作
        Cookie[] cookies = req.getCookies();
        for (int i = 0; i < cookies.length; i++) {
            Cookie cookie1 = cookies[i];
            boolean key = cookie1.getName().equals("key");
            String value = cookie1.getValue();
        }
3.设置cookie的寿命
//设置一天
cookie.getMaxAge(24*60*60);
4.删除cookie
//        删除cookie操作
//        设置寿命时间为0
        cookie.setMaxAge(0);
5.编码和解码操作
//        进行utf-8编码操作
        Cookie cookie = new Cookie("work", URLEncoder.encode("牛","utf-8"));
//        进行utf-8解码操作
        URLDecoder.decode(cookie.getValue(),"UTF-8");

6.Sesson

  • 服务器会给每个用户创建一个Session对象
  • 一个Session独占一个服务器,只有服务器没关闭,该Session将一直存在
  • 用户登录之后与用户绑定的整个网站都可以访问
public class session1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.setAttribute("name","value");
        String id = session.getId();
        Cookie cookie = new Cookie("idcookie",id);
        resp.addCookie(cookie);
        if(session.isNew()) {
            resp.getWriter().write("有新id产生:"+id);
        }else {
            resp.getWriter().write("已有id:"+id);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
public class session2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        String name = (String) session.getAttribute("name");
        resp.getWriter().write("获取session1的设置的name:"+name);
        String value = null;
        for (Cookie cookie : req.getCookies()) {
            if(cookie.getName().equals("name")){
                value = cookie.getValue();
            }
        }

        resp.getWriter().write("获取/one中cookie存储的id"+value);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
public class session3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.setMaxInactiveInterval(0);
//        session.invalidate();
    }

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

7.JSP

1.基本概念

1.本质还是servlet

2.较于HTML的动态页面,可以嵌入java代码

2.JSP原理

在服务器内部工作,tomcat中存在work目录。

idea使用tomcat会在idea中的tomcat产生一个work目录

浏览器向服务器发送请求,无论什么资源的访问,就是再servlet中

3.语法

jsp注释

<%--注释--%>

jsp表达式

<%= new java.util.Date()%>

jsp脚本片段

<%
    for (int i = 0; i < 5; i++) {
        out.println(i);
    }
%>

jsp脚本片段再实现(嵌套标签语言)

<%
    for (int i = 0; i < 5; i++) {
%>
<h1>hello</h1><%=i%>
<%}%>xxxxxxxxxx <%    for (int i = 0; i < 5; i++) {%><h1>hello</h1><%=i%><%}%><%!static {    System.out.println("hello,world");};%>

jsp声明

会被编译到jsp生成java的类中,其他会被生成到jspservice方法中

<%!static {
    System.out.println("hello,world");
};%>
<%----%>
<%=%>  ${el}
<%!%>
<%%>
4.指令

可用于嵌套页面

<jsp:include page="/...jsp">
<%@include file="test.jsp"%>
5.九大内置对象
<%
    pageContext.setAttribute("name1","one");
//    数据只会在一个页面中有效
    request.setAttribute("name2","two");
//    数据只在一次请求中有效,请求转发会携带该数据
    session.setAttribute("name3","three");
//    数据只在一次会话中有效,从打开浏览器到关闭浏览器
    application.setAttribute("name4","four");
//    数据只在服务器中有效,从打开服务器到关闭服务器
%>

<h1>${pageContext.findAttribute("name1")}</h1>
<%--one--%>
<h1>${pageContext.findAttribute("name2")}</h1>
<%--two--%>
<h1>${pageContext.findAttribute("name3")}</h1>
<%--three--%>
<h1>${pageContext.findAttribute("name4")}</h1>
<%--four--%>
<h1>${pageContext.findAttribute("name5")}</h1>
<%--不存在--%>
<h1><%=pageContext.findAttribute("name5")%></h1>
<%--null--%>

pageContext从底层到高层(作用域)

page->request->session->application

<h1>${pageContext.findAttribute("name1")}</h1>
<h1>${pageContext.findAttribute("name2")}</h1>
<h1>${pageContext.findAttribute("name3")}</h1>
<h1>${pageContext.findAttribute("name4")}</h1>
<%--four--%>
<h1>${pageContext.findAttribute("name5")}</h1>
<%--不存在--%>
<h1><%=pageContext.findAttribute("name5")%></h1>

request:客户端向服务器发送请求,产生的数据,用户接收即消失。

session:客户端向服务器发送请求,产生的数据,用户接收后还可以继续接收

application:客户端向服务器发送请求产生数据,可多用户使用

6.JSP标签,JSTL标签,EL表达式

1.EL表达式:${ }

2.jstl:为了弥补HTML标签的不足,它自定义了许多标签

未完待续

8.Javabean

实体类

javabean有特定的写法:

  • 必须要有一个无参构造
  • 属性必须私有化
  • 必须有对应的get/set方法

一般用来和数据库的字段做映射ORM:对象关系映射

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

9.MVC三层架构

Model view Controller

模型 视图 控制器

1.过时操作

image-20211124163528889

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

程序臃肿,不利于维护

2.经典操作,三层架构

image-20211125012312871

Model

  • 业务处理:业务逻辑(Service)
  • 数据持久层:CRUD(DAO):增删改查

View

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

Controller

  • 接收用户的请求:req:请求参数,session信息

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

  • 控制视图的跳转

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

10.Filter过滤器

1.概念

用来处理过滤网站的数据

  • 处理中文乱码
  • 登录验证

image-20211125013645751

public class CharactorEncodingFilter implements Filter {
//    初始化
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharactorEncodingFilter初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=UTF-8");
        System.out.println("过滤器执行前....");
//        处理链
//        总结:过滤器中所有代码,在过滤特定请求时都会执行
//        必须要让过滤器继续同行,即往下转交
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("过滤器执行后....");

    }

    @Override
    public void destroy() {
        System.out.println("filter已经销毁");
    }
}

同行处理

    <servlet>
        <servlet-name>one</servlet-name>
        <servlet-class>com.servlet.ShowServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>one</servlet-name>
        <url-pattern>/servlet/one</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>oneinit</servlet-name>
        <servlet-class>com.servlet.ShowServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>oneinit</servlet-name>
        <url-pattern>/one</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>filter1</filter-name>
        <filter-class>com.filter.CharactorEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filter1</filter-name>
        <servlet-name>one</servlet-name>
<!--        只要经过/servlet的任何请求都会触发过滤器-->
        <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>
2.实现步骤
  1. 导入jar包
  2. 实现Filter接口
  3. 在web.xml中配置Filter过滤器

11.监听器

1.概念

实现一个监听器的接口(有多种接口)

image-20211125021747341

2.实现在线人数
public class onlineCountListener implements HttpSessionListener {
//    一旦创建session就会触发一次这个创建事件
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext context = se.getSession().getServletContext();
        System.out.println(se.getSession().getId());
        Integer onlineCount = (Integer) context.getAttribute("OnlineCount");
        if(onlineCount == null){
            onlineCount = new Integer(1);
        }else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count + 1);
        }
        context.setAttribute("OnlineCount",onlineCount);
    }
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext context = se.getSession().getServletContext();
        System.out.println(se.getSession().getId());
        Integer onlineCount = (Integer) context.getAttribute("OnlineCount");
        if(onlineCount == null){
            onlineCount = new Integer(0);
        }else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count - 1);
        }
        context.setAttribute("OnlineCount",onlineCount);
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>当前正在访问此页面的人数有<%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%></h1>
<%--<%System.out.println((Integer) request.getServletContext().getAttribute("JSESSIONID"));%>--%>
</body>
</html>

思考为什么一次访问会显示2个在线用户?

image-20211125031206937

解释:tomcat启动项目时,构造出了多个ip向本机服务器发起tcp请求,会导致产生多个会话,为实现功能需要重新部署

3.实现步骤
  1. 实现监听器的接口
  2. web.xml注册监听器
  3. 看情况是否使用
4.监听器和过滤器的实用例子:

1.GUI

2.实现登录状况可以进第二页面,非登录不可以直接跳转第二页面,在第二页面设置一个注销按钮,回到登陆页面

12.JDBC

1.固定(DB)步骤
  1. 加载驱动

  2. 连接数据库

  3. 向数据库发送SQL对象PrepareStatement:CRUD

    PrepareStatement预编译

  4. 编写SQL,根据业务,不同的SQL

  5. 执行SQL

  6. 关闭连接

对数据库的增删改查Updata操作略

2.事务

要么都成功,要么都失败

ACID原则,保证数据的安全

开启事务
事务提交 commit()
事务回滚 rollback()
关闭事务
public class connectFactory {
    private Connection conn;
    public static void getConn(){
        String url = "jdbc://mysql://localhost:3306/meeting?useUnicode=true&character";
        String username = "root";
        String password = "123456";
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(url, username, password);
            //            1.通知数据库开启事务
            connection.setAutoCommit(false);//false 开启事务/关闭自动提交事件
            String sql1 = "update事件1";
            connection.prepareStatement(sql1).executeUpdate();
//            2.创建错误
            int i = 1/0;//报错
            String sql2 = "update与事件1对立的事件2";
            connection.prepareStatement(sql2).executeUpdate();
//            3.提交事件
            connection.commit();//若两个sql语句执行成功,则提交;
            System.out.println("success");
            try {
//                若报错则回滚
                connection.rollback();//回滚
            } catch (SQLException e) {
                e.printStackTrace();
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

//
    }

}

13.简单的业务项目

image-20211127131328435

  1. Dao包,数据库管理
  2. pojo包,实体类封装,需要连接什么数据就封装什么数据
  3. Filter包,过滤数据
  4. Servlet包,交互数据,请求前端的数据,递交于service
  5. Service包,业务管理(中间商),将servlet获取的数据递交于Dao,进行数据库操作
posted @ 2021-12-21 19:21  Jmin-Channel  阅读(132)  评论(0)    收藏  举报