How ask a browser to not store cache Java EE/Tomcat - caching

I want to my browser not to store cache, when I update the content of my server I always have the first version of a document.
But when erase cache on my browser everything's ok.
Is there anyway to tell the browser not to store cache when running my webApp ?
I am using Java EE (JSPs) and Apache Tomcat Server.

You can use a ServletFilter to ensure that the HTTP response contains headers to instruct browsers not to cache:
public class NoCachingFilter implements Filter {
public void init(FilterConfig filterConfig) {
}
public void destroy() {
}
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Cache-Control", "no-cache");
httpResponse.setDateHeader("Expires", 0);
httpResponse.setHeader("Pragma", "no-cache");
httpResponse.setDateHeader("Max-Age", 0);
chain.doFilter(request, response);
}
}
and then configure the web.xml to use that filter for all requests:
<filter>
<filter-name>NoCachingFilter</filter-name>
<filter-class>my.pkg.NoCachingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>NoCachingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Related

Spring Boot - Download WSDL using ?WSDL

I created a webservice using Spring Boot using the steps defined hereWhen I try to download the wsdl , I am having to use .wsdl in the url. However when I use ?wsdl , the wsdl is not getting downloaded. How can I rewrite the url to download the wsdl when I use ?wsdl in the url?
I use this filter to be able to acces wsdl with Spring styled .wsdl as well as ?wsdl:
public class WsdRequestCompatibilityFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if ("GET".equals(request.getMethod()) && "wsdl".equalsIgnoreCase(request.getQueryString())) {
request.getSession().getServletContext().getRequestDispatcher(request.getRequestURI() + ".wsdl").forward(request, response);
} else {
filterChain.doFilter(request, response);
}
}
}
You need to register this as been named wsdlRequestCompatibilityFilter and add folowing config to your web.xml:
<filter>
<filter-name>wsdlRequestCompatibilityFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>wsdlRequestCompatibilityFilter</filter-name>
<url-pattern>/ws/*</url-pattern>
</filter-mapping>

Extending SpringBootWebSecurityConfiguration with custom HttpSecurity configuration

I am trying to gain a better understanding of the auto-configuration of spring boot. In particular I need to add some custom spring security configuration to disable authentication for HTTP OPTIONS verbs in order to get my CORS requests working.
Without any custom configuration by default the SpringBootWebSecurityConfiguration is loaded by Spring Boot's auto-configuration.
What I would like to do is to keep using this auto-configuration but add some additional http configuration. I tried this:
#Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
Logger logger = LogManager.getLogger (SecurityConfiguration.class);
#Override
protected void configure (HttpSecurity http) throws Exception {
logger.info ("--- ALLOW all HTTP OPTIONS Requests");
http.authorizeRequests ().antMatchers (HttpMethod.OPTIONS, "*//**").permitAll ();
}
}
But this does not work as excepted. When I debug through SpringBootWebSecurityConfiguration and also the above code, I can see that both my configure-method and springs auto-configuration are executed but it looks like my http-configuration takes precedence.
So does that mean the auto-configuration is available only in an all-or-nothing kind of way? Or can I use the the auto-configuration but still extend it with some custom antMatcher?
What is the best-practice for this scenario?
You could create a new servlet filter and place it before the Spring security filter. For example:
#Component("CORSFilter")
public class CORSFilter implements Filter {
public void doFilter(
ServletRequest req,
ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Origin", "THE_HOST_YOU_WANT_TO_ALLOW_HERE");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, PUT, PATCH, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers",
"origin, content-type, accept, x-requested-with, authorization");
if (request.getMethod().equals("OPTIONS")) {
try {
response.getWriter().print("OK");
response.getWriter().flush();
} catch (IOException e) {
//...
}
} else {
chain.doFilter(req, res);
}
}
public void init(FilterConfig filterConfig) {
//...
}
public void destroy() {
//...
}
}
and then add this to your web.xml (or configure in your WebInitializer if you are using Java config only):
<filter>
<filter-name>CORSFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>contextAttribute</param-name>
<param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.[YOUR_SERVLET_NAME]</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CORSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The reason you cannot do it is you are missing the annotation #EnableWebSecurity, have a look at the javadoc:
* Add this annotation to an {#code #Configuration} class to have the Spring Security
* configuration defined in any {#link WebSecurityConfigurer} or more likely by extending
* the {#link WebSecurityConfigurerAdapter} base class and overriding individual methods:

SpringMVC Session Timeout - Redirect to a Special JSP

I've looked everywhere but haven't found a simple solution.
We have a special JSP, timeout.jsp, that needs to be shown whenever a SpringMVC module intercepts an invalid session action. The timeout is already configured in web.xml and works correctly.
Previously in Struts, it was a matter of defining a forward and intercepting dispatchMethod,
<forward name="sessionTimeout" path="/WEB-INF/timeout.jsp" redirect="false" />
#Override
protected ActionForward dispatchMethod(final ActionMapping mapping, final ActionForm form,
final HttpServletRequest request, final HttpServletResponse response, final String name)
throws Exception {
//...
if (!isSessionValid())
return mapping.findForward("sessionTimeout");
}
But how would you implement a catch-all solution in SpringMVC modules?
All my SpringMVC URLs come to this servlet mapping, *.mvc:
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>*.mvc</url-pattern>
</servlet-mapping>
Anything that sends a URL with this pattern should be cross-checked for session validity and if invalid, redirected to timeout.jsp.
NOTE
The solution given here (https://stackoverflow.com/a/5642344/1005607) did not work:
<web-app>
<error-page>
<exception-type>org.springframework.web.HttpSessionRequiredException</exception-type>
<location>/index.jsp</location>
</error-page>
</web-app>
There's a NullPointerException in my SpringMVC Form Code even before any kind of SessionRequiredException, as soon as I try to access the session. I need to globally protect against these NullPointerExceptions.
My final solution: an old-fashioned Filter. It works for me, no other simple solution available.
web.xml
<filter>
<filter-name>spring_mvc_controller_filter</filter-name>
<filter-class>myapp.mypackage.SpringMVCControllerFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>spring_mvc_controller_filter</filter-name>
<url-pattern>*.mvc</url-pattern>
</filter-mapping>
SpringMVCControllerFilter
public class SpringMVCControllerFilter implements Filter
{
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpSession session = request.getSession(false);
if (session.isValid() && !session.isNew())
{
chain.doFilter(request, response);
}
else
{
request.getRequestDispatcher("/WEB-INF/jsp/sessionTimeout.jsp").forward(request, response);
}
}
#Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}

Aspect to wrap around log entries

I am using the sl4j Logger throughout my spring application.
I would like to append a custom string to all log entries (info/trace/debug etc) done throughout the application. This would ideally be done using an Aspect however I am not sure what format the aspect would have. I am assuming something along the lines of
#Around("org.slf4j.Logger.info(*)")
however i cannot find any reliable way to make this apply to all the methods involved correctly.
As #PavelHoral mentioned The following was the solution using MDC
Create your own filter
import org.slf4j.MDC;
import javax.servlet.*;
import java.io.IOException;
public class MDCLoggingFilter implements Filter {
#Override
public void init(final FilterConfig filterConfig) throws ServletException {}
#Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
MDC.put("myKey", "myValue");
try {
chain.doFilter(request, response);
} finally {
// remove the key once you are done with it
MDC.remove("myKey");
}
}
#Override
public void destroy() {}
}
Then add your filter to your web.xml as follows
<filter>
<filter-name>mdcLoggingFilter</filter-name>
<filter-class>path.to.MDCLoggingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>mdcLoggingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
However, this does not seem to be applying to all my messages. some warnings seem to not be displaying the field. currently investigating.

Get Parameter Encoding

I have a problem using spring mvc and special chars in a GET request. Consider the following method:
#RequestMapping("/update")
public Object testMethod(#RequestParam String name) throws IOException {
}
to which I send a GET request with name containing an "ä" (german umlaut), for instance. It results in spring receiving "ä" because the browser maps "ä" to %C3%A4.
So, how can I get the correct encoded string my controller?
Thanks for your help!
You're having this problem, because the request differentiates between body encoding and URI encoding. A CharacterEncodingFilter sets the body encoding, but not the URI encoding.
You need to set URIEncoding="UTF-8" as an attribute in all your connectors in your Tomcat server.xml. See here: http://tomcat.apache.org/tomcat-6.0-doc/config/ajp.html
Or, alternatively, you can set useBodyEncodingForURI="True".
If you're using the maven tomcat plugin, just add this parameter:
mvn -Dmaven.tomcat.uriEncoding=UTF-8 tomcat:run
What about this? Could it help?
In your web.xml:
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.example.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<servlet-name>dispatcher</servlet-name>
</filter-mapping>
com.example.CharacterEncodingFilter:
public class CharacterEncodingFilter implements Filter {
protected String encoding;
public void init(FilterConfig filterConfig) throws ServletException {
encoding = filterConfig.getInitParameter("encoding");
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
request.setCharacterEncoding(encoding);
filterChain.doFilter(servletRequest, servletResponse);
}
public void destroy() {
encoding = null;
}
}

Resources