科技时代新浪首页 > 科技时代 > 学园 > 正文

使用JSF和MyFaces实现文件上载(3)


http://www.sina.com.cn 2005年08月18日 08:48 天极yesky

  文/陶刚编译

    示例应用程序

  前面的部分介绍了是MyFaces如何在通用文件上载的帮助下支持文件上载的。现在我们来看一个实际的利用了这种特性的应用程序。JSF窗体(MyForm.jsp)让用户选择一个文件和一个报文摘要算法,后台bean( MyBean.java)使用这个算法计算出一个散列值,显示在另外一个web页面(MyResult.jsp)中。这些页面和后台bean通过一个JSF配置文件(faces-config.xml)结合在一起。

  MyForm.jsp页面

  这个JSF窗体使用了MyFaces的<x:inputFileUpload>标记,同时还使用了其它一些标准的JSF标记来呈现标签、消息、包含报文摘要算法的下拉列表、使用JSF表达式(#{myBean.processMyFile})指定了处理被上载文件的操作方法的命令按钮:

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://myfaces.apache.org/extensions" prefix="x"%>

<f:view>
<h:form id="MyForm" enctype="multipart/form-data" >
 <h:messages globalOnly="true" styleClass="message"/>
 <h:panelGrid columns="3" border="0" cellspacing="5">
 <h:outputLabel for="myFileId" value="File: "/>
 <x:inputFileUpload id="myFileId" value="#{myBean.myFile}" storage="file" required="true"/>
 <h:message for="myFileId"/>
 <h:outputLabel for="myParamId" value="Param: "/>
 <h:selectOneMenu id="myParamId" value="#{myBean.myParam}" required="true">
 <f:selectItem itemLabel="" itemValue=""/>
 <f:selectItem itemLabel="MD5" itemValue="MD5"/>
 <f:selectItem itemLabel="SHA-1" itemValue="SHA-1"/>
 <f:selectItem itemLabel="SHA-256" itemValue="SHA-256"/>
 <f:selectItem itemLabel="SHA-384" itemValue="SHA-384"/>
 <f:selectItem itemLabel="SHA-512" itemValue="SHA-512"/>
</h:selectOneMenu>
<h:message for="myParamId"/>

<h:outputText value=" "/>
<h:commandButton value="Submit"
action="#{myBean.processMyFile}"/>
<h:outputText value=" "/>

</h:panelGrid>
</h:form>
</f:view>

  MyBean类

  后台bean拥有三个属性:myFile、myParam和myResult。前面已经解释了myFile属性的角色。它让你获取被上载文件的内容和文件名、文件大小、内容类型。myParam属性的值是报文摘要算法。myResult属性将保存processMyFile()方法执行之后的散列值。MyBean类为自己的所有属性提供了get和set方法:

package com.devsphere.articles.jsfupload;

import org.apache.myfaces.custom.fileupload.UploadedFile;
...
public class MyBean {
 private UploadedFile myFile;
 private String myParam;
 private String myResult;

 public UploadedFile getMyFile() {
  return myFile;
 }

 public void setMyFile(UploadedFile myFile) {
  this.myFile = myFile;
 }

 public String getMyParam() {
  return myParam;
 }

 public void setMyParam(String myParam) {
  this.myParam = myParam;
 }

 public String getMyResult() {
  return myResult;
 }

 public void setMyResult(String myResult) {
  this.myResult = myResult;
 }
 ...
}

  processMyFile()通过一个输入流获取被上载文件的内容,这个输入流是通过myFile.getInputStream()获得的。散列值是在java.security.MessageDigest的帮助下计算出来的,然后把它转换为字符串,这样就可以被myResult属性访问了:

package com.devsphere.articles.jsfupload;
...
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import java.io.*;

public class MyBean {
 ...
 public String processMyFile() {
  try {
   MessageDigest md= MessageDigest.getInstance(myParam);
   InputStream in = new BufferedInputStream(
   myFile.getInputStream());
   try {
    byte[] buffer = new byte[64 * 1024];
    int count;
    while ((count = in.read(buffer)) > 0)
     md.update(buffer, 0, count);
  } finally {
   in.close();
  }
  byte hash[] = md.digest();
  StringBuffer buf = new StringBuffer();
  for (int i = 0; i < hash.length; i++) {
   int b = hash[i] & 0xFF;
   int c = (b >> 4) & 0xF;
   c = c < 10 ? ’0’ + c : ’A’ + c - 10;
   buf.append((char) c);
   c = b & 0xF;
   c = c < 10 ? ’0’ + c : ’A’ + c - 10;
   buf.append((char) c);
  }
  myResult = buf.toString();
  return "OK";
 } catch (Exception x) {
  FacesMessage message = new FacesMessage(
  FacesMessage.SEVERITY_FATAL,
  x.getClass().getName(), x.getMessage());
  FacesContext.getCurrentInstance().addMessage(null, message);
  return null;
 }
}

}

  faces-config.xml文件

  JSF配置文件把后台bean定义在request作用域中,并且指定了一个导航规则:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE faces-config PUBLIC
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

<faces-config>

<managed-bean>
<managed-bean-name>myBean</managed-bean-name>
<managed-bean-class>
com.devsphere.articles.jsfupload.MyBean
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>

<navigation-rule>
<from-view-id>/MyForm.jsp</from-view-id>
<navigation-case>
<from-outcome>OK</from-outcome>
<to-view-id>/MyResult.jsp</to-view-id>
</navigation-case>
</navigation-rule>

</faces-config>

  MyResult.jsp页面

  这个web页面显示了被上载文件的一些信息:

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

<f:view>

<h:panelGrid columns="2" border="0" cellspacing="5">

<h:outputText value="FileName:"/>
<h:outputText value="#{myBean.myFile.name}"/>

<h:outputText value="FileSize:"/>
<h:outputText value="#{myBean.myFile.size}"/>

<h:outputText value="Param:"/>
<h:outputText value="#{myBean.myParam}"/>

<h:outputText value="Result:"/>
<h:outputText value="#{myBean.myResult}"/>

</h:panelGrid>

</f:view>

  被显示的文件名可能带有客户端文件系统的完整路径,如下所示:

使用JSF和MyFaces实现文件上载(3)
图2:结果页面产生的输出信息

  总结

  在很多情况下,用户需要通过浏览器上载文件,但是在服务器端却没有处理这些文件的理想方法。把文件的内容保存在内存中对于小型文件来说是可以接受的,但是把被上载的文件存储在临时文件中使这种情况变复杂了。MyFaces让你能够选择一个适合应用程序需求的解决方案,但是这个框架组件也有一些小问题。当你不再需要临时文件的时候,它无法让你删除它们;文件名有时候带有文件路径;当用户上载过大的文件的时候也没有警告信息。这些缺陷是可以修补的,因为我们可以使用源代码,而且本文就介绍了MyFaces代码可以改进的一些的地方。无论如何,对于多数应用程序来说,MyFaces不做修改就合乎需求。本文的例子是使用JSF 1.1.01、MyFaces 1.0.9和通用文件上载1.0环境测试的。

[上一页] [1] [2] [3]


  爱问(iAsk.com)


评论】【应用软件论坛】【收藏此页】【 】【多种方式看新闻】【下载点点通】【打印】【关闭




科技时代意见反馈留言板 电话:010-82628888-5828   欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

Copyright © 1996 - 2005 SINA Inc. All Rights Reserved

版权所有 新浪网