Читать «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;