Есть способ сделать это в Java (без возни с server.xml
)
Не работают:
protected static final String CHARSET_FOR_URL_ENCODING = "UTF-8";
String uname = request.getParameter("name");
System.out.println(uname);
// ÏηγÏÏÏÏη
uname = request.getQueryString();
System.out.println(uname);
// name=%CF%84%CE%B7%CE%B3%CF%81%CF%84%CF%83%CF%82%CE%B7
uname = URLDecoder.decode(request.getParameter("name"),
CHARSET_FOR_URL_ENCODING);
System.out.println(uname);
// ÏηγÏÏÏÏη // !!!!!!!!!!!!!!!!!!!!!!!!!!!
uname = URLDecoder.decode(
"name=%CF%84%CE%B7%CE%B3%CF%81%CF%84%CF%83%CF%82%CE%B7",
CHARSET_FOR_URL_ENCODING);
System.out.println("query string decoded : " + uname);
// query string decoded : name=τηγρτσςη
uname = URLDecoder.decode(new String(request.getParameter("name")
.getBytes()), CHARSET_FOR_URL_ENCODING);
System.out.println(uname);
// ÏηγÏÏÏÏη // !!!!!!!!!!!!!!!!!!!!!!!!!!!
Работы :
final String name = URLDecoder
.decode(new String(request.getParameter("name").getBytes(
"iso-8859-1")), CHARSET_FOR_URL_ENCODING);
System.out.println(name);
// τηγρτσςη
Сработало, но сломается, если кодировка по умолчанию! = Utf-8 - попробуйте это вместо этого (пропустите вызов decode (), в котором нет необходимости):
final String name = new String(request.getParameter("name").getBytes("iso-8859-1"),
CHARSET_FOR_URL_ENCODING);
Как я сказал выше, если server.xml
испорчен как в:
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1"
redirectPort="8443" URIEncoding="UTF-8"/>
(обратите внимание на URIEncoding="UTF-8"
) приведенный выше код будет нарушен (потому что getBytes("iso-8859-1")
должно читаться как getBytes("UTF-8")
). Так что для пуленепробиваемого решения вы должны получить значение атрибута URIEncoding
. К сожалению, это, похоже, зависит от контейнера - еще хуже для конкретной версии контейнера. Для Tomcat 7 вам понадобится что-то вроде:
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import org.apache.catalina.Server;
import org.apache.catalina.Service;
import org.apache.catalina.connector.Connector;
public class Controller extends HttpServlet {
// ...
static String CHARSET_FOR_URI_ENCODING; // the `URIEncoding` attribute
static {
MBeanServer mBeanServer = MBeanServerFactory.findMBeanServer(null).get(
0);
ObjectName name = null;
try {
name = new ObjectName("Catalina", "type", "Server");
} catch (MalformedObjectNameException e1) {
e1.printStackTrace();
}
Server server = null;
try {
server = (Server) mBeanServer.getAttribute(name, "managedResource");
} catch (AttributeNotFoundException | InstanceNotFoundException
| MBeanException | ReflectionException e) {
e.printStackTrace();
}
Service[] services = server.findServices();
for (Service service : services) {
for (Connector connector : service.findConnectors()) {
System.out.println(connector);
String uriEncoding = connector.getURIEncoding();
System.out.println("URIEncoding : " + uriEncoding);
boolean use = connector.getUseBodyEncodingForURI();
// TODO : if(use && connector.get uri enc...)
CHARSET_FOR_URI_ENCODING = uriEncoding;
// ProtocolHandler protocolHandler = connector
// .getProtocolHandler();
// if (protocolHandler instanceof Http11Protocol
// || protocolHandler instanceof Http11AprProtocol
// || protocolHandler instanceof Http11NioProtocol) {
// int serverPort = connector.getPort();
// System.out.println("HTTP Port: " + connector.getPort());
// }
}
}
}
}
И все же вам нужно настроить это для нескольких разъемов (проверьте закомментированные части). Тогда вы бы использовали что-то вроде:
new String(parameter.getBytes(CHARSET_FOR_URI_ENCODING), CHARSET_FOR_URL_ENCODING);
Тем не менее это может завершиться ошибкой ( IIUC ), если parameter = request.getParameter("name");
, декодированный с помощью CHARSET_FOR_URI_ENCODING, был поврежден, поэтому байты, которые я получаю с помощью getBytes (), не были оригинальными (вот почему iso-8859-1) используется по умолчанию - , это сохранит байты ). Вы можете избавиться от всего этого, вручную проанализировав строку запроса в строках:
URLDecoder.decode(request.getQueryString().split("=")[1],
CHARSET_FOR_URL_ENCODING);
Я все еще ищу место в документации, где упоминается, что request.getParameter("name")
вызывает URLDecoder.decode()
вместо возврата строки %CF%84%CE%B7%CE%B3%CF%81%CF%84%CF%83%CF%82%CE%B7
? Ссылка в источнике будет высоко ценится.
Также, как я могу передать в качестве значения параметра строку, скажем, %CE
? => см. Комментарий: parameter=%25CE