package at.gv.egovernment.moa.id.configuration.filter; import java.io.IOException; import java.nio.charset.Charset; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.ToStringBuilder; import lombok.extern.slf4j.Slf4j; /** * @author Thomas Knall */ @Slf4j public class EncodingFilter implements javax.servlet.Filter { private static final String SERVLET_INIT_PARAM_ENCODING = "encoding"; private static final String SERVLET_INIT_PARAM_SET_REQUEST_ENCODING = "setRequestEncoding"; private static final String SERVLET_INIT_PARAM_FORCE_REQUEST_ENCODING = "forceRequestEncoding"; private static final String SERVLET_INIT_PARAM_SET_RESPONSE_ENCODING = "setResponseEncoding"; private static final String SERVLET_INIT_PARAM_FORCE_RESPONSE_ENCODING = "forceResponseEncoding"; private static final boolean DEFAULT_SET_REQUEST_ENCODING_VALUE = true; private static final boolean DEFAULT_FORCE_REQUEST_ENCODING_VALUE = true; private static final boolean DEFAULT_SET_RESPONSE_ENCODING_VALUE = false; private static final boolean DEFAULT_FORCE_RESPONSE_ENCODING_VALUE = false; private String encoding = null; private boolean setRequestEncoding; private boolean forceRequestEncoding; private boolean setResponseEncoding; private boolean forceResponseEncoding; private boolean enabled = false; private boolean parseBooleanInitParameter(final FilterConfig filterConfig, String parameterName, boolean defaultValue) { String paramValue = filterConfig.getInitParameter(parameterName); if (paramValue == null) { return defaultValue; } paramValue = paramValue.trim(); if (paramValue.equalsIgnoreCase("true")) { return true; } else if (paramValue.equalsIgnoreCase("false")){ return false; } else { log.warn("Unknown value \"" + paramValue + "\" for init parameter \"" + parameterName + "\" detected. Should be \"true\" or \"false\". Using default value \"" + defaultValue + "\"."); return defaultValue; } } public void init(final FilterConfig filterConfig) throws ServletException { log.debug("Initializing encoding filter (" + getClass().getName() + ")."); // mandatory parameter encoding String desiredEncoding = filterConfig.getInitParameter(SERVLET_INIT_PARAM_ENCODING); if (StringUtils.isEmpty(desiredEncoding)) { log.warn("Unable to initialize encoding filter (" + getClass().getName() + "). Init parameter \"" + SERVLET_INIT_PARAM_ENCODING + "\" empty or not supplied."); } else if (!Charset.isSupported(desiredEncoding)) { log.warn("Unable to initialize encoding filter (" + getClass().getName() + "). Encoding \"" + desiredEncoding + "\" is not supported."); } else { this.encoding = desiredEncoding; this.enabled = true; this.setRequestEncoding = this.parseBooleanInitParameter(filterConfig, SERVLET_INIT_PARAM_SET_REQUEST_ENCODING, DEFAULT_SET_REQUEST_ENCODING_VALUE); this.forceRequestEncoding = this.parseBooleanInitParameter(filterConfig, SERVLET_INIT_PARAM_FORCE_REQUEST_ENCODING, DEFAULT_FORCE_REQUEST_ENCODING_VALUE); this.setResponseEncoding = this.parseBooleanInitParameter(filterConfig, SERVLET_INIT_PARAM_SET_RESPONSE_ENCODING, DEFAULT_SET_RESPONSE_ENCODING_VALUE); this.forceResponseEncoding = this.parseBooleanInitParameter(filterConfig, SERVLET_INIT_PARAM_FORCE_RESPONSE_ENCODING, DEFAULT_FORCE_RESPONSE_ENCODING_VALUE); log.debug("Encoding filter \"" + getClass().getName() + "\" configured: " + this.toString(true)); } } public String toString(boolean verbose) { if (verbose) { return new ToStringBuilder(this) .append(SERVLET_INIT_PARAM_ENCODING, this.encoding) .append(SERVLET_INIT_PARAM_SET_REQUEST_ENCODING, this.setRequestEncoding) .append(SERVLET_INIT_PARAM_FORCE_REQUEST_ENCODING, this.forceRequestEncoding) .append(SERVLET_INIT_PARAM_SET_RESPONSE_ENCODING, this.setResponseEncoding) .append(SERVLET_INIT_PARAM_FORCE_RESPONSE_ENCODING, this.forceResponseEncoding) .toString(); } else { return super.toString(); } } public void doFilter(ServletRequest request, ServletResponse response, final FilterChain filterChain) throws IOException, ServletException { if (this.enabled) { if (this.setRequestEncoding) { if (this.forceRequestEncoding) { log.trace("Forcing request encoding \"" + this.encoding + "\"."); request.setCharacterEncoding(this.encoding); } else if (request.getCharacterEncoding() == null) { log.trace("Request character encoding not set. Setting to \"" + this.encoding + "\"."); request.setCharacterEncoding(this.encoding); } } if (this.setResponseEncoding) { if (this.forceResponseEncoding) { log.trace("Forcing response encoding \"" + this.encoding + "\"."); response.setCharacterEncoding(this.encoding); } else if (response.getCharacterEncoding() == null) { log.trace("Response character encoding not set. Setting to \"" + this.encoding + "\"."); response.setCharacterEncoding(this.encoding); } } } filterChain.doFilter(request, response); } public void destroy() { } }