(2013/4/6 追記:PrimeFaces3.5では、そのままFileUploadFilterを使ってよいようです)
PrimeFacesでファイルアップロードするときは、FileUploadFilterというのを組み込まないといけないのだけど、それだけだとファイル以外のパラメータでの日本語が文字化けしてしまう。
ファイル名は化けないのだけど。
同じことで悩んでる人もいた。報告をしてるっぽい。
http://stackoverflow.com/questions/11190081/primefaces-fileupload-filter-with-utf8-characters-filter
Commons FileUploadがファイル以外のパラメータの値でエンコード変換してくれないのが悪いのだけど、そうも言ってられないので、対策する。
FileUploadFilterをまるっとコピーして、エンコード変換したMultipartRequestを渡すという作戦。ただ、ここでMultipartRequestのaddFormParamがprivateなので、publicになってる値の取得メソッドに細工した。
このフィルタの前に、SetCharacterEncodingFilterっぽいものでエンコーディング指定しておく必要がある。
とりあえずGlassFish3.1.2.2+PrimeFaces3.4.2で確認。
public class UtfFileUploadFilter implements Filter { private final static Logger logger = Logger.getLogger(FileUploadFilter.class.getName()); private final static String THRESHOLD_SIZE_PARAM = "thresholdSize"; private final static String UPLOAD_DIRECTORY_PARAM = "uploadDirectory"; private String thresholdSize; private String uploadDir; @Override public void init(FilterConfig filterConfig) throws ServletException { thresholdSize = filterConfig.getInitParameter(THRESHOLD_SIZE_PARAM); uploadDir = filterConfig.getInitParameter(UPLOAD_DIRECTORY_PARAM); if(logger.isLoggable(Level.FINE)) logger.fine("UtfFileUploadFilter initiated successfully"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest) request; String enc = httpServletRequest.getCharacterEncoding(); if(enc == null){ enc = "utf-8"; } final String encoding = enc; boolean isMultipart = ServletFileUpload.isMultipartContent(httpServletRequest); if(isMultipart) { if(logger.isLoggable(Level.FINE)) logger.fine("Parsing utf file upload request"); DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(); if(thresholdSize != null) { diskFileItemFactory.setSizeThreshold(Integer.valueOf(thresholdSize)); } if(uploadDir != null) { diskFileItemFactory.setRepository(new File(uploadDir)); } ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory); MultipartRequest multipartRequest; multipartRequest = new MultipartRequest(httpServletRequest, servletFileUpload){ String convert(String result){ if(result == null){ return result; } try { return new String(result.getBytes("8859_1"), encoding); } catch (UnsupportedEncodingException ex) { return result; } } @Override public String getParameter(String name) { return convert(super.getParameter(name)); } @Override public String[] getParameterValues(String name) { String[] values = super.getParameterValues(name); String[] result = new String[values.length]; for(int i = 0; i < values.length; ++i){ result[i] = convert(values[i]); } return result; } @Override public Map getParameterMap() { Map<String, String[]> params = super.getParameterMap(); Map<String, String[]> result = new HashMap<>(); for(Map.Entry<String, String[]> me : params.entrySet()){ String[] values = me.getValue(); String[] convvalues = new String[values.length]; for(int i = 0; i < values.length; ++i){ convvalues[i] = convert(values[i]); } result.put(me.getKey(), convvalues); } return result; } }; if(logger.isLoggable(Level.FINE)) logger.fine("File upload request parsed succesfully, " + "continuing with filter chain with a wrapped utf multipart request"); filterChain.doFilter(multipartRequest, response); } else { filterChain.doFilter(request, response); } } @Override public void destroy() { if(logger.isLoggable(Level.FINE)) logger.fine("Destroying utf FileUploadFilter"); } }