zoukankan      html  css  js  c++  java
  • 监听器&上传下载&I18N

     

     

     

    监听器(Listener)

    监听Java对象 的方法调用和属性改变()

    web的一个组件

    事件驱动编程:事件源,事件名称,事件响应函数,事件对象

    以后在Spring中的配置

    WEB中有哪些监听器?  作用域生命周期监听器    作用域属性监听器

    作用域的生命周期监听器: 负责监听request,session,application的创建和销毁.

     ServletRequestListener:

          HttpSessionListener:

          ServletContextListener: 监听系统启动时,直接编写初始化代码.

    作用域属性监听器

    作用域的属性监听器(添加/删除/替换属性):

          ServletRequestAttributeListener:

          HttpSessionAttributeListener:

          ServletContextAttributeListener

    进行配置(webxml, 标签配置)1<listener><listener-class>包名。类名<listener-class><listener>

    @webListener

    上传功能

    想要上传,我们在前台(页面上)需要一个上传的控件,让用户可以通过这个控件选择文件。

    <input type="file" name="heading">

    reg.jsp

    <form action="/upload" method="post">

    用户:<input type="text" name="name" /> <br />

    密码:<input type="password" name="pwd" /> <br />

    头像:<input type="file" name="headImg" /> <br />

    <input type="submit" value="注册">

    </form>

     咱们的Servlet中拿到的是一个文件的名称(字符串)

     最后想要的肯定是一个二进制的流

    重要:上传时,我们表单的请求类型必需设置成multipart/form-data

              上传的method必需是POST

    上传流的请求头信息

    content-type

    咱们Servlet中拿到的值与数据必需是经过编码的值,而现在我们无法拿到任何值了。这里如果要拿到值

    1 准备一个form表单,里面有一个上传,form表单的类型必需是multipart/form-data

    2 准备一个上传的Servlet,到后台接收传过来的普通表单数据 与 文件(二进制)

    3 导入相应的FileUpload jar(commons-fileupload-1.2.2.jar ,commons-io-1.4.jar)

     完成上传功能

    完成文件上传重要方法:

    fileItem.write(File file);

    FileItemd对象就是从request中获得数据对象,

    通过调用它的write把其中的数据写入到磁盘文件(File file

    //boolean isMultipart = ServletFileUpload.isMultipartContent(req);

    try {

    //创建一个磁盘工厂对象

    FileItemFactory factory = new DiskFileItemFactory();

    //创建文件 上传处理器

    ServletFileUpload upload = new ServletFileUpload(factory);

    //解析请求(生成FileItem对象放到集合中)

    //FileItem对象:对表单中的每一个表单控制做的封装 <input type="text" name="name" />

    List<FileItem> items = upload.parseRequest(req);

    for (FileItem fileItem : items) {

    if(fileItem.isFormField()){

    //代表是一般表单,用一般表单的处理方式解决即可

    }else{

    //拿到文件的名称

    String fileName = fileItem.getName();

    //最后文件上传的位置

    File uploadFile = new File("D:/",fileName);

    //将本地的文件写到服务器中

    fileItem.write(uploadFile);

    }

    }

    } catch (Exception e) {

    e.printStackTrace();

    }

    上传细节处理

      IE低版本的文件名称Bug解决

     修改前

    String filename=fileItem.getname();

    修改后

    String filename=FilenameUtil.getName(fileItem.getname());

    上传文件的名称冲突问题

    代码分析:

    //拿到文件的名称

    String fileName = FilenameUtils.getName(fileItem.getName());

    //拿到文件的后缀

    String extName = FilenameUtils.getExtension(fileName);

    //生成随机的名称

    String fileUUIDName = UUID.randomUUID().toString();

    //结合成我们的随机名称(带后缀)

    String randomFileName = fileUUIDName+"."+extName;

    //最后文件上传的位置

    File uploadFile = new File("D:/",randomFileName);

     将文件存在本项目中

     在自己的项目下根目录下面创建一个upload文件夹,然后把所有上传的文件保存在这个目录下即可:

    super.getServletContext().getRealPath("/");      我们upload文件夹的路径,然后把上传的文件保存到这个文件夹中了。

    代码:拿到本项目中的路径

    //最后文件上传的位置

    String realPath = super.getServletContext().getRealPath("/upload");

    File uploadFile = new File(realPath,randomFileName);

     普通字段获取

    if(fileItem.isFormField()){

    //代表是一般表单,用一般表单的处理方式解决即可

    //拿到字段的名称(请参照表单控制的name属性)

    String fieldName = fileItem.getFieldName();

    //拿到相应字段的值

    String value = fileItem.getString("UTF-8");

    System.out.println(fieldName+":"+value);

    }else{

       //上传文件的代码

    }

     设置缓存大小与临时目录

    设置缓存大小:

    factory.setSizeThreshold(1024 * 10 * 5); //50KB //设置缓存大小

    设置临时目录:

    factory.setRepository(new File("C:/temp"));  //设置临时目录

     设置文件大小

    //得到一个文件的最大值 -1代表没有上限

    upload.setFileSizeMax(1024 * 10* 2); //20KB

    //代表所有请求的大小 -1代表没有上限

    upload.setSizeMax(1024 * 1024 * 2); // 2M

      上传工具类(FileUtil)

     把我们要抽取的这段重复代码直接写到工具方法中

    该方法中需要的一些参数咱们直接传过去

    提供更好的灵活性,对工具类进行修改

    我们要提供一个工具类FileUtil,然后添加一个静态方法uploadImg

    咱们现在在工具类上加一个功能:确定我们要上传的图片类型

    //准备只支持的图片类型

    private static final String[] IMG_TYPE = {"jpg","png","gif","bmp"};

    /**

     * 如果我的工具类要检查文件的类型,怎么做?

     * @param req

     */

    public static void upload(HttpServletRequest req){

    try {

    DiskFileItemFactory  factory = new DiskFileItemFactory();

    ServletFileUpload upload = new ServletFileUpload(factory);

    upload.setFileSizeMax(1024*1024*2);//单个文件最大2M

    upload.setSizeMax(1024*1024*3);//总大小最大3M

    List<FileItem> items = upload.parseRequest(req);

    for (FileItem fileItem : items) {

    if(fileItem.isFormField()){

    //代表是一般表单,用一般表单的处理方式解决即可

    //拿到字段的名称(请参照表单控制的name属性)

    String fieldName = fileItem.getFieldName();

    //拿到相应字段的值

    String value = fileItem.getString("UTF-8");

    System.out.println(fieldName+":"+value);

    }else{

    //拿到文件的名称

    String fileName = FilenameUtils.getName(fileItem.getName());

    //拿到文件的后缀

    String extName = FilenameUtils.getExtension(fileName);

    //如果图片类型不匹配,

    if(!Arrays.asList(IMG_TYPE).contains(extName)){

    //给出错误提示

    throw new RuntimeException("亲,你上传的图片类型不匹配!");

    }

     

    //生成随机的名称

    String fileUUIDName = UUID.randomUUID().toString();

    //结合成我们的随机名称(带后缀)

    String randomFileName = fileUUIDName+"."+extName;

    //最后文件上传的位置

    String realPath = req.getServletContext().getRealPath("/upload");

    File uploadFile = new File(realPath,randomFileName);

    //将本地的文件写到服务器中

    fileItem.write(uploadFile);

    }

    }

    }catch(RuntimeException e){

    throw e;

    }catch (Exception e) {

    e.printStackTrace();

    }

    }

    第一个问题:拿不到当前表单字段值(只能在工具类中打印没有意义)

    第二个问题:文件上传后,我们拿到不到上传的文件的数据(文件名称与路径)

        注意了:上面的数据我们以后很有可能需要拿到并上传到数据库

     们准备两个容器(就是集合),然后一个容器装普通表单,一个窗口装上传的文件数据。

    由于可能会出现多文件上传!而一个文件对应的属性有很多,于是我们需要把文件单独进行一个对象的封装(这个在以后的实际开发中是非常有必要的)。于是我们准备了一个CFile对象还封装文件对象。

    CFile

    //文件对象

    public class CFile {

    private String name;

    private String path;

       //提供getter,setter 。。。

    }

    FileUtil

    Servlet中完整代码

    try {

    //装普通form的容器

    Map<String,String> fieldMap = new HashMap<String,String>();

    //装文件的容器

    Map<String,CFile> filesMap = new HashMap<String,CFile>();

    FileUtil.upload(req,fieldMap,filesMap);

    System.out.println(fieldMap);

    System.out.println(filesMap);

    } catch (RuntimeException e) {

    req.setAttribute("errorMsg", e.getMessage());

    req.getRequestDispatcher("/reg.jsp").forward(req, resp);

    }

     

    下载功能

    超连接下载功能:

    download.jsp

    <a href="/download?filename=aa.rar">aa.rar</a><br />

    <a href="/download?filename=美女.rar">美女.rar</a><br />

    <a href="/download?filename=用户.rar">用户.rar</a><br />

    <a href="/download?filename=用户.png">用户.png</a><br />

    ·  

    @WebServlet("/download")

    public class DownLoadServlet extends HttpServlet{

     

    @Override

    protected void service(HttpServletRequest req, HttpServletResponse resp)

    throws ServletException, IOException {

    //告诉浏览器文件应该被下载,而不是被直接打开(IE6直接打开)

    resp.setContentType("application/x-msdownload");

    //得到文件名

    String filename = req.getParameter("filename");

    //得到文件的真实路径

    String realpath = super.getServletContext().getRealPath("/download");

    //拿到咱们要下载的文件

    File file = new File(realpath, filename);

     

    //解决乱码问题(兼容IE与火狐)

    /**

     * 这里注意:这个MSIE只对IE低版本有效,高版本又需要单独处理

     */

    String userAgent = req.getHeader("User-Agent");

    if(userAgent.contains("MSIE")){

    filename = URLEncoder.encode(filename, "UTF-8");

    }else{

    filename = new String(filename.getBytes("UTF-8"),"ISO-8859-1");

    }

    解决下载文件全部都是download名字

    resp.setHeader("Content-Disposition", "attachment; filename="+filename);

    //将文件下载到本地

    /**

     * 两个参数:第一个参数相当于拿到程序中的真实文件

     *          第二个参数拿到我们的响应输出流

     *     然后通过流将文件从程序拷备到客户端

     */

    Files.copy(Paths.get(file.getAbsolutePath()), resp.getOutputStream());

    }

    }

     

     

     

     

     

     

  • 相关阅读:
    netstat命令的使用详情
    ps -ef | grep使用详解
    java反射
    Java中的类和类加载机制
    SpringMVC自定义视图 Excel视图和PDF视图(excel部分自己看过,pdf没接触过 )
    JS中!!的作用
    JSONObject没有fromObject方法及其依赖引入
    hdu 3507 Print Article(斜率优化)
    hrbust 2373 小C的问题
    poj 2104 K-th Number(可持久化线段树)/hdu 2665
  • 原文地址:https://www.cnblogs.com/wzscom/p/10391532.html
Copyright © 2011-2022 走看看