JavaWeb
1、概念
- 静态web
- html ,css
- 轮播图,点击特效:实现了伪动态
- 伪动态技术实现:JavaScript[实际开发用的多],VBScript
- 动态web
- 技术栈:Servlet/JSP,ASP,PHP
ASP:
- 微软:国内最早流行的
- 在HTML中嵌入VB的脚本,ASP+COM;
- 维护成本高,页面混乱
- C#
PHP:
- 开发速度快,跨平台
- 无法承载大访问量的情况
JSP/Servlet:
- sun公司主推的B/S架构
- 可以承载高并发,高可用,高性能带来的影响;
2、Web服务器
IIS
微软的;ASP,Windows中自带的
Tomcat
实际上运行JSP页面和Servlet
2.1、Tomcat启动和配置
Tomcat核心配置文件,conf/server.xml
可以配置主机端口号,默认端口号8080;
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"/>
可以配置主机名称:
- 默认的主机名为localhost:127.0.0.1
- 在本地配置中System32/drivers/etc host配置文件中修改
- 默认网站存放位置webapps
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
面试题:
网站如何进行访问?
- 输入域名
- 检查本机的C:\Windows\System32\driver\etc\hosts配置文件有没有这个域名映射;
- 若查找到对应域名映射,返回ip地址
- 若本机没有查找到去DNS查找
2.2、HTTP
超文本传输协议,http:80,https:443
2.2.1、两个时代
- http 1.0
- 协议http/1.0:客户端可以与web服务器连接后,只能获得一个web资源,断开连接
- http 2.0
- 协议http/1.1:客户端可以与web服务器连接后,能获得多个web资源,断开连接
2.2.2、HTTP请求和响应
请求行:
- 请求方式:Get/Post,head,delete,put,tract
- get:请求能够携带的参数比较少,大小有限制,会显示,不安全,但是高效
- post:请求能够携带的参数没有限制,大小无限制,不显示,安全但是不高效
消息头:
- Accept:浏览器所支持的数据类型
- Accept-Encoding:支持的编码格式 GBK UTF-8 GB2312 ISO8859-1
- Accept-Language:语言环境
- Cache-Control:缓存控制
- Connection:请求完成是否断开连接
- Host:主机
响应体:
- 与消息头相同;
响应状态码:
- 200:响应成功
- 3**:请求重定向
- 404:页面不存在
- 5**:服务器代码错误
面试题:
浏览器地址栏输入并回车到页面展示都经历了什么?
3、Servlet
用于开发动态web
Servlet接口在Sun公司有两个默认的实现类:HttpServlet,GenericServlet
为什么编写Servlet映射?
- 我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务器中注册我们写的Servlet,并且还需要给他一个浏览器能够访问的路径
<!--注册servlet-->
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.shine.HelloServlet</servlet-class>
</servlet>
<!--一个servlet对应一个Mapping:映射-->
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<!--请求路径-->
<url-pattern>/shine</url-pattern>
</servlet-mapping>
3.1、Servlet原理
Servlet是由Web服务器调用,web服务器在收到浏览器的首次请求后,会将类加载为class后运行,web容器会产生请求和响应
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z1rnOJlG-1654347700567)(C:\Users\阳光就在天上\Desktop\flag\Servlet请求原理.png)]
3.2、Mapping相关问题
- 优先级问题
- 指定了固有的映射路径优先级最高,如果找不到就会走默认的请求处理;
- 指定后缀
- 自定义后缀实现请求映射
<!--注意:*前不能加项目的映射路径-->
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>*.sunshine</url-pattern>
</servlet-mapping>
- 配置多个映射
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/shine01</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/shine02</url-pattern>
</servlet-mapping>
3.3 、ServletContext
ServletContext是在服务器范围存在,服务器不关闭,数据一致存在。
web容器在启动时候,他会为每个web程序都创建一个对应的ServletContext对象,他代表了当前web应用:
-
共享数据
-
在这个Servlet中保存的数据,在另外一个Servlet中可以拿到
-
String name = "阳光就在天上"; ServletContext context = this.getServletContext(); context.setAttribute("name",name);
-
resp.setContentType("text/http"); resp.setCharacterEncoding("utf-8"); ServletContext context = this.getServletContext(); String name = (String)context.getAttribute("name"); resp.getWriter().print(name);
-
-
获取初始化参数
-
可以获得xml配置文件中配置的参数
-
<context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/mybatis</param-value> </context-param>
-
ServletContext context = this.getServletContext(); String url = context.getInitParameter("url"); resp.getWriter().print(url);
-
-
请求转发
-
转发路径不会改变
-
ServletContext context = this.getServletContext(); context.getRequestDispatcher("/gp").forward(req,resp);
-
-
读取资源文件
-
InputStream stream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"); Properties prop= new Properties(); prop.load(stream); String username = prop.getProperty("username"); String password = prop.getProperty("password"); resp.getWriter().print(username+password);
-
资源导出问题解决:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
3.4、HttpServletRequest
web服务器接收客户端请求,创建代表请求的HttpServletRequest对象
- 获取前端传递的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobby");
- 请求转发
req.getRequestDispatcher("/success.jsp").forward(req,resp);
3.5、HttpServletResponse
负责向浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException; //写中文,造成字符串损坏或丢失
负责向浏览器发送响应头
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentType(String var1);
常见应用:
- 向浏览器输出信息
- 下载文件
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取下载文件的路径
String realPath = this.getServletContext().getRealPath("/1.png");
System.out.println("文件下载路径"+realPath);
//2.获取下载的文件名
//直接获取最后一个\后面的下一位
String filename = realPath.substring(realPath.lastIndexOf("\\")+1);
//3.让浏览器支持下载所需要的东西
resp.setHeader("Content-Disposition","attachment;filename="+filename);
//4.获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
//5.创建缓冲区
int len=0;
byte[] buffer = new byte[1024];
//6.获得OutputStream对象
ServletOutputStream out = resp.getOutputStream();
//7.将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区数据写至客户端
while ((len=in.read(buffer))!=-1){
out.write(buffer,0,len);
}
in.close();
out.close();
}
- 验证码实现
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置浏览器三秒刷新一次
resp.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);
//告诉浏览器这个请求用图片方式打开
resp.setContentType("image/jpeg");
//网站存在缓存,取消浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//将图片写给浏览器
ImageIO.write(image,"jpg",resp.getOutputStream());
}
//生成随机数
private String makeNum(){
Random random = new Random();
String num = random.nextInt(9999999) + "";
//将随机数一直保持7位,不够后面填充0
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < 7-num.length(); i++) {
buffer.append(0);
}
num = buffer.toString() + num;
return num;
}
- 实现重定向
/*
resp.setHeader("Location","/r/img");
resp.setStatus(302);
*/
resp.sendRedirect("/r/img");
面试题:重定向和转发的区别?
相同点:
- 都会实现页面跳转
不同点:
- 请求转发,url地址不会发生变化
- 重定向,不会发生变化
4、Cookie、Session
保存会话的两种技术Cookie、Session
4.1、Cookie
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
Cookie[] cookies = req.getCookies();
if (cookies != null){
out.write("上次访问时间为:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//获取cookie的名字
if (cookie.getName().equals("time")){
//获取cookie中的值
long l = Long.parseLong(cookie.getValue());
Date date = new Date(l);
//下面进行编码,这里输出就需要解码
//out.write(URLDecoder.decode(cookie.getValue(),"utf-8"));
out.write(date.toLocaleString());
}
}
}else {
out.write("这是你第一次访问");
}
Cookie cookie = new Cookie("time", System.currentTimeMillis()+"");
//若是中文可以利用URLEncoder.encode进行编码
//cookie = new Cookie("name", URLEncoder.encode("阳光就在天上","utf-8"));
//设置cookie有效期
cookie.setMaxAge(24*60*60);
//服务器给客户端响应一个cookie
resp.addCookie(cookie);
cookie:一般会保存在本地目录下appdata;
一个cookie只能保存一个信息,
一个web站点可以给浏览器发送多个cookie,
浏览器上限为300个cookie,
每个站点最多存放20个cookie
cookie大小限制为4kb;
4.2、Session
- 服务器会给每一个用户(浏览器)创建一个Session对象
- 一个Session独占一个浏览器,不关闭浏览器Session就一直存在
- 保存用户信息
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//给Session中存放东西
session.setAttribute("name",new Person("阳光就在天上",1));
//获取Session的ID
String sessionId = session.getId();
if (session.isNew()){
resp.getWriter().write("session创建成功");
}else {
resp.getWriter().write("session已经在服务器中存在,他的id是:" + sessionId);
}
会话自动过期,xml配置:
<!--设置Session默认的失效时间-->
<session-config>
<!--十五分钟Session自动失效-->
<session-timeout>15</session-timeout>
</session-config>
4.3、Session和Cookie区别
- Cookie是将用户的数据写给用户的浏览器,浏览器保存
- Session是把用户的数据写到用户独占Session中。服务器端保存
- Session对象由服务器创建
5、JSP
5.1、JSP原理
浏览器向服务器发送请求,无论访问什么资源,都是在访问Servlet,
JSP最终会被转换成一个Java类
JSP本质上就是一个Servlet
//初始化
public void _jspInit() {
}
//销毁
public void _jspDestroy() {
}
//JSPService
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
内置对象
final javax.servlet.jsp.PageContext pageContext; //页面上下文
javax.servlet.http.HttpSession session = null; //session
final javax.servlet.ServletContext application; //application
final javax.servlet.ServletConfig config; //config
javax.servlet.jsp.JspWriter out = null; //out
final java.lang.Object page = this; //page当前页面
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
5.2、JSP基础语法
JSP表达式
<%=变量或者表达式%>
<%= new java.util.Date()%>
JSP脚本片段
<%
int sum = 2;
out.println("<h1>Sum="+sum+"</h1>");
%>
<%
for(int i = 0; i<5;i++){
%>
<h1>Hello,world <%=i%> </h1>
<%
}
%>
JSP声明(全局声明)
<%!
static{
System.out.pringln("阳光就在天上");
}
private int globalVar = 0;
%>
JSP声明:会被编译到JSP生成JAVA的类中,其他的,就会被生成到_jspService方法中;
JSP注释,不会在客户端显示,HTML注释会显示;
5.3、JSP指令
<%--这个标签在底层会将两个页面合为一个--%>
<%@include ...%>
<%--这个标签会拼接页面--%>
<jsp:include ...>
5.4、9大内置对象
- 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");//保存的数据只在服务器中有效,从服务器开启到关闭
%>
<%
String name1 = (String) pageContext.findAttribute("name1");
String name2 = (String) pageContext.findAttribute("name2");
String name3 = (String) pageContext.findAttribute("name3");
String name4 = (String) pageContext.findAttribute("name4");
String name5 = (String) pageContext.findAttribute("name5");
pageContext.forward("/pageDemo02.jsp");
%>
<%--使用EL表达式输出--%>
<h1>取出的值为</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<h3>${name5}</h3>
<h3><%=name5%></h3>
从底层到高层(作用域):page–>request–>session–>application(双亲委派机制)
5.5、JSP标签、JSTL标签、EL表达式
EL表达式:
- 获取数据
- 执行运算
- 获取web开发的常用对象
JSP标签:
<jsp:include page="jsptag02.jsp"/>
<%--jsp标签--%>
<jsp:forward page="jsptag02.jsp">
<jsp:param name="name" value="阳光就在天上"/>
<jsp:param name="age" value="18"/>
</jsp:forward>
JSTL标签库:
- 核心标签
<%--引入核心标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:out></c:out>
<c:when></c:when>
<c:foreach></c:foreach>
<form action="coreif01.jsp" method="get">
<%--
EL表达式获取表单中的数据
${param.参数名}
--%>
<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>
<c:out value="${isadmin}"></c:out>
<%--定义变量--%>
<c:set var="score" value="12"/>
<c:choose>
<c:when test="${score>=90}">
成绩优秀
</c:when>
<c:when test="${score>=80}">
成绩良好
</c:when>
<c:when test="${score<=60}">
成绩差
</c:when>
</c:choose>
<%
ArrayList<String> people = new ArrayList<String>();
people.add(0,"1");
people.add(1,"2");
people.add(2,"3");
people.add(3,"4");
people.add(4,"5");
people.add(5,"6");
request.setAttribute("list",people);
%>
<c:forEach var="people" items="${list}">
<c:out value="${people}"/>
<br>
</c:forEach>
在Tomcat中也需要导入jstl的包,否则会报:jstl解析错误
- 格式化标签
- SQL标签
- XML标签
6、JavaBean
实体类:
- 必须要有无参构造
- 属性必须私有化
- 必须有对应get/set方法
一般用来和数据库字段做映射 ORM(对象关系映射);
<%
// People people = new People();
// people.setAddress("大同");
// people.setAge(18);
// people.setId(3);
// people.setName("sun");
%>
<%--等价于上面--%>
<jsp:useBean id="people" class="com.xiong.pojo.People" scope="page"/>
<jsp:setProperty name="people" property="address" value="大同"/>
<jsp:setProperty name="people" property="id" value="3"/>
<jsp:setProperty name="people" property="age" value="18"/>
<jsp:setProperty name="people" property="name" value="sun"/>
<%--<%=people.getAddress()%>--%>
姓名:<jsp:getProperty name="people" property="name"/>
ID:<jsp:getProperty name="people" property="id"/>
年龄:<jsp:getProperty name="people" property="age"/>
地址:<jsp:getProperty name="people" property="address"/>
7、MVC三层架构
- 控制器:Controller(servlet)
- 接收用户的请求(request、Session)
- 交给业务层处理对应请求
- 重定向或者转发
- 视图层:View(JSP)
- 展示数据
- 提供连接发起Servlet请求
- Model:
- 业务处理:业务逻辑(Service)
- 数据持久层:CRUD(Dao)
Servlet专注于处理请求,以及控制视图跳转
JSP专注于显示数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-23HI6QWS-1654347700569)(C:\Users\阳光就在天上\Desktop\flag\MVC三层架构.png)]
8、过滤器(Filter)
public class CharacterEncodingFilter implements Filter {
//web服务器启动就初始化
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter初始化");
}
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("CharacterEncodingFilter执行前");
//让请求继续执行,若不写程序便停止
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("CharacterEncodingFilter执行后");
}
public void destroy() {
System.out.println("CharacterEncodingFilter销毁");
}
}
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.xiong.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
9、监听器(listener)
在线人数监听,通过session监听
public class OnlineCountListener implements HttpSessionListener {
//一旦创建session就会触发这个事件
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount");
System.out.println(httpSessionEvent.getSession().getId());
if (onlineCount==null){
onlineCount = new Integer(1);
}else {
//装箱拆箱
int count = onlineCount.intValue();
onlineCount = new Integer(count+1);
}
servletContext.setAttribute("OnlineCount",onlineCount);
}
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount");
if (onlineCount==null){
onlineCount = new Integer(0);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count-1);
}
servletContext.setAttribute("OnlineCount",onlineCount);
}
}
面试题:
System.exit(0)和System.exit(1)的区别:
System.exit(0)是将你的整个虚拟机里的内容都停掉了 ,而dispose()只是关闭这个窗口,但是并没有停止整个application exit() 。无论如何,内存都释放了!也就是说连JVM都关闭了,内存里根本不可能还有什么东西System.exit(0)是正常退出程序,而System.exit(1)或者说非0表示非正常退出程序System.exit(status)不管status为何值都会退出程序。和return 相比有以下不同点:return是回到上一层,而System.exit(status)是回到最上层。
10、文件上传
public class FileServlet extends HttpServlet {
@Override
protected void doPost(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.mkdirs();//若不存在则创建这个目录
}
//缓存(临时文件)
//临时路劲,假如文件超过了预期的大小,我们就将其放再一个临时文件中,过几天自动删除,或者提醒用户转存为永久
String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
File tmpFile = new File(tmpPath);
if (!tmpFile.exists()){
tmpFile.mkdirs();//若不存在则创建这个临时目录
}
//处理上传文件,一般都需要通过流来获取,我们可以使用request.getInputStream(),原生态的文件上传流获取,解析流,很麻烦
//但是我们建议使用Apache的文件上传组件来实现,common-fileupload,
//1.创建DiskFileItemFactory对象,处理文件上传路径或者大小限制
DiskFileItemFactory factory = getDiskFileItemFactory(tmpFile);
//2.获取ServletFileUpload
ServletFileUpload upload =getServletFileUpload(factory);
//3.处理上传文件
try {
String msg = uploadParseRequest(upload,req,uploadPath);
//servlet请求转发
req.setAttribute("msg",msg);
req.getRequestDispatcher("info.jsp").forward(req,resp);
} catch (FileUploadException e) {
e.printStackTrace();
}
}
public static DiskFileItemFactory getDiskFileItemFactory(File tmpFile) {
DiskFileItemFactory factory = new DiskFileItemFactory();
//创建这个工厂设置一个缓冲区,当文件大于这个缓冲区的时候,将他放入临时文件中
factory.setSizeThreshold(1024*1024);//大小为1M
factory.setRepository(tmpFile);
return factory;
}
public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
ServletFileUpload upload = new ServletFileUpload(factory);
//监听文件的上传进度
upload.setProgressListener(new ProgressListener() {
public void update(long l, long l1, int i) {
System.out.println("总大小:"+ l1 + "已上传" + l);
}
});
//处理乱码问题
upload.setHeaderEncoding("UTF-8");
//设置单个文件的最大值
upload.setFileSizeMax(1024*1024*10);
//设置总共能够上传文件的大小
upload.setSizeMax(1024*1024*10);
return upload;
}
public static String uploadParseRequest(ServletFileUpload upload, HttpServletRequest req, String uploadPath) throws IOException, FileUploadException {
String msg = "";
//将前端请求解析,封装成一个FileItem对象
//通过upload对象解析请求进行封装
List<FileItem> fileItems=upload.parseRequest(req);
for (FileItem fileItem:fileItems){
if (fileItem.isFormField()){ //判断上传文件的表单(普通表单还是带文件的表单)判断里面的每一项
//getFiledName指的是前端表单控件的name
String name = fileItem.getFieldName();
String value = fileItem.getString("UTF-8");//处理乱码
System.out.println(name + ":" + value);
}else {//判断为是上传文件
//===================处理文件=======================
//拿到文件名字
String uploadFileName = fileItem.getName();
System.out.println("上传文件的名字是:"+uploadFileName);
if (uploadFileName.trim().equals("")||uploadFileName==null){
continue;//文件名不合法直接判断下一个
}
//获取上传的文件名 /images/girl/2.png
String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/")+1);
//获得文件的后缀名
String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".")+1);
/*
如果文件后缀名不是我们所需要的就直接return,不处理,告诉用户文件类型错误
*/
System.out.println("文件信息[文件名" + fileName + "文件类型" + fileExtName + "]");
//可以使用UUID(唯一识别的通用码),保证文件名唯一
//UUID.randomUUID(),随机生成一个唯一识别的通用码
String uuidPath = UUID.randomUUID().toString();
//=====================文件存放地址=======================
//文件真实存在路径 realPath
String realPath = uploadPath+"/"+uuidPath;
//给每一个文件创建一个对应的文件夹
File realPathFile = new File(realPath);
if (!realPathFile.exists()){
realPathFile.mkdirs();
}
//=====================文件传输================
//获得文件上传的流
InputStream inputStream = fileItem.getInputStream();
//创建一个文件输出流
//realPath = 真实的文件夹
//差了一个文件;加上输出文件的名字+"/"uuidFileName
FileOutputStream fos = new FileOutputStream(realPath+"/"+fileName);
//创建一个缓冲区
byte[] buffer = new byte[1024*1024];
//判断文件是否读取完毕
int len = 0;
while ((len=inputStream.read(buffer))>0){
fos.write(buffer,0,len);
}
//关闭流
fos.close();
inputStream.close();
msg = "文件上传成功!";
fileItem.delete();//上传成功,清除临时文件
}
}
return msg;
}
}