Читать «Java 7 (Наиболее полное руководство)» онлайн - страница 421
Ильдар Шаукатович Хабибуллин
Организация цепочки достается на долю контейнера, интерфейс FilterChain описывает только один метод
public void doFilter(ServletRequest req, ServletResponse resp);
Чтобы передать управление фильтру, следующему в цепочке, фильтр должен просто обратиться к этому методу, передав ему измененные объекты req и resp.
Приведем пример фильтра. Русскоязычному программисту постоянно приходится думать о правильной кодировке кириллицы. Параметры запроса идут от браузера чаще всего в MIME-типе application/x-www-form-urlencoded, использующем байтовую кодировку, принятую по умолчанию на машине клиента. Эта кодировка должна указываться в заголовке Content-Type, например:
Content-Type: application/x-www-form-urlencoded;charset=windows-1251
Но, как правило, браузер не посылает этот заголовок Web-серверу. В таком случае встает задача определить кодировку параметров запроса и заслать ее в метод setCharacterEncoding(String), чтобы метод getParameter(String) правильно перевел значение параметра в Unicode. Эту задачу должен решать метод getCharacterEncoding(), но он чаще всего реализован так, что просто берет кодировку из заголовка Content-Type. Листинг 26.7 показывает схему такой реализации в одной из прежних версий контейнера сервлетов Tomcat. Оцените качество кодирования и посмотрите, почему, используя эту версию Tomcat, между словом "charset" и знаком равенства нельзя оставлять пробелы.
Кстати говоря, некоторые контейнеры сервлетов не воспринимают кодировку, если оставлены пробелы между точкой с запятой и словом "charset".
Листинг 26.7. Фильтр определения кодировки параметров запроса
import java.io.*;import javax.servlet.*; import j avax.servlet.annotation.*;
@WebFilter(
urlPatterns={"/*"}, servletNames={""}
initParams={ @WebInitParam(name="simpleParam", value="paramValue") }
)
public class SetCharEncFilter implements Filter{ protected String enc; protected FilterConfig fc;
@Override
public void init(FilterConfig conf) throws ServletException{ fc = conf;
enc = conf.getInitParameter("encoding");
}
@Override
public void doFilter(ServletRequest req,
ServletResponse resp,
FilterChain chain)
throws IOException, ServletException{
String encoding = selectEncoding(req); if (encoding != null) req.setCharacterEncoding(encoding);
chain.doFilter(req, resp);
}
protected String selectEncoding(ServletRequest req){ String charEncoding =
getCharsetFromContentType(req.getContentType()); return (charEncoding == null) ? enc : charEncoding;
}
// From org.apache.tomcat.util.RequestUtil.java
public static String getCharsetFromContentType(String type){ if (type == null) { return null;
}
int semi = type.indexOf(";");
if (semi == -1) { return null;
String afterSemi = type.substring(semi + 1); int charsetLocation = afterSemi.indexOf("charset="); if (charsetLocation == -1) { return null;
}
String afterCharset = afterSemi.substring(charsetLocation + 8);
String encoding = afterCharset.trim(); return encoding; }
@Override
public void destroy(){ enc = null; fc = null;