JavaWeb
1.基础概念
1.1前言
web开发:
-
web,网页
-
静态web
- html,css
- 不会发生改变的网页
-
动态web
- 可以动态改变的网页
- 技术栈:Servlet/JSP,ASP,PHP
使用Java进行的动态web资源开发的技术统称为JavaWeb
1.2Web应用程序
Web应用程序:可以提供浏览器访问的程序
- a.html b.html…多个web资源,web资源可以被外界访问,对外界提供服务
- 用户能访问到的任何一个页面或者资源,都存在这个世界某一台计算机上
- URL
- 这个统一的web资源都会被放在同一个文件夹下,web应用程序 —>Tomcat:服务器
- 一个web应用由多个部分组成(静态web,动态web)
- html,css,js
- jsp,servlet
- java程序
- jar包
- 配置文件(Properties)
1.3静态Web
- 静态web存在的缺点
- web页面无法动态更新,所有用户看到都是同一个页面
- 轮播图,点击特效:伪动态
- JavaScript(应用较多)
- VBScript
- 无法和数据库交互(数据无法持久化,用户无法交互)
- web页面无法动态更新,所有用户看到都是同一个页面
1.4动态web
页面会动态展示:“Web页面会因人而异”
缺点:
* 假如服务器的动态web资源出现了错误,我们需要重新编写我们的后台程序,重新发布
优点:
- Web页面可以动态更新,所有用户看到的不是同一个页面
- 可以进行数据交互(数据持久化:注册,商品信息,用户信息)
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ic3qNc8e-1619330279630)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201010143535875.png)]
2.Web服务器
2.1技术讲解
ASP:
- 微软:国内最早流行
- 在HTML中嵌入VB的脚本, ASP+COM
PHP:
- PHP开发速度很快,功能强大,跨平台,代码简单
- 无法承载大访问量(局限性)
JSP/Servlet:
B/S:浏览器和服务器
C/S:客户端和服务器
-
Sun公司主推的B/S架构
-
基于Java语言
-
可以承载三高问题(高并发,高可用,高性能)
-
语法像ASP,ASP–>JSP,加强市场强度
2.2Web服务器
服务器是一种被动的操作,用来处理用户的请求及响应
IIS:
微软:ASP,Windows自带
Tomcat:Java的
3.Tomcat
3.1配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CsDnAQWq-1619330279632)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201010140612415.png)]
server.xml文件可以配置启动的端口号
- tomcat的默认端口号为:8080
- mysql:3306
- http:80
- https:443
可以配置主机的名称
- 默认的主机名为:localhost->127.0.0.1
- 默认网站应用存放的位置为:webapps
面试题
请你谈谈网站是如何访问的
-
输入一个域名; 回车
-
检查本机的C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名映射
-
有:直接返回对应的IP地址,这个地址中有我们需要访问的web程序,可以直接访问
例如: 127.0.0.1 ----------------- localhost
-
没有: 去DNS服务器找(管理全世界域名与ip地址映射),找到的话就会返回
-
3.4发布一个web网站
- 将自己写的网站,放到服务器(Tomcat)中指定的web应用文件夹(webapps)下,就可以访问
网站的结构
– webapps: Tomcat服务器的web目录
– Root
– kuangshenstudy:网站目录名
– web-INF
--classes:java程序
--lib:web应用所依赖的jar包
– web.xml:网站配置文件
– index.html 默认的首页
4Http
4.1什么是HTTP
HTTP(超文本传输协议)是一个简单的请求-响应协议,通常运行在TCP之上
- 文本:html,字符串…
- 超文本:图片,音乐,视频,定位,地图…
- 端口:80
Https:安全的
- 端口:443
4.2两个时代
- http1.0
- HTTP/1.0:客户端可以与web服务器连接后,只能获得一个web资源,断开连接
- http2.0
- HTTP/1.1:客户端可以与web服务器连接后,可以获得多个web资源
4.3Http请求
- 客户端—发请求(Request)—服务器
Request URL:https://www.baidu.com/ 请求地址
Request Method:GEt get方法/post方法
Status Code:200 OK 状态码
Remote Address:14.215.177.39:443
Accept:text/html
Accept-Encoding:gzip,deflate,br
Accept-Language:zh-CN,zh;q=0.9 语言
Cache-Control:max-age=0
Connection:keep-alive
1.请求行
- 请求行中的请求方式:GET
- 请求方式:GET/Post,HEAD,DELETE,PUT
- get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全但是高效
- post:请求能够携带的参数没有限制,大小没有限制,不回在浏览器的URL地址栏显示数据内容,安全但不高效
2.消息头
Accept: 支持的数据类型
Accept-Encoding: 支持的编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language:语言环境
Cache-Control: 缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
Host: 主机..../.
4.4Http响应
-
服务器—响应—客户端
Cache-Control:private 缓存控制 Connection:Keep-Alive 连接 Content-Encoding:gzip 编码类型 Content-Type:text/html 类型
1.响应体
Accept: 支持的数据类型
Accept-Encoding: 支持的编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language:语言环境
Cache-Control: 缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
Host: 主机..../.
Refrush:定时刷新
Location:让网页重新定位
2.响应状态码
200:请求响应成功
3**:请求重定向
- 重定向:请求新的页面
404:找不到资源
- 资源不存在
5xx:服务器代码错误 500 502:网关错误
常见面试题:
当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么?
5.Maven
1.在JavaWeb开发中需要使用大量的jar包,这些jar包需要手动导入
2.自动导入和配置jar包
5.1Maven项目架构管理工具
方便导入jar包
Maven的核心思想:约定大于配置
- 有约束不要去违反
Maven会规定好你该如何去编写java代码,必须按照规范来
5.2下载按照Maven
官网:https://maven.apache.org/
下载完成解压即可
电脑上的所有环境都放在一个文件夹下
5.3配置环境变量
在系统环境变量中
配置如下配置:
- M2_HOME maven目录下的bin目录
- MAVEN_HOME maven的目录
- 在系统的path中配置MAVEN_HOME
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ARnBnjgP-1619330279635)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201010160824722.png)]
测试Maven是否安装成功
5.4阿里云镜像
-
镜像:mirros
-
作用:加速下载
-
国内建议使用阿里云镜像
<mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror>
5.5本地仓库
在本地的仓库,远程仓库
建立一个本地仓库:localRepository
在config\setting.xml中配置localRepository,url指向的路径就是maven管理jar包的仓库
<localRepository>D:\javaworktools\apache-maven-3.6.3\maven-repo</localRepository>
5.6在IDEA中使用Maven
1.创建一个Maven项目
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-307tjRr0-1619330279636)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201011133603065.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yA5DozD2-1619330279637)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201011134224664.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-moCZWsm1-1619330279638)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201011134608038.png)]
2.项目创建完毕后,idea会自动根据setting.xml文件中的路径去下载文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mqtl89w6-1619330279639)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201011135002201.png)]
3.观察maven仓库中多了什么东西
4.IDEA中的Maven设置
IDEA创建成功后需要去setting中检查Maven配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3oGOViSK-1619330279639)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201011135631947.png)]
5.5标记文件夹功能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YZGHRTLt-1619330279640)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201011141005314.png)]
5.6在IDEA中配置Tomcat
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7voXEehP-1619330279640)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201011141823937.png)]
解决警告问题
必要的配置问题缘由:访问网站时需要指定一个文件夹名称
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DFv9nWx4-1619330279641)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201011142123733.png)]
5.7Pom文件
pom.xml时Maven的核心配置文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wsJS3Meb-1619330279641)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201011142841495.png)]
<?xml version="1.0" encoding="UTF-8"?>
<!--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.0</modelVersion>
<!--这里是配置的GAV-->
<groupId>com.kuang</groupId>
<artifactId>javaweb-01-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<!--
Package:项目的打包方式
jar:java应用
war:javaweb应用
-->
<name>javaweb-01-maven 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>
<!--具体依赖的jar包-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<!--项目构建使用插件-->
<build>
<finalName>javaweb-01-maven</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>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rHyJ2PtO-1619330279642)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201011145621707.png)]
maven由于他的约定大于配置,之后可能会遇到写的配置文件,无法被导出或者生效的问题,解决方案
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
在java文件中存在有非class文件时,导出项目会存在这个问题,需要在pom中配置resource解决
5.8IDEA操作
生成项目目录树
maven中jar包的体系关联图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kHpiuvYE-1619330279643)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201011150415483.png)]
5.9使用Maven直接创建项目时可能会遇到发行版本不支持
这是因为maven框架会覆盖idea的jdk版本
在maven的pom.xml中配置如下
<properties>
<!-- 项目编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 本地编译JDK版本 -->
<maven.compiler.source>14</maven.compiler.source>
<!-- 项目部署JDK版本 -->
<maven.compiler.target>14</maven.compiler.target>
</properties>
锁定jdk版本
6.Servlet
6.1Servlet简介
- Servlet就是sun公司开发动态web的一门技术
- Sun在这些API中提供一个接口叫做:Servelt,如果你想开发一个Servlet程序,只需要完成两个小步骤
- 编写一个类实现Servlet接口
- 把开发好的java类部署到web服务器中
把实现了Servlet接口的java程序叫做Servlet
6.2HelloServlet
Servlet接口在Sun公司有两个默认的实现类:HttpServlet,GenericServlet
-
构建一个Maven项目,删掉里面的src目录,以后的学习就在这个项目里面创建Moudel
这个空的工程就是Maven主工程
-
关于Maven父子工程的理解:
父项目中会有
<modules> <module>servlet-01</module> </modules>
子项目中会有
<parent> <artifactId>javaweb-02-servlet</artifactId> <groupId>org.kuang</groupId> <version>1.0-SNAPSHOT</version> </parent>
父项目中的jar包子项目可以直接使用,反之不行
son extends father
-
Maven环境优化
- 修改web.xml为最新
- 将maven的结构搭建完整
-
编写servlet程序
- 编写一个普通类
- 继承HttpServlet类
package com.sy.servlet; 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.IOException; import java.io.PrintWriter; public class HelloServlet extends HttpServlet { //由于get或者post只是请求实现的不同方式,可以相互调用,业务逻辑都一样 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //ServletOutputStream outputStream = resp.getOutputStream(); PrintWriter writer = resp.getWriter(); //响应流 writer.print("Hello,Servlet"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
-
编写Servlet的映射
为什么需要映射:我们写的是Java程序,但是需要通过浏览器访问,而浏览器需要连接web服务器,所以需要在web服务器中注册我们写的servlet,还需要给他一个浏览器能够访问的路径
<!--注册Servlet--> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.sy.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
-
配置Tomcat
注意:配置项目发布的路径
-
6.3Servlet原理
Servlet是由Web服务器,web服务器在收到浏览器请求之后,会
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UzF0CNlg-1619330279643)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201011213212267.png)]
6.4Mapping问题
-
一个Servlet可以指定一个映射路径
<servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
-
一个Servlet可以指定多个映射路径
<servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello2</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello3</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello4</url-pattern> </servlet-mapping>
-
一个Servlet可以指定通用映射路径
<servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello/*</url-pattern> </servlet-mapping>
-
指定一些后缀或者前缀等等
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>*.sy</url-pattern>
</servlet-mapping>
-
优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求
<servlet>
<servlet-name>ErrorSerlet</servlet-name>
<servlet-class>com.sy.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ErrorServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
6.5ServletContext
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表当前的web应用
1.共享数据
-
我在这个Servlet中保存的数据,可以在另外一个Servlet中使用
-
@WebServlet(name = "HelloServlet",urlPatterns = "/hello") public class HelloServlet 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="qingjiang"; //数据 context.setAttribute("username",username); //将一个数据保存在了ServletContext中 System.out.println("hello"); } }
-
读取:
@WebServlet(name = "GetServlet",urlPatterns = "/get") 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"); System.out.println(username); } }
测试访问结果
2.请求转发
3.读取资源文件
Properties
- 在java目录下新建properties
- 在resource目录下新建properties
发现:都被打包到了同一个路径下:classes,我们俗称为classpath(类路径)
思路:需要一个文件流
username=qingjiang
password=123456
public class PropertiesServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("target\\servlet-02\\WEB-INF\\classes\\db.properties");
Properties prop = new Properties();
prop.load(is);
String username = prop.getProperty("username");
System.out.println(username);
}
}
6.6HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息都会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息
1. 获取前端信息
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] parameterValues = req.getParameterValues("habit");
//打印
System.out.println(username+":"+password);
System.out.println(Arrays.toString(parameterValues));
//重定向
resp.sendRedirect("success.jsp");
}
6.7HttpServletResponse
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest
对象,代表响应的一个HttpServletResponse
- 如果要获取客户端请求过来的参数:找HttpServletRequest
- 如果要给客户端响应一些信息:找HttpServletResponse
1.简单分类
负责向浏览器发送数据的方法
public ServletOutputStream getOutputStream() throws IOException;
public PrintWriter getWriter() throws IOException;
负责向浏览器发送响应头的方法
public void setCharacterEncoding(String charset);
public void setContentLengthLong(long len);
public void setContentType(String type);
public void setDateHeader(String name, long date);
public void addDateHeader(String name, long date);
public void setHeader(String name, String value);
public void setIntHeader(String name, int value);
public void addIntHeader(String name, int value);
2.常见应用(下载文件)
1. 向浏览器输出消息
2.下载文件
-
要获取下载文件的路径
-
下载的文件名
-
设置浏览器能支持下载的东西
-
获取下载文件的输入流
-
获取OutputStream对象
-
将FileOutputStream流写入到buffer缓冲区
-
使用OutputStream将缓冲区的数据输出到客户端
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 要获取下载文件的路径 String realPath = "D:\\IDEA\\javaweb-02-servlet\\response\\src\\main\\resources\\1.jpg"; System.out.println("下载文件的路径"+realPath); //2. 下载的文件名 String fileName = realPath.substring(realPath.lastIndexOf("\\")+1); //3. 设置浏览器能支持下载的东西(使用URLEncoding.encode来解决文件编码问题) resp.setHeader("Content-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缓冲区 while((len=in.read(buffer))>0){ //8. 使用OutputStream将缓冲区的数据输出到客户端 out.write(buffer,0,len); } out.close(); in.close(); }
3.验证码功能
验证码
-
前端实现
-
后端实现,需要用到Java图片类,生成图片
-
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //如何让浏览器5秒自动刷新一次 response.setHeader("refresh","3"); //在内存中创建一个图片 BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB); //得到图片(笔) Graphics2D graphics = (Graphics2D) image.getGraphics(); //设置图片的背景颜色 graphics.setColor(Color.white); graphics.fillRect(0,0,80,20); //给图片写数据 graphics.setColor(Color.blue); graphics.setFont(new Font(null,Font.BOLD,20)); graphics.drawString(makeNum(),0,20); //告诉浏览器这个请求用图片的方式打开 response.setContentType("image/jpg"); //网站存在缓存,不让网站缓存(不设置的话多次刷新占用内存) response.setDateHeader("expires",-1); response.setHeader("Cache-Control","no-cache"); response.setHeader("Pragma","no-cache"); //把图片写给浏览器 boolean write = ImageIO.write(image,"jpg",response.getOutputStream()); } private String makeNum(){ Random random = new Random(); String num = random.nextInt(8888)+""; StringBuffer sb = new StringBuffer(); for (int i = 0;i<4-num.length();i++){ sb.append("0"); } num = sb.toString()+num; return num; }
4.实现重定向
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9xUzII0r-1619330279644)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201014152416653.png)]
一个web资源收到客户端请求后,B会通知客户端A去访问另外一个web资源C,这个过程叫重定向
常见常见:
- 用户登录
public void sendRedirect(String location) throws IOException;
测试:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
response.setHeader("Location","/r/image");
response.setStatus(302);
*/
//重定向
response.sendRedirect("image");
}
面试题:请你聊聊重定向和转发的区别?
相同点
- 页面都会实现跳转
不同点
- 请求转发的时候,url不会发生变化 307
- 重定向时候,url地址栏会发生变化 302
6.x常见问题
启动Tomcat时需要选择打包的项目,每次保证只有一个项目被打包.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vl0qvauH-1619330279645)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201013095553910.png)]
7.Cookie,Session
7.1会话
会话:用户打开浏览器,并点击连接,访问web资源,关闭浏览器,这个过程称为会话
**有状态会话:**一个同学来过教室,下次再来教室,我们会知道这个同学曾经来过,称之为有状态会话
- 服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了. cookie
- 服务器登记你来过了,下次我来匹配你;
7.2保存会话的两种技术
cookie
- 客户端技术(响应,请求)
session
- 服务器技术,利用这个技术,可以保存用户的会话信息,我们可以把信息或者数据放在session中
常见常见:网站登录后,第二次直接登录
7.3保存会话的两只技术
- 从请求中获得cookie信息
- 服务器响应给客户端cookie
Cookie[] cookies = request.getCookies();//获得Cookie
cookie.getName(); //获得cookie中的key
cookie.getValue();//获得cookie中的值
cookie.setMaxAge(3*3600);//设置cookie存活时间
response.addCookie(cookie);//响应给客户端cookie
cookie:一般会保存在本地的用户目录下appdata
一个网站cookie是否存在上限
- 一个Cookie只能保存一个信息
- 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie
- Cookie大小限制为4kb
- 浏览器Cookie上限为300个
删除Cookie:
- 不设置有效期,关闭浏览器,自动失效
- 设置有效期时间为0;
7.4编码和解码
//解码
URLDecoder.decode(cookie.getValue(),"utf-8");
//编码
URLEncoder.encode("沈洋","utf-8");
7.5Session(重点)
什么是Session:
- 服务器会给每一个用户(浏览器)创建一个Session对象
- 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
- 用户登录后,整个网站都可以访问 -->保存用户信息
- 可以通过在web.xml中配置Session-config指定session自动失效的时间
<!--设置Session默认的失效时间-->
<session-config>
<!--15分钟后Session自动失效, 以分钟为单位-->
<session-timeout>15</session-timeout>
</session-config>
Session和Cookie的区别
- Cookie是把用户的数据写给用户的浏览器,浏览器保存
- Session把用户的数据写到用户独占的Session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
- Session对象是由服务器创建
使用场景:
- 保存一个登录用户的信息
- 购物车信息
- 在整个网站中经常会使用的数据,我们将它保存在Session中
使用Session:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置请求格式,设置响应编码格式
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//获得Session
HttpSession session = request.getSession();
//在Session中存东西
session.setAttribute("name","shenyang");
//获取Session的id
String id = session.getId();
//判断Session是不是新创建的
System.out.println(session.isNew());
//Session创建的时候做了什么(相当于在cookie中存放了session的id)
Cookie cookie = new Cookie("JSESSIONID",session.getId());
response.addCookie(cookie);
}
会话自动过期:web.xml配置
<!--设置Session默认的失效时间-->
<session-config>
<!--15分钟后Session自动失效, 以分钟为单位-->
<session-timeout>15</session-timeout>
</session-config>
8.JSP
8.1什么是JSP
Java Server Pages: java服务器端页面,也和Servlet一样,用于动态Web技术
最大的特点:
- 写JSP相当于写HTML
- 区别:
- HTML只给用户提供静态数据
- JSP页面中可以嵌套JAVA代码,为用户提供动态数据
8.2JSP原理
思路:JSP到底怎么执行的
-
代码层面
-
服务器内部工作
实际会在idea的work目录下将jsp文件转化成java程序
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet
JSP最终被转化成为一个java类
JSP本质上就是一个Servlet
//初始化
public void _jspInit(){
}
//销毁
public void _jspDestroy(){
}
//JSPService
public void _jspService(HttpServletRequst request,HttpServletResponse response)
- 判断请求
- 内置一些对象(九大内置对象)
final javax.servlet.jsp.PageContext pageContext;//页面上下文
javax.servlet.http.HttpSession session = null; //session
final javax.servlet.ServletContext application; //applicationContext
final javax.servlet.ServletContext config; //config
javax.servlet.jsp.JspWriter out = null; //out
final java.lang.Object page = this; //page 当前
HttpServletRequest request //请求
HttpServletResponse response //响应
- 输出页面前增加的代码
response.setContentType("text/html"); //设置响应的页面类型
pageContext = _jspxFactory.getPageContext(this,request,response,null,true,8192,true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jVDJ1h6R-1619330279645)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201017133730586.png)]
在JSP页面中:
只要是JAVA代码就会原封不动的输出
如果是HTML代码,就会被转换为
out.write("<html>\r\n");
8.3JSP基础语法
任何语言都有自己的语法,JAVA中有,JSP作为java技术的一种应用,它拥有一些自己扩充的语法
JSP表达式
<%--JSP表达式
作用:用来将程序的输出,输出到客户端--%>
<%= new java.util.Date()%>
<hr>
JSP脚本片段
<%--jsp脚本片段--%>
<%
int sum = 0;
for (int i = 1; i <=100 ; i++) {
sum += i;
}
%>
JSP声明(全局代码块) ----<%! %>
会被编译到JSP生成的java类中,其他的都会被生成到_jspService方法中
<%! public void fun(){
}%>
EL表达式(类是于JSP表达式)
${"sh".getBytes()}
JSP的注释,不会传递到客户端,HTML会
8.4JSP指令
- 在web.xml中配置所有错误页面
<error-page>
<error-code>500</error-code>
<location>/errror/500.jsp</location>
</error-page>
- 在jsp中配置单个的错误界面跳转路径
<%@page errorPage="errror/500.jsp" %>
- 页面合成(尽量使用JSP标签)
<body>
<%--会将两个页面合二为一--%>
<%@include file="common/header.jsp"%>
<h2>网页主体</h2>
<%@ include file="common/footer.jsp"%>
<hr>
<%--JSP标签
jsp:include:拼接页面,本质还是三个页面
--%>
<jsp:include page="/common/header.jsp"/>
<h2>网页主体</h2>
<jsp:include page="/common/footer.jsp"/>
</body>
8.5九大内置对象
- PageContext
- 存东西
- Request
- 存东西
- Response
- Session
- 存东西
- Application [ServletContext]
- 存东西
- config [ServletConfig]
- out
- page
- exception
**四个具有作用域的对象 **
各自拥有不同权限
pageContext:1
request:2
session:3
application:4(Context)
取数据时从底层到高层(作用域): pageContext—>request—>session—>application
<%
//保存的数据只在一个页面中有效
pageContext.setAttribute("name1","sy1");
//保存的数据只在一次请求中有效,请求转发会携带
request.setAttribute("name2","sy2");
//保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
session.setAttribute("name3","sy3");
//保存的数据只在服务器中有效,从打开服务器到关闭服务器
application.setAttribute("name4","sy4");
%>
request: 客户端向服务器发送请求,产生的数据,用户看完就不需要了,比如:新闻
session:客户端向服务器发送请求,产生的数据,用户用完还会使用,比如:登录用户数据
application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用
8.6JSP标签,JSTL标签,EL表达式
EL表达式: ${}
- 获取数据
- 执行运算
- 获取web开发的常用对象
JSP标签
<jsp:include page="/index.jsp"></jsp:include>
<jsp:forward page="index.jsp">
<jsp:param name="name" value="shenyang"/>
<jsp:param name="age" value="12"/>
</jsp:forward>
JSTL表达式(现在用得很少)
JSTL标签库的使用就是为了弥补HTML标签的不足;它自定义了许多标签,可以供我们使用,相当于java代码
核心标签(掌握部分)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cudbg6T6-1619330279646)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201017210309085.png)]
JSTL标签使用步骤
- 引入对应的taglib
- 使用其中的方法
- 在Tomcat也需要引入JSTL的包,否则会报错:JSTL解析错误
<body>
<h4>if测试</h4>
<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:out>
</c:if>
</body>
格式化标签
SQL标签
XML标签
9.JavaBean
实体类
一般放在java文件夹下的pojo包(或者entity)
JavaBean有特定的方法
- 必须要有一个无参构造
- 属性必须私有化
- 必须有对应的get/set方法
一般用来和数据库的字段做映射 ORM
ORM:对象关系映射
- 表—>类
- 字段—>属性
- 行记录—>对象
people表
id | name | age | address |
---|---|---|---|
1 | sy1 | 39 | 成都 |
2 | sy2 | 45 | 西安 |
3 | sy3 | 100 | 北京 |
对应的Java类
class People{
private int id;
private String name;
private int age;
private String address;
}
10.MVC三层架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g5OpPAeC-1619330279647)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201018102859182.png)]
Model
- 业务处理:业务逻辑(Service)
- 数据持久层:CRUD(Dao)
View
- 展示数据
- 提供链接发起Servlet请求(a,form,img)
Controller
- 接收用户请求(req:请求参数,session信息)
- 交给业务层处理对应的代码
- 控制视图的跳转
登录--->接收用户的登录请求--->处理用户的请求(获取用户登录的参数,username,password)--->交给业务层处理登录业务(判断用户密码是否正确:事务)--->Dao层查询用户名和密码是否正确--->数据库
11.Filter
Filter:过滤器,用来过滤网站的数据
- 处理中文乱码
- 登录验证…
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bD0j6YMY-1619330279647)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201018104250842.png)]
Filter开发步骤:
-
导包
-
编写过滤器
-
导包不要错
-
实现Filter接口.重写方法
package com.sy.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter(filterName = "CharacterEncodingFilter",urlPatterns ="/show" ) public class CharacterEncodingFilter implements Filter { //初始化 @Override public void init(FilterConfig filterConfig) throws ServletException { } //chain:链 /* *1.过滤所有代码,再过滤特定请求的时候都会被执行 *2.必须让过滤器继续放行 */ @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("utf-8"); servletResponse.setContentType("text/html;charset=utf-8"); System.out.println("CharacterEncodingFilter执行前"); filterChain.doFilter(servletRequest,servletResponse); System.out.println("CharacterEncodingFilter执行后"); } @Override public void destroy() { System.out.println("CharacterEncodingFilter销毁"); } }
-
在web.xml中配置Filter(可以使用注释)
-
12.监听器
实现一个监听器的接口;
- 编写监听器
- 实现监听器的接口
- 配置监听器
13.过滤器,监听器常见应用
监听器:**GUI(图像界面编程)**编程中经常使用
package com.sy.listener;
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("国庆节快乐");
//面板
Panel panel = new Panel(null);
//设置窗体布局
frame.setLayout(null);
frame.setBounds(300,300,500,500);
//设置背景颜色
frame.setBackground(new Color(0,0,255));
panel.setBounds(50,50,300,300);
panel.setBackground(new Color(0,255,0));
frame.add(panel);
frame.setVisible(true);
//监听事件,监听关闭事件
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
System.out.println("打开");
}
@Override
public void windowClosing(WindowEvent e) {
System.out.println("关闭");
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println("已关闭");
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
System.out.println("激活");
}
@Override
public void windowDeactivated(WindowEvent e) {
System.out.println("未激活");
}
});
}
}
用户登录之后才能进入主页!用户注销之后不能进入主页
-
用户登录之后,向Session中放入用户的数据
-
进入主页的时候要判断是否已经登录(在过滤器中实现)
package com.sy.listener; import com.sy.util.Constanst; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter(filterName = "SysFilter",urlPatterns = "/sys/*") public class SysFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) servletRequest; HttpServletResponse resp = (HttpServletResponse) servletResponse; if(req.getSession().getAttribute(Constanst.getUserSession())==null){ resp.sendRedirect("/test_war_exploded/login.jsp"); } filterChain.doFilter(servletRequest,servletResponse); } @Override public void destroy() { } }
14.JDBC
JDBC:Java连接数据库
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3jm19RQ5-1619330279648)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201019094335295.png)]
实验环境搭建
1.SQL语句
CREATE TABLE users(
id INT PRIMARY KEY,
`name` VARCHAR(40),
`password` VARCHAR(40),
email VARCHAR(60),
birthday DATE
)
INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES(1,'张三','123456','zs@qq.com','2000-01-01'),
(2,'李四','98765','ls@qq.com','2000-02-02'),
(3,'王五','123','ww@qq.com','2000-02-02'),
(4,'赵六','qifei','zl@qq.com','2000-02-02')
2.新建数据库依赖
在pom.xml中导入数据库的依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
3.IDEA中连接数据库
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N7bb5bBN-1619330279649)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201019110345799.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wIigF2yu-1619330279650)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201019110508818.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7d0r8mso-1619330279650)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201019110610617.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1koBWCvw-1619330279651)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201019110657157.png)]
JDBC操作
- 加载驱动
- 连接数据库,代表数据库
- 向数据库发送SQL的对象Statement:CRUD
- 编写SQL(根据业务,不同的SQL)
- 执行SQL
- 关闭连接
url:
public static String sqlUrl = "jdbc:mysql://localhost:3306/" +
"company?useUnicode=true&characterEncoding=" +
"utf8&serverTimezone=GMT%2B8&useSSL=false";
实例1
//配置信息
//解决中文乱码和时区问题
String sqlUrl = "jdbc:mysql://localhost:3306/" +
"jdbc?useUnicode=true&characterEncoding=" +
"utf8&serverTimezone=GMT%2B8&useSSL=false";
String sqlUser = "root";
String sqlPwd = "123123";
//1.加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.连接数据库,代表数据库
Connection connection = DriverManager.getConnection(sqlUrl,sqlUser,sqlPwd);
//3.向数据库发送SQL对象
Statement statement = connection.createStatement();
//4.编写sql
String sql = "select *from users";
//5.执行查询sql,返回一个ResultSet : 结果集
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()){
System.out.println("id="+resultSet.getInt("id"));
System.out.println("name="+resultSet.getString("name"));
System.out.println("password="+resultSet.getString("password"));
System.out.println("email="+resultSet.getString("email"));
System.out.println("birthday="+resultSet.getString("birthday"));
}
//6.关闭连接,释放资源,先开后关
resultSet.close();
statement.close();
connection.close();
实例2(预编译SQL)
package com.sy.test;
import java.sql.*;
public class TestJdbc2 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置信息
//解决中文乱码和时区问题
String sqlUrl = "jdbc:mysql://localhost:3306/" +
"jdbc?useUnicode=true&characterEncoding=" +
"utf8&serverTimezone=GMT%2B8&useSSL=false";
String sqlUser = "root";
String sqlPwd = "123123";
//1.加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.连接数据库,代表数据库
Connection connection = DriverManager.getConnection(sqlUrl,sqlUser,sqlPwd);
//3.编写sql
String sql = "insert into users(id,name,password,email,birthday) values(?,?,?,?,?)";
//4.预编译
PreparedStatement ps = connection.prepareStatement(sql);
ps.setInt(1,10);
ps.setString(2,"吴心瑞");
ps.setString(3,"123456789");
ps.setString(4,"wxr@qq.com");
ps.setDate(5,new Date(new java.util.Date().getTime()));
ps.executeUpdate();
//6.关闭连接,释放资源,先开后关
ps.close();
connection.close();
}
}
事务
要么都成功,要么都失败
ACID原则:保证数据的安全
开启事务
事务提交 commit()
事务回滚 rollback()
关闭事务
@Test
public void test(){
String sqlUrl = "jdbc:mysql://localhost:3306/" +
"jdbc?useUnicode=true&characterEncoding=" +
"utf8&serverTimezone=GMT%2B8&useSSL=false";
String sqlUser = "root";
String sqlPwd = "123123";
Connection connection = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection(sqlUrl,sqlUser,sqlPwd);
//3.通知数据库开启事务(false为开启)
connection.setAutoCommit(false);
String sq1 = "update account set money = money-100 where name='A'";
connection.prepareStatement(sq1).executeUpdate();
//制造错误
//int i = 1/0;
String sq2 = "update account set money = money+100 where name='B'";
connection.prepareStatement(sq2).executeUpdate();
connection.commit();
} catch (Exception e) {
try {
connection.rollback();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}finally {
try {
//如果出现异常,通知事务回滚
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
15.文件上传和下载
下载文件
1. 向浏览器输出消息
2.下载文件
-
要获取下载文件的路径
-
下载的文件名
-
设置浏览器能支持下载的东西
-
获取下载文件的输入流
-
获取OutputStream对象
-
将FileOutputStream流写入到buffer缓冲区
-
使用OutputStream将缓冲区的数据输出到客户端
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 要获取下载文件的路径 String realPath = "D:\\IDEA\\javaweb-02-servlet\\response\\src\\main\\resources\\1.jpg"; System.out.println("下载文件的路径"+realPath); //2. 下载的文件名 String fileName = realPath.substring(realPath.lastIndexOf("\\")+1); //3. 设置浏览器能支持下载的东西(使用URLEncoding.encode来解决文件编码问题) resp.setHeader("Content-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缓冲区 while((len=in.read(buffer))>0){ //8. 使用OutputStream将缓冲区的数据输出到客户端 out.write(buffer,0,len); } out.close(); in.close(); }
上传文件
1.上传文件的前端代码
当表单中需要上传文件时需要在form中添加属性enctype=“multipart/form-data”
<%--通过表单上传文件--%>
<form method="post" action="" enctype="multipart/form-data">
<p>
<input type="file" name="file1">
</p>
<p>
<input type="file" name="file2">
</p>
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
-
上传文件Servlet代码
package com.sy.servlet; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.ProgressListener; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.util.List; import java.util.UUID; @WebServlet(name = "FileServlet02",urlPatterns = "/upload2.do") public class FileServlet02 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //判断上传文件是普通表单还是带文件的表单 if(!ServletFileUpload.isMultipartContent(req)){ return; } //创建上传文件的保存路径,建议在web-inf路径下,用户无法直接访问上传的文件 String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload"); File uploadFile = new File(uploadPath); if(!uploadFile.exists()){ uploadFile.mkdir(); } String tempPath = this.getServletContext().getRealPath("/WEB-INF/upload"); File tempFile = new File(tempPath); if(!tempFile.exists()){ tempFile.mkdir(); } try { // DiskFileItemFactory factory = getDiskFileItemFactory(tempFile); // ServletFileUpload upload = getServletFileUpload(factory); //处理文件 String msg = uploadParseRequest(upload,req,uploadPath); //请求转发 req.setAttribute("msg",msg); req.getRequestDispatcher("info.jsp").forward(req,resp); } catch (Exception e) { e.printStackTrace(); } } private DiskFileItemFactory getDiskFileItemFactory(File tempFile) { DiskFileItemFactory factory = new DiskFileItemFactory(); //通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将其放入到临时文件中 //设置缓冲区大小为1M factory.setSizeThreshold(1024*1024); //临时目录的保存目录,需要一个file factory.setRepository(tempFile); return factory; } private ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) { ServletFileUpload upload = new ServletFileUpload(factory); //监听文件上传进度: upload.setProgressListener(new ProgressListener() { @Override public void update(long pBytesRead, long pContentLength, int pItems) { System.out.println("总大小:"+pContentLength+"已上传:"+pBytesRead); } }); //处理乱码问题 upload.setHeaderEncoding("UTF-8"); //设置总共能够上传文件的大小 //1024 = 1kb*1024 = 1M*10 = 10M; upload.setSizeMax(1024*1024*10); return upload; } private String uploadParseRequest(ServletFileUpload upload, HttpServletRequest req, String uploadPath) { String msg = null; try { List<FileItem> fileItems = upload.parseRequest(req); for (FileItem fileItem : fileItems) { if(fileItem.isFormField()){ String name = fileItem.getName(); String value = fileItem.getString("UTF-8"); System.out.println(name+":"+value); }else { String uploadFileName = fileItem.getName(); //================处理文件======================// if(uploadFileName.trim().equals("")||uploadFileName == null){ continue; } String fileName = uploadFileName.substring(uploadFileName.indexOf("/")+1); String fileExtName = uploadFileName.substring(uploadFileName.indexOf(".")+1); String uuidPath = UUID.randomUUID().toString(); //================存放文件======================// //文件真实存储路径realPath String realPath = uploadPath+"/"+uuidPath; File realPathFile = new File(realPath); if(!realPathFile.exists()){ realPathFile.mkdir(); } //================文件传输======================// InputStream is = fileItem.getInputStream(); FileOutputStream fileOutputStream = new FileOutputStream(realPath+"/"+fileName); //创建缓冲区 byte[] buffer = new byte[1024*1024]; //判断是否读取完毕 int len = 0; while((len=is.read(buffer))>0){ //写入 fileOutputStream.write(buffer,0,len); } fileOutputStream.close(); is.close(); msg = "文件上传成功"; //文件上传成功清楚临时文件 fileItem.delete(); } } } catch (FileUploadException | UnsupportedEncodingException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return msg; } }
16.邮件发送
-
发送使用SMTP协议
-
接收使用POP3协议
-
MIME支持非文本传输
邮件分为简单邮件和非简单邮件
简单邮件只传输文本类型的文件(纯文本邮件)
非简单邮件可以传输如附件、图片等文件。
17.细节
1.JavaWeb项目下的web-inf文件是对用户不可见的,所以尽量不将文件放在里面.
2.JVM:双亲委派机制:如何寻找一个类
先从导的包中寻找,再取类加载器中找,再到art.jar包找
3.使用Maven直接创建项目时可能会遇到发行版本不支持
这是因为maven框架会覆盖idea的jdk版本
在maven的pom.xml中配置如下
<properties>
<!-- 项目编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 本地编译JDK版本 -->
<maven.compiler.source>14</maven.compiler.source>
<!-- 项目部署JDK版本 -->
<maven.compiler.target>14</maven.compiler.target>
</properties>
锁定jdk版本
4.Junit单元测试
作用:在方法前加入@Test,即可不需要main函数,来执行函数
在pom.xml中导入junit依赖
注意是否存在scope标签限制作用域
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
@Test
public void test(){
System.out.println("Hello");
}
5.针对URL如何获取它的文件名和文件格式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ph9wfSRV-1619330279652)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20201110084011222.png)]
6.针对使用Maven创建空项目时遇到不支持发行版本的错误
原因:但是如果用Idea建立一个普通的Maven项目,然后再随便建立一个类运行,则就会报这个错。那么说明maven限制了此项目jdk的版本为1.5,或者说Idea软件与Maven软件配合的不够好。
解决办法:直接在pom.xml中添加如下
<properties>
<!-- 项目编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 本地编译JDK版本 -->
<maven.compiler.source>14</maven.compiler.source>
<!-- 项目部署JDK版本 -->
<maven.compiler.target>14</maven.compiler.target>
</properties>
7.对于IDEA中提示的一些无必要的警告解决办法
使用注解@SuppressWarnings(“all”)
package com.sy.util;
@SuppressWarnings("all")
public class IdUtils {
}
} catch (FileUploadException | UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return msg;
}
}
# 16.邮件发送
1. 发送使用SMTP协议
2. 接收使用POP3协议
3. MIME支持非文本传输
邮件分为简单邮件和非简单邮件
简单邮件只传输文本类型的文件(纯文本邮件)
非简单邮件可以传输如附件、图片等文件。
# 17.细节
## 1.JavaWeb项目下的web-inf文件是对用户不可见的,所以尽量不将文件放在里面.
## 2.JVM:双亲委派机制:如何寻找一个类
先从导的包中寻找,再取类加载器中找,再到art.jar包找
## 3.使用Maven直接创建项目时可能会遇到发行版本不支持
这是因为maven框架会覆盖idea的jdk版本
在maven的pom.xml中配置如下
```xml
<properties>
<!-- 项目编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 本地编译JDK版本 -->
<maven.compiler.source>14</maven.compiler.source>
<!-- 项目部署JDK版本 -->
<maven.compiler.target>14</maven.compiler.target>
</properties>
锁定jdk版本
4.Junit单元测试
作用:在方法前加入@Test,即可不需要main函数,来执行函数
在pom.xml中导入junit依赖
注意是否存在scope标签限制作用域
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
@Test
public void test(){
System.out.println("Hello");
}
5.针对URL如何获取它的文件名和文件格式
[外链图片转存中…(img-Ph9wfSRV-1619330279652)]
6.针对使用Maven创建空项目时遇到不支持发行版本的错误
原因:但是如果用Idea建立一个普通的Maven项目,然后再随便建立一个类运行,则就会报这个错。那么说明maven限制了此项目jdk的版本为1.5,或者说Idea软件与Maven软件配合的不够好。
解决办法:直接在pom.xml中添加如下
<properties>
<!-- 项目编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 本地编译JDK版本 -->
<maven.compiler.source>14</maven.compiler.source>
<!-- 项目部署JDK版本 -->
<maven.compiler.target>14</maven.compiler.target>
</properties>
7.对于IDEA中提示的一些无必要的警告解决办法
使用注解@SuppressWarnings(“all”)
package com.sy.util;
@SuppressWarnings("all")
public class IdUtils {
}