注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

流星永恒的博客

JSF,Facelets,Rich(Prime)Faces,和java的笔记

 
 
 

日志

 
 

Single file upload using JSF2 and Servlet 3.0  

2009-12-29 16:48:23|  分类: jsf2.0 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

JSF2.0 SUN-RI 没有上传组件,所以得自己写个上传的组件。JSF2.0以后,开发组件变得非常简单,不再像1.1和1.2那样的繁琐。

考虑到上传组件和输入组件在html中只是type不同,所以我们继承UIInput组件来写上传组件。

也许你不相信下面这点代码就是一个组件了。

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com;

import java.io.File;
import java.io.IOException;
import javax.el.ValueExpression;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.FacesComponent;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.servlet.http.HttpServletRequest;

/**
 *
 * @author Daniel Yang
 */
@FacesComponent(value = "fileUpload")
public class FileUpload extends UIInput{

    @Override
    public String getFamily() {
        return "upload";
    }

    @Override
    public void encodeEnd(FacesContext context) throws IOException {
  ResponseWriter responseWriter = context.getResponseWriter();
  String clientId = getClientId(context);  //把它写成html文件输入组件,简单!!
  responseWriter.startElement("input", null);
  responseWriter.writeAttribute("id", clientId, "id");
  responseWriter.writeAttribute("name", clientId, "clientId");
  responseWriter.writeAttribute("type", "file", "file");
  responseWriter.endElement("input");
  responseWriter.flush();
    }

    @Override
    public void decode(FacesContext context) {
  ExternalContext external = context.getExternalContext();
  HttpServletRequest request = (HttpServletRequest) external.getRequest();
  String clientId = getClientId(context);
            File file = (File) request.getAttribute(clientId);   //在Filter中我们上传了文件,并把文件设置到

                                                                            //httpServletRequest中,这里可以得到传给jsf的managedbean
            ValueExpression valueExpr = getValueExpression("value");
  if (valueExpr != null) {
   UIComponent component=getCurrentComponent(context);
                ((EditableValueHolder) component).setSubmittedValue(file);
   ((EditableValueHolder) component).setValid(true);
  }
 }
}

配置tag TLD,在WEB-INF下新建upload.tld文件

<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib xmlns="
http://java.sun.com/xml/ns/javaee"
 xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
 version="2.0">
 <namespace>http://www.acetech.com/fileUpload</namespace>
 <tag>
  <tag-name>fileUpload</tag-name>
  <component>
   <component-type>fileUpload</component-type>
  </component>
 </tag>
</facelet-taglib>

将配置包含到web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="
http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
      <context-param>
        <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
        <param-value>/WEB-INF/upload.tld</param-value>
    </context-param>
  <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.jsf</welcome-file>
    </welcome-file-list>
</web-app>

我们知道JSF1.1到现在的2.0都不能对附带MultiPart的httpServletRequest进行处理,所以要用Filter过滤MultiPart得到我们所需要的文件流进行处理,其他参数可以交给JSF处理了。

这里参考了apache fileupload的代码。

//其中配置了上传的路,还有mapping pattern,配置如下

@WebFilter(filterName = "FileUploadFilter", urlPatterns = {"/upload.jsf"},
initParams = { @WebInitParam(name="path", value="c:/uploadFile/") })

 

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.Part;

/**
 *
 * @author Daniel Yang
 */
@WebFilter(filterName = "FileUploadFilter", urlPatterns = {"/upload.jsf"},initParams = {
                        @WebInitParam(name="path", value="c:/uploadFile/")
                     })
public class FileUploadFilter implements Filter {
    private FilterConfig filterConfig = null;
    public FileUploadFilter() {
    }

    /**
     *
     * @param request The servlet request we are processing
     * @param response The servlet response we are creating
     * @param chain The filter chain we are processing
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain)
            throws IOException, ServletException {
        Throwable problem = null;
        try {
            if (!(request instanceof HttpServletRequest)) {
                chain.doFilter(request, response);
                return;
            }

            HttpServletRequest httpRequest = (HttpServletRequest) request;
            if (!FileUploadUtil.isMultipartContent(httpRequest)) {
    chain.doFilter(request, response);
    return;
   }
            Collection<Part> parts = null;
            try {
                parts = httpRequest.getParts();
                Iterator<Part> items = parts.iterator();
                final Map<String,String[]> paramMap = new HashMap<String, String[]>();
                while (items.hasNext()) {
                    Part part = items.next();
                    if(!"uploadFile".equals(part.getName())){//这里有局限性(组件的id必须为uploadFile)
                            String name = part.getName();
                            String[] values = (String[]) paramMap.get(name);
                            if (values == null) {
                                paramMap.put(name, new String[] {new BufferedReader(new InputStreamReader(part.getInputStream())).readLine()});
                    } else {
                        int length = values.length;
                        String[] newValues = new String[length + 1];
                        System.arraycopy(values, 0, newValues, 0, length);
                        newValues[length] = new BufferedReader(new InputStreamReader(part.getInputStream())).readLine();
                    }
                }else{
                        String fullFilename = null;
                        for (String str : part.getHeader("content-disposition").split(";")) {
                            if (str.trim().startsWith("filename")) {
                                fullFilename = str.substring(str.indexOf('=') + 1).trim().replace("\"", "");
                                break;
                            }
                        }
                 String path = getFilterConfig().getInitParameter("path");
                 String uploadedFileName = path+fullFilename.substring(fullFilename.lastIndexOf(File.separator)+1,fullFilename.length());
                        System.out.println("File:"+uploadedFileName);
                //write file to disk
                   InputStream is = part.getInputStream();
                   OutputStream os = new FileOutputStream(uploadedFileName);
                   byte[] buffer = new byte[2048];

                int read = 0;
                int count = 0;
                while((read=is.read(buffer))>0){
                    os.write(buffer, 0, read);
                    if(count==50){
                    os.flush();
                    count = 0;
                    }
                    count++;
                }
                os.close();
                is.close();
                 File uploadedFile = new File(uploadedFileName);
                 httpRequest.setAttribute(part.getName(),uploadedFile);
                 part.delete();
                }
                }
           
            chain.doFilter(new HttpServletRequestWrapper(httpRequest) {
                //inner methods passed as parameters
                @Override
                public Map<String, String[]> getParameterMap() {
                    return paramMap;
                }

                @Override
                public String[] getParameterValues(String name) {
                    Map<String, String[]> map = getParameterMap();
                    return (String[]) map.get(name);
                }

                @Override
                public String getParameter(String name) {
                    String[] params = getParameterValues(name);
                    if (params == null) {
                        return null;
                    }
                    return params[0];
                }

                @Override
                public Enumeration<String> getParameterNames() {
                    Map<String, String[]> map = getParameterMap();
                    return Collections.enumeration(map.keySet());
                }
            }, response);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Throwable t) {
            problem = t;
            t.printStackTrace();
        }

        // If there was a problem, we want to rethrow it if it is
        // a known type, otherwise log it.
        if (problem != null) {
            if (problem instanceof ServletException) {
                throw (ServletException) problem;
            }
            if (problem instanceof IOException) {
                throw (IOException) problem;
            }
            sendProcessingError(problem, response);
        }
    }

    /**
     * Return the filter configuration object for this filter.
     */
    public FilterConfig getFilterConfig() {
        return (this.filterConfig);
    }

    /**
     * Set the filter configuration object for this filter.
     *
     * @param filterConfig The filter configuration object
     */
    public void setFilterConfig(FilterConfig filterConfig) {
        this.filterConfig = filterConfig;
    }

    /**
     * Destroy method for this filter
     */
    public void destroy() {
    }


    /**
     * Return a String representation of this object.
     */
    @Override
    public String toString() {
        if (filterConfig == null) {
            return ("FileUploadFilter()");
        }
        StringBuffer sb = new StringBuffer("FileUploadFilter(");
        sb.append(filterConfig);
        sb.append(")");
        return (sb.toString());
    }

    private void sendProcessingError(Throwable t, ServletResponse response) {
        String stackTrace = getStackTrace(t);

        if (stackTrace != null && !stackTrace.equals("")) {
            try {
                response.setContentType("text/html");
                PrintStream ps = new PrintStream(response.getOutputStream());
                PrintWriter pw = new PrintWriter(ps);
                pw.print("<html>\n<head>\n<title>Error</title>\n</head>\n<body>\n"); //NOI18N

                // PENDING! Localize this for next official release
                pw.print("<h1>The resource did not process correctly</h1>\n<pre>\n");
                pw.print(stackTrace);
                pw.print("</pre></body>\n</html>"); //NOI18N
                pw.close();
                ps.close();
                response.getOutputStream().close();
            } catch (Exception ex) {
            }
        } else {
            try {
                PrintStream ps = new PrintStream(response.getOutputStream());
                t.printStackTrace(ps);
                ps.close();
                response.getOutputStream().close();
            } catch (Exception ex) {
            }
        }
    }

    public static String getStackTrace(Throwable t) {
        String stackTrace = null;
        try {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            t.printStackTrace(pw);
            pw.close();
            sw.close();
            stackTrace = sw.getBuffer().toString();
        } catch (Exception ex) {
        }
        return stackTrace;
    }

    public void log(String msg) {
        filterConfig.getServletContext().log(msg);
    }

    public void init(FilterConfig filterConfig) throws ServletException {
    }
}

编写managedbean

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com;

import java.io.File;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

/**
 *
 * @author Daniel Yang
 */
@ManagedBean(name="TestBean")
@RequestScoped
public class TestBean {
 private String msg;
 private File uploadFile;
    /** Creates a new instance of TestBean */
    public TestBean() {
    }

 

 

    public void upload(){
        System.out.println("uploading...");
        if(uploadFile==null){
            System.out.println("File is null");
            msg = "Error";
        }else{
            System.out.println(uploadFile.getAbsolutePath());
            //process file, it has existed in server disk.
            //TODO
            msg = uploadFile.getAbsolutePath();
        }
    }

    public File getUploadFile() {
        return uploadFile;
    }

    public void setUploadFile(File uploadFile) {
        this.uploadFile = uploadFile;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

书写upload.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ac="http://www.acetech.com/fileUpload">

.....

<!--这里的prependid必须设置为false--> 
<h:form id="uploadForm" prependId="false" enctype="multipart/form-data">

<!--这里的id必须为uploadFile,name不用写-->
<ac:fileUpload id="uploadFile" value="#{TestBean.uploadFile}"/><br/>
<h:commandButton id="uploadBution" action="#{TestBean.upload}"  value="Upload">
</h:commandButton>
</h:form>
<h:outputText id="out1" value="#{TestBean.msg}"/>

....

 效果图:

Single file upload using JSF2 and Servlet 3.0 - yyq2007aa - 流星永恒的博客

 

Single file upload using JSF2 and Servlet 3.0 - yyq2007aa - 流星永恒的博客

源代码已经上传(Netbeans 6.8)

http://d.download.csdn.net/down/1945857/yyq2008

 

  评论这张
 
阅读(901)| 评论(2)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018