This commit is contained in:
parent
5875db6899
commit
6f85901356
2 changed files with 256 additions and 0 deletions
163
src/main/java/jp/sf/fess/filter/FessEncodingFilter.java
Normal file
163
src/main/java/jp/sf/fess/filter/FessEncodingFilter.java
Normal file
|
@ -0,0 +1,163 @@
|
|||
package jp.sf.fess.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.codec.DecoderException;
|
||||
import org.apache.commons.codec.net.URLCodec;
|
||||
import org.codelibs.core.util.StringUtil;
|
||||
import org.seasar.extension.filter.EncodingFilter;
|
||||
|
||||
public class FessEncodingFilter extends EncodingFilter {
|
||||
public static String ENCODING_MAP = "encoding-map";
|
||||
|
||||
protected Map<String, String> encodingMap = new ConcurrentHashMap<>();
|
||||
|
||||
protected String encoding;
|
||||
|
||||
protected ServletContext servletContext;
|
||||
|
||||
protected URLCodec urlCodec = new URLCodec();
|
||||
|
||||
@Override
|
||||
public void init(final FilterConfig config) throws ServletException {
|
||||
super.init(config);
|
||||
servletContext = config.getServletContext();
|
||||
|
||||
encoding = config.getInitParameter(ENCODING);
|
||||
if (encoding == null) {
|
||||
encoding = DEFAULT_ENCODING;
|
||||
}
|
||||
|
||||
// ex. sjis:Shift_JIS,eucjp:EUC-JP
|
||||
final String value = config.getInitParameter(ENCODING_MAP);
|
||||
if (StringUtil.isNotBlank(value)) {
|
||||
final String[] encodingPairs = value.split(",");
|
||||
for (final String pair : encodingPairs) {
|
||||
final String[] encInfos = pair.trim().split(":");
|
||||
if (encInfos.length == 2) {
|
||||
encodingMap.put("/" + encInfos[0] + "/", encInfos[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(final ServletRequest request,
|
||||
final ServletResponse response, final FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
final HttpServletRequest req = (HttpServletRequest) request;
|
||||
final String servletPath = req.getServletPath();
|
||||
for (final Map.Entry<String, String> entry : encodingMap.entrySet()) {
|
||||
final String path = entry.getKey();
|
||||
if (servletPath.startsWith(path)) {
|
||||
req.setCharacterEncoding(entry.getValue());
|
||||
final StringBuilder locationBuf = new StringBuilder(1000);
|
||||
final String contextPath = servletContext.getContextPath();
|
||||
locationBuf.append(StringUtil.isBlank(contextPath) ? "/"
|
||||
: contextPath);
|
||||
locationBuf.append(servletPath.substring(path.length()));
|
||||
boolean append = false;
|
||||
final Map<String, String[]> parameterMap = new HashMap<>();
|
||||
parameterMap.putAll(req.getParameterMap());
|
||||
parameterMap.putAll(getParameterMapFromQueryString(req,
|
||||
entry.getValue()));
|
||||
for (final Map.Entry<String, String[]> paramEntry : parameterMap
|
||||
.entrySet()) {
|
||||
final String[] values = paramEntry.getValue();
|
||||
if (values == null) {
|
||||
continue;
|
||||
}
|
||||
final String key = paramEntry.getKey();
|
||||
for (final String value : values) {
|
||||
if (append) {
|
||||
locationBuf.append('&');
|
||||
} else {
|
||||
locationBuf.append('?');
|
||||
append = true;
|
||||
}
|
||||
locationBuf.append(urlCodec.encode(key, encoding));
|
||||
locationBuf.append('=');
|
||||
locationBuf.append(urlCodec.encode(value, encoding));
|
||||
}
|
||||
|
||||
}
|
||||
final HttpServletResponse res = (HttpServletResponse) response;
|
||||
res.sendRedirect(locationBuf.toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
super.doFilter(request, response, chain);
|
||||
}
|
||||
|
||||
protected Map<String, String[]> getParameterMapFromQueryString(
|
||||
final HttpServletRequest request, final String enc)
|
||||
throws IOException {
|
||||
final String queryString = request.getQueryString();
|
||||
if (StringUtil.isNotBlank(queryString)) {
|
||||
return parseQueryString(queryString, enc);
|
||||
} else {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, String[]> parseQueryString(final String queryString,
|
||||
final String enc) throws IOException {
|
||||
final Map<String, List<String>> paramListMap = new HashMap<>();
|
||||
final String[] pairs = queryString.split("&");
|
||||
try {
|
||||
for (final String pair : pairs) {
|
||||
final int pos = pair.indexOf('=');
|
||||
if (pos >= 0) {
|
||||
final String key = urlCodec.decode(pair.substring(0, pos),
|
||||
enc);
|
||||
List<String> list = paramListMap.get(key);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
paramListMap.put(key, list);
|
||||
}
|
||||
if (pos + 1 < pair.length()) {
|
||||
list.add(urlCodec.decode(pair.substring(pos + 1), enc));
|
||||
} else {
|
||||
list.add(StringUtil.EMPTY);
|
||||
}
|
||||
} else {
|
||||
final String key = urlCodec.decode(pair, enc);
|
||||
List<String> list = paramListMap.get(key);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
paramListMap.put(key, list);
|
||||
}
|
||||
list.add(StringUtil.EMPTY);
|
||||
}
|
||||
}
|
||||
} catch (DecoderException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
final Map<String, String[]> paramMap = new HashMap<>(
|
||||
paramListMap.size());
|
||||
for (final Map.Entry<String, List<String>> entry : paramListMap
|
||||
.entrySet()) {
|
||||
final List<String> list = entry.getValue();
|
||||
paramMap.put(entry.getKey(), list.toArray(new String[list.size()]));
|
||||
}
|
||||
return paramMap;
|
||||
}
|
||||
}
|
93
src/test/java/jp/sf/fess/filter/FessEncodingFilterTest.java
Normal file
93
src/test/java/jp/sf/fess/filter/FessEncodingFilterTest.java
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright 2009-2014 the CodeLibs Project and the Others.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package jp.sf.fess.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import org.seasar.extension.unit.S2TestCase;
|
||||
|
||||
public class FessEncodingFilterTest extends S2TestCase {
|
||||
public void test_normal() throws IOException {
|
||||
FessEncodingFilter filter = new FessEncodingFilter();
|
||||
Map<String, String[]> paramMap;
|
||||
|
||||
paramMap = filter.parseQueryString("a=1", "UTF-8");
|
||||
assertEquals(1, paramMap.size());
|
||||
assertEquals("1", paramMap.get("a")[0]);
|
||||
|
||||
paramMap = filter.parseQueryString("a=1&b=2", "UTF-8");
|
||||
assertEquals(2, paramMap.size());
|
||||
assertEquals("1", paramMap.get("a")[0]);
|
||||
assertEquals("2", paramMap.get("b")[0]);
|
||||
|
||||
paramMap = filter.parseQueryString("a=111&b=222&c=333", "UTF-8");
|
||||
assertEquals(3, paramMap.size());
|
||||
assertEquals("111", paramMap.get("a")[0]);
|
||||
assertEquals("222", paramMap.get("b")[0]);
|
||||
assertEquals("333", paramMap.get("c")[0]);
|
||||
|
||||
paramMap = filter.parseQueryString("a=1&b=2&c=3&a=2", "UTF-8");
|
||||
assertEquals(3, paramMap.size());
|
||||
assertEquals("1", paramMap.get("a")[0]);
|
||||
assertEquals("2", paramMap.get("a")[1]);
|
||||
assertEquals("2", paramMap.get("b")[0]);
|
||||
assertEquals("3", paramMap.get("c")[0]);
|
||||
|
||||
}
|
||||
|
||||
public void test_missing() throws IOException {
|
||||
FessEncodingFilter filter = new FessEncodingFilter();
|
||||
Map<String, String[]> paramMap;
|
||||
|
||||
paramMap = filter.parseQueryString("a=", "UTF-8");
|
||||
assertEquals(1, paramMap.size());
|
||||
assertEquals("", paramMap.get("a")[0]);
|
||||
|
||||
paramMap = filter.parseQueryString("a", "UTF-8");
|
||||
assertEquals(1, paramMap.size());
|
||||
assertEquals("", paramMap.get("a")[0]);
|
||||
|
||||
paramMap = filter.parseQueryString("=1", "UTF-8");
|
||||
assertEquals(1, paramMap.size());
|
||||
assertEquals("1", paramMap.get("")[0]);
|
||||
|
||||
paramMap = filter.parseQueryString("=", "UTF-8");
|
||||
assertEquals(1, paramMap.size());
|
||||
assertEquals("", paramMap.get("")[0]);
|
||||
|
||||
}
|
||||
|
||||
public void test_decode() throws IOException {
|
||||
FessEncodingFilter filter = new FessEncodingFilter();
|
||||
Map<String, String[]> paramMap;
|
||||
|
||||
paramMap = filter.parseQueryString("a=%E3%83%86%E3%82%B9%E3%83%88",
|
||||
"UTF-8");
|
||||
assertEquals(1, paramMap.size());
|
||||
assertEquals("テスト", paramMap.get("a")[0]);
|
||||
|
||||
paramMap = filter.parseQueryString("a=%A5%C6%A5%B9%A5%C8", "EUC-JP");
|
||||
assertEquals(1, paramMap.size());
|
||||
assertEquals("テスト", paramMap.get("a")[0]);
|
||||
|
||||
paramMap = filter.parseQueryString("a=%83e%83X%83g", "Shift_JIS");
|
||||
assertEquals(1, paramMap.size());
|
||||
assertEquals("テスト", paramMap.get("a")[0]);
|
||||
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue