玻璃鱼 - 上传图片 - 如何正确操作

4

我正在使用最新的Glassfish(3.1.2),因此不需要使用Apache FileItem,也没有使用getPart()时出现的错误。我读到上传图像的最佳实践是将它们保存在文件系统中(例如请参见这里)。我正在编辑已经存在的代码 - 而且还很臭 - 所以我想做以下操作:

Part p1 = request.getPart("file");
System.out.println("!!!!!P1 : " + p1);

打印:

!!!!!P1 : File name=DSC03660.JPG, 
StoreLocation=C:\_\glassfish3\glassfish\domains\domain1\generated\jsp\elkethe\upload_7cb06306_138b413999a__7ffa_00000000.tmp, 
size=2589152bytes, isFormField=false, FieldName=file

newlines mine. In the code people are doing :

if (request.getParameter("crop") != null) {
    // get path on the server
    String outputpath = this.getServletContext().getRealPath(
            "images/temp/" + session.getId() + ".jpg");
    // store photo
    InputStream is = p1.getInputStream();
    createPhoto(is, outputpath);
    session.setAttribute("photo_path", "images/temp/" + session.getId()
            + ".jpg");
    response.sendRedirect("cropping");
    return;
}

在哪里

private void createPhoto(InputStream is, String outputpath) {
    FileOutputStream os = null;
    try {
        os = new FileOutputStream(outputpath);
        // write bytes taken from uploaded file to target file
        int ch = is.read();
        while (ch != -1) {
            os.write(ch);
            ch = is.read();
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        Helpers.close(os);
    }
}

现在的情况是,提交表单时,文件会上传到StoreLocation(???),所以所有这些都是无用的。
我的问题是:
- 什么是StoreLocation?这些glassfish上传有多长时间?所有这些参数都在哪里设置?我确实阅读了BalusC的tutorial - 但没有提到StoreLocation(Google也不是很有帮助either)。 - 处理这种情况的更专业的方法是什么 - 包括将照片保留在Webroot之外 - 但使用glassfish提供的设施(如果它确实提供)? - 即使p1打印得很好,也难以理解(它似乎没有覆盖toString())。

如果您对如何重命名照片等内容感兴趣(这个sessionID是正确的吗?-还要检查时间技巧),请参考以下提示:

if (request.getParameter("save") != null) {
    long time = System.currentTimeMillis();
    String path = "images/upload/" + session.getId() + time + ".jpg";
    String outputpath = this.getServletContext().getRealPath(path);
    // store photo
    InputStream is = p1.getInputStream();
    createPhoto(is, outputpath);
    // etc
}

类StoreLocation的完全限定名称是什么?对我来说看起来不太熟悉。 - gerrytan
@gerrytan:不是一个类 - 只是在 Parts 的 toString() 中打印输出 - 我很快会更新问题 - 我认为我可以回答其中的一些问题 - 我现在只是太忙了。 - Mr_and_Mrs_D
2个回答

0

良好的实践是选择一个文件系统上的路径来上传照片。通常,此路径被编程为可通过Java系统属性进行配置(例如:通过在JVM参数中传递-Dcom.mycompany.uploadPath=/path/to/photos/dir系统属性)。

您还可以使用Java系统属性查找特定于环境的路径:user.diruser.home等。请参见Java SE教程上的系统属性。或者使用glassfish相对路径,请参见glassfish系统属性

一旦您引用了Part,就只需要进行文件IO以将上传的文件复制到此上传路径中,例如:

Part part = // obtain part somehow..
String photoFileName = // build a file name somehow..
InputStream photoInputStream = part.getInputStream();
FileOutputStream photoOutputStream = new FileOutputStream(System.getProperty("com.mycompany.uploadPath") + File.separator + photoFileName);
IOUtils.copy(photoInputStream, photoOutputStream);
// close streams here...

上面的代码使用apache IOUtils是为了方便,但你可以自己编写复制方法。你还应该添加异常处理方法。


看一下我的回答 - 我的主要关注点是移动(而不是复制)文件 - 并找出所有那些Glassfish垃圾的含义。 - Mr_and_Mrs_D

0
StoreLocation 是什么?这些 glassfish uploads 有多临时?所有这些参数都在哪里设置的?

StoreLocation 只是 FileItem 数据临时存储位置的 java.io.File 对象。位于 javax.servlet.context.tempdir 中,默认为 %GLASSFISH_HOME%\domains\domain1\generated\jsp\webApp。这些上传文件与其他任何临时文件一样 (文件的生命周期与 FileItem 实例的生命周期绑定;当实例被垃圾回收时,文件将被删除 - 来自 这里)。还没有成功通过编程方式更改 javax.servlet.context.tempdir 的值 (请评论) - 它是 sun-web.xml 的 sun-web-app 元素tempdir 属性。

有没有更专业的方式来处理这种情况 - 包括将照片保存在Webroot之外,但使用Glassfish提供的设施(如果它确实提供)?
更专业的方法是使用Part.write()将文件“移动”到所需位置。由于Glassfish的实现,您无法向write提供绝对路径 - 这是一项繁琐的任务。我在这里提出了问题。
至于要保存文件的位置:https://dev59.com/K2Ml5IYBdhLWcg3wJD9S#18664715 这是用于保存文件的方法 - 要从应用程序之外的位置提供服务,您需要在sun-web.xml(或glassfish-web.xml)中定义“alternatedocroot”属性。

即使p1打印得如此完美,我也无法理解(似乎它没有覆盖toString())

没错 它确实这样做

对于如何重命名照片等感兴趣的提示(这个sessionID的事情是正确的吗?-还要检查时间技巧)

不,不是 - 我倾向于使用 File#createTempFile() - 无论如何,这是一个不同的问题,已经在这里提问了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接