SSM下使用fileupload上传视频文件

FileUpload 是 Apache commons下面的一个子项目,用来实现Java环境下面的文件上传功能,与常见的SmartUpload齐名

上传的文件要求包括一个根据RFC 1867(在HTML中基于表单的文件)编码的选项列表清单。组件FileUpload可以解析这个请求,并给你的应用程序提供一份独立上传的项目清单。无论每个项目背后如何执行都实现了FileItem接口。

这里将描述组件FileUpload库的普通API,这些API比较简单。不过,对于最终的实现,你可以参考最新的API流。

每一个文件项目都有一些属性,这些可能在你的应用程序中应用到。比如:每一个项目有一个名称name和内容类型content type,并提供了一个 InputStream访问其数据。另一方面,你处理项目的方法可能有所不同,这个依赖于是否这个项目是一个规则的表单域,即:这个数据是来自普通的表单文本,还是普通的HTML域或是一个上传文件。在FileItem接口中提供了处理这些问题的方法,可以更加方便的去访问这些数据。

组件FileUpload使用FileItemFactory工厂创建新的文件项目。这个给了组件FileUpload很大的灵活性。这个工厂拥有怎样创建项目的最终控制权。工厂执行过程中上传项目文件的临时数据可以存储在内存中或硬盘上。这个依赖于上传项目的大小(即:数据的字节)。不过这种行为可以在你的应用程序中适当的自定制。

第一步在pom.xml文件下导入相应的jar包,如下所示:

	<!-- 上传视频 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-io</artifactId>
			<version>1.3.2</version>
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.5</version>
		</dependency>

		<dependency>
    		<groupId>commons-fileupload</groupId>
    		<artifactId>commons-fileupload</artifactId>
   			 <version>1.3.2</version>
		</dependency>

第二步:修改spring-mvc.xml文件,如下所示:

  <!-- 文件上传的配置 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 指定所上传文件的总大小不能超过500MB。注意maxUploadSize属性的限制不 是针对单个文件,而是所有文件的容量之和 -->
    <property name="maxUploadSize" value="52428800"></property>
    </bean>

第三步:创建数据库表:,如下所示

第四步:创建实体类:,如下所示:

package com.exam.bean;

public class Media {
    private Integer id;

    private String title;

    private String src;

    private String picture;

    private String descript;

    private String uptime;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title == null ? null : title.trim();
    }

    public String getSrc() {
        return src;
    }

    public void setSrc(String src) {
        this.src = src == null ? null : src.trim();
    }

    public String getPicture() {
        return picture;
    }

    public void setPicture(String picture) {
        this.picture = picture == null ? null : picture.trim();
    }

    public String getDescript() {
        return descript;
    }

    public void setDescript(String descript) {
        this.descript = descript == null ? null : descript.trim();
    }

    public String getUptime() {
        return uptime;
    }

    public void setUptime(String uptime) {
        this.uptime = uptime == null ? null : uptime.trim();
    }
}

 第五步:编写dao层的mapper接口,如下所示:

package com.exam.dao;


import java.util.List;

import com.exam.bean.Media;


public interface MediaMapper {
    int deleteByPrimaryKey(Integer id);

    int insert(Media record);

    int insertSelective(Media record);

    Media selectByPrimaryKey(Integer id);

    int updateByPrimaryKeySelective(Media record);

    int updateByPrimaryKey(Media record);
    
    List<Media> findAllMedia();
 
}

第六步:配置与数据库映射的xml文件,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.exam.dao.MediaMapper">
  <resultMap id="BaseResultMap" type="com.exam.bean.Media">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="title" jdbcType="VARCHAR" property="title" />
    <result column="src" jdbcType="VARCHAR" property="src" />
    <result column="picture" jdbcType="VARCHAR" property="picture" />
    <result column="descript" jdbcType="VARCHAR" property="descript" />
    <result column="uptime" jdbcType="VARCHAR" property="uptime" />
  </resultMap>
  <sql id="Base_Column_List">
    id, title, src, picture, descript, uptime
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from media
    where id = #{id,jdbcType=INTEGER}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    delete from media
    where id = #{id,jdbcType=INTEGER}
  </delete>
  <insert id="insert" parameterType="com.exam.bean.Media">
    insert into media (id, title, src, 
      picture, descript, uptime
      )
    values (#{id,jdbcType=INTEGER}, #{title,jdbcType=VARCHAR}, #{src,jdbcType=VARCHAR}, 
      #{picture,jdbcType=VARCHAR}, #{descript,jdbcType=VARCHAR}, #{uptime,jdbcType=VARCHAR}
      )
  </insert>
  <insert id="insertSelective" parameterType="com.exam.bean.Media">
    insert into media
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="title != null">
        title,
      </if>
      <if test="src != null">
        src,
      </if>
      <if test="picture != null">
        picture,
      </if>
      <if test="descript != null">
        descript,
      </if>
      <if test="uptime != null">
        uptime,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=INTEGER},
      </if>
      <if test="title != null">
        #{title,jdbcType=VARCHAR},
      </if>
      <if test="src != null">
        #{src,jdbcType=VARCHAR},
      </if>
      <if test="picture != null">
        #{picture,jdbcType=VARCHAR},
      </if>
      <if test="descript != null">
        #{descript,jdbcType=VARCHAR},
      </if>
      <if test="uptime != null">
        #{uptime,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.exam.bean.Media">
    update media
    <set>
      <if test="title != null">
        title = #{title,jdbcType=VARCHAR},
      </if>
      <if test="src != null">
        src = #{src,jdbcType=VARCHAR},
      </if>
      <if test="picture != null">
        picture = #{picture,jdbcType=VARCHAR},
      </if>
      <if test="descript != null">
        descript = #{descript,jdbcType=VARCHAR},
      </if>
      <if test="uptime != null">
        uptime = #{uptime,jdbcType=VARCHAR},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.exam.bean.Media">
    update media
    set title = #{title,jdbcType=VARCHAR},
      src = #{src,jdbcType=VARCHAR},
      picture = #{picture,jdbcType=VARCHAR},
      descript = #{descript,jdbcType=VARCHAR},
      uptime = #{uptime,jdbcType=VARCHAR}
    where id = #{id,jdbcType=INTEGER}
  </update>
  
  <!-- 查询所有 -->
  <select id="findAllMedia" resultMap="BaseResultMap">
  	select * from media
  </select>
  
</mapper>

第七步:编写service层接口,如下所示:

package com.exam.service;

import java.util.List;

import com.exam.bean.Media;



/**
 * 视频播放接口
 * @author cp
 *
 */
public interface IMediaService {
	  /**
     * 视频转码
     * @param ffmpegPath    转码工具的存放路径
     * @param upFilePath    用于指定要转换格式的文件,要截图的视频源文件
     * @param codcFilePath    格式转换后的的文件保存路径
     * @param mediaPicPath    截图保存路径
     * @return
     * @throws Exception
     */
    public boolean executeCodecs(String ffmpegPath,String upFilePath, String codcFilePath, String mediaPicPath)throws Exception;
    
    /**
     * 保存文件
     * @param media
     * @return
     * @throws Exception
     */
    public boolean saveMedia(Media media)throws Exception;
 
    
    /**
     * 根据Id查询视频
     * @param id
     * @return
     * @throws Exception
     */
    public Media queryMediaById(int id)throws Exception;
    
    /**
     * 查询所有的视频
     */
    public List<Media> queryAllMedia();
}

第八部:编写接口实现类,如下所示:

package com.exam.serviceImpl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.exam.bean.Media;
import com.exam.dao.DaoFactory;
import com.exam.service.IMediaService;



@Service
public class MediaService implements IMediaService {

	@Resource
	private DaoFactory daoFactory;
	
	@Override
	public boolean executeCodecs(String ffmpegPath, String upFilePath, String codcFilePath, String mediaPicPath)
			throws Exception {
		 // 创建一个List集合来保存转换视频文件为flv格式的命令
        List<String> convert = new ArrayList<String>();
        convert.add(ffmpegPath); // 添加转换工具路径
        convert.add("-i"); // 添加参数"-i",该参数指定要转换的文件
        convert.add(upFilePath); // 添加要转换格式的视频文件的路径
        convert.add("-qscale");     //指定转换的质量
        convert.add("6");
        convert.add("-ab");        //设置音频码率
        convert.add("64");
        convert.add("-ac");        //设置声道数
        convert.add("2");
        convert.add("-ar");        //设置声音的采样频率
        convert.add("22050");
        convert.add("-r");        //设置帧频
        convert.add("24");
        convert.add("-y"); // 添加参数"-y",该参数指定将覆盖已存在的文件
        convert.add(codcFilePath);

        // 创建一个List集合来保存从视频中截取图片的命令
        List<String> cutpic = new ArrayList<String>();
        cutpic.add(ffmpegPath);
        cutpic.add("-i");
        cutpic.add(upFilePath); // 同上(指定的文件即可以是转换为flv格式之前的文件,也可以是转换的flv文件)
        cutpic.add("-y");
        cutpic.add("-f");
        cutpic.add("image2");
        cutpic.add("-ss"); // 添加参数"-ss",该参数指定截取的起始时间
        cutpic.add("17"); // 添加起始时间为第17秒
        cutpic.add("-t"); // 添加参数"-t",该参数指定持续时间
        cutpic.add("0.001"); // 添加持续时间为1毫秒
        cutpic.add("-s"); // 添加参数"-s",该参数指定截取的图片大小
        cutpic.add("800*280"); // 添加截取的图片大小为350*240
        cutpic.add(mediaPicPath); // 添加截取的图片的保存路径

        boolean mark = true;
        ProcessBuilder builder = new ProcessBuilder();
        try {
            builder.command(convert);
            builder.redirectErrorStream(true);
            builder.start();
            
            builder.command(cutpic);
            builder.redirectErrorStream(true);
            // 如果此属性为 true,则任何由通过此对象的 start() 方法启动的后续子进程生成的错误输出都将与标准输出合并,
            //因此两者均可使用 Process.getInputStream() 方法读取。这使得关联错误消息和相应的输出变得更容易
            builder.start();
        } catch (Exception e) {
            mark = false;
            System.out.println(e);
            e.printStackTrace();
        }
        return mark;

	}

	@Override
	public boolean saveMedia(Media media) throws Exception {
		try {
			daoFactory.getMediaDao().insert(media);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
  
	@Override
	public Media queryMediaById(int id) throws Exception {
		Media media = daoFactory.getMediaDao().selectByPrimaryKey(id);
		return media;
	}

	@Override
	public List<Media> queryAllMedia() {
		List<Media> medias = daoFactory.getMediaDao().findAllMedia();
		return medias;
	}
	
	

}
package com.exam.serviceImpl;


import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.exam.service.IMediaService;



 
/**
 * serviceFactory
 * @author cp
 *
 */
@Service
public class ServiceFactory { 
	
	@Resource
	private IMediaService mediaService;
	
	 
	public IMediaService getMediaService(){
		return this.mediaService;
	}
}

第九步:编写前端展示页面jsp代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>视频上传</title>
</head>
<body>
	<form action="${pageContext.request.contextPath}/dofunction.do" method="post" enctype="multipart/form-data">
		<table>
			<tr>
				<td>选择视频:</td>
				<td>
					<input type="file" name="myvideo" />
				</td>
			</tr>
			<tr>
				<td>视频标题</td>
				<td>
					<input type="text" name="title"/>
				</td>
			</tr>
			<tr>
				<td>视频描述</td>
				<td>
					<textarea name="descript"></textarea>
				</td>
			</tr>
			<tr>
				<td colspan="2">
					<input type="submit" value="提交"/>
				</td>			 
			</tr>
			<tr>
				<td colspan="2">
					<a href="${pageContext.request.contextPath}/searchAll.do">进入视频列表</a>
				</td>			 
			</tr>
		</table>
	</form>
</body>
</html>

第十一步:编写control层代码,如下所示:

package com.exam.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.util.Streams;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import com.exam.bean.Media;
import com.exam.serviceImpl.ServiceFactory;
import com.exam.utils.MyWebPrinter;

/**
 * 测试controller
 * @author 
 *
 */
@Controller
public class MediaController {

//	private static final Logger logger = LoggerFactory.getLogger(MediaController.class);

	@Resource
	private ServiceFactory serviceFactory;

	/**
	 * 视频上传,解码并保存
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "/dofunction")
	public void handler(HttpServletRequest request, HttpServletResponse response,
			@RequestParam("myvideo") MultipartFile file) throws IOException {
		String message = "";
		try {
			Media media = new Media();
			// 解析数据
			media.setTitle(request.getParameter("title"));
			media.setDescript(request.getParameter("descript"));
			boolean flag = false; // 转码成功与否的标记
			// 上传文件
			ServletContext sctx = request.getServletContext();
			// 获得保存文件的路径
			String basePath = sctx.getRealPath("videos"); 
			// 获得文件名
			String fileUrl = file.getOriginalFilename();
			// 在某些操作系统上,item.getName()方法会返回文件的完整名称,即包括路径
			String fileType = fileUrl.substring(fileUrl.lastIndexOf(".")); // 截取文件格式
			// 自定义方式产生文件名
			String serialName = String.valueOf(System.currentTimeMillis());
			// 待转码的文件
			File uploadFile = new File(basePath + "/temp/" + serialName + fileType);
 
			// 保存文件
			Streams.copy(file.getInputStream(),new FileOutputStream(uploadFile.getAbsolutePath()),true);			
			// 判断文件的大小
			if (file.getSize() > 500 * 1024 * 1024) {
				message = "上传失败!您上传的文件太大,系统允许最大文件500M";
			}
			String codcFilePath = basePath + "/" + serialName + ".flv"; // 设置转换为flv格式后文件的保存路径
			String mediaPicPath = basePath + "/images" + File.separator + serialName + ".jpg"; // 设置上传视频截图的保存路径

			// 获取配置的转换工具(ffmpeg.exe)的存放路径
			String ffmpegPath = request.getServletContext().getRealPath("/tools/ffmpeg.exe");

			media.setSrc("videos/" + serialName + ".flv");
			media.setPicture("videos/images/" + serialName + ".jpg");
			media.setUptime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis())));
			// 转码
			flag = serviceFactory.getMediaService().executeCodecs(ffmpegPath, uploadFile.getAbsolutePath(),
					codcFilePath, mediaPicPath);

			if (flag) {
				// 转码成功,向数据表中添加该视频信息
				serviceFactory.getMediaService().saveMedia(media);	
				message="上传成功";
			}
			request.setAttribute("message", message);
		} catch (Exception e) {
			e.printStackTrace();			 
		}	 
		MyWebPrinter.print(response,"<script>alert('"+message+"');window.location.href='indexing.do';</script>");
	}

	/**
	 * 查询所有的视频
	 */
	@RequestMapping("/searchAll")
	public String findAll(HttpServletRequest request, Model model) {
		List<Media> medias = serviceFactory.getMediaService().queryAllMedia();
		request.setAttribute("medias", medias);
		return "admin/media_list";
	}

	/**
	 * 视频播放
	 */
	@RequestMapping("/play")
	public String play(int id, HttpServletRequest request, HttpServletResponse response) {
		String idstr = id + "";
		int mediaId = -1;
		Media media = null;
		if (null != idstr) {
			mediaId = Integer.parseInt(idstr);
		}
		try {
			media = serviceFactory.getMediaService().queryMediaById(mediaId);
		} catch (Exception e) {
			e.printStackTrace();
		}
		request.setAttribute("media", media);
		return "admin/media_player";
	}

	/**
	 * 开始上传视频
	 * 
	 * @return
	 */
	@RequestMapping("/indexing")
	public String media(HttpServletRequest request, Model model) {
		return "admin/media_upload";
	}
}

测试:

 需要源码的+Q1556554374

发布了85 篇原创文章 · 获赞 39 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_41338249/article/details/96703043