Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions docs/developer-guide/mapstore-migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,37 @@ In your project, you should update the `print-lib.version` property from version
+ <print-lib.version>2.3.3</print-lib.version>
```

### Update `web.xml` with cache control

MapStore 2025.02.00 introduces an improvement in cache management to prevent internal proxies and browsers from caching certain files, ensuring that updates are correctly applied.

To enable this improvement, the `web.xml` file (usually located in `java/web/`) has been updated.
If your custom project includes its own web.xml, make sure to update it by adding the following lines.

```xml
<!-- Cache management -->
<filter>
<filter-name>noCacheFilter</filter-name>
<filter-class>it.geosolutions.mapstore.filters.NoCacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>noCacheFilter</filter-name>
<url-pattern>/</url-pattern> <!-- index.html -->
</filter-mapping>
<filter-mapping>
<filter-name>noCacheFilter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>noCacheFilter</filter-name>
<url-pattern>*.json</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>noCacheFilter</filter-name>
<url-pattern>*.txt</url-pattern>
</filter-mapping>
```

### Removal of terrain from cfg.additionalLayers property using the new background selector

All contexts containing configuration for a `terrain` layer inside the `cfg.additionalLayers` property of the `Map` plugin should be updated as follow:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package it.geosolutions.mapstore.filters;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class NoCacheFilter implements Filter {

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {

HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1
httpResponse.setHeader("Pragma", "no-cache"); // HTTP 1.0
httpResponse.setDateHeader("Expires", 0); // Proxies

chain.doFilter(request, response);
}

@Override
public void init(FilterConfig filterConfig) throws ServletException { }

@Override
public void destroy() { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package it.geosolutions.mapstore.filters;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletResponse;

import static org.mockito.Mockito.*;

import static org.junit.Assert.fail;

public class NoCacheFilterTest {

private NoCacheFilter filter;

@Before
public void setUp() {
filter = new NoCacheFilter();
}

@Test
public void testDoFilterSetsNoCacheHeaders() throws IOException, ServletException {
ServletRequest request = mock(ServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
FilterChain chain = mock(FilterChain.class);

filter.doFilter(request, response, chain);

verify(response).setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
verify(response).setHeader("Pragma", "no-cache");
verify(response).setDateHeader("Expires", 0L);

verify(chain).doFilter(request, response);
}

@Test
public void testDoFilterSetsHeadersWhenChainThrowsException() throws IOException {
ServletRequest request = mock(ServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
FilterChain chain = mock(FilterChain.class);

try {
doThrow(new ServletException("chain failure")).when(chain).doFilter(any(ServletRequest.class), any(ServletResponse.class));
filter.doFilter(request, response, chain);
fail("Expected ServletException to be thrown");
} catch (ServletException e) {
// verify headers were set before the exception from the chain
verify(response).setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
verify(response).setHeader("Pragma", "no-cache");
verify(response).setDateHeader("Expires", 0L);

try {
verify(chain).doFilter(request, response);
} catch (ServletException ignored) {
// verification may declare ServletException; ignore since we're already handling it
}
}
}
}
22 changes: 21 additions & 1 deletion java/web/src/main/webapp/WEB-INF/web.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
<url-pattern>/*</url-pattern>
</filter-mapping>


<!-- Spring Security Servlet -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
Expand Down Expand Up @@ -72,6 +71,27 @@
<filter-name>CompressionFilter</filter-name>
<url-pattern>*.js</url-pattern>
</filter-mapping>
<!-- Cache management -->
<filter>
<filter-name>noCacheFilter</filter-name>
<filter-class>it.geosolutions.mapstore.filters.NoCacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>noCacheFilter</filter-name>
<url-pattern>/</url-pattern> <!-- index.html -->
</filter-mapping>
<filter-mapping>
<filter-name>noCacheFilter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>noCacheFilter</filter-name>
<url-pattern>*.json</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>noCacheFilter</filter-name>
<url-pattern>*.txt</url-pattern>
</filter-mapping>

<!-- Backend Spring MVC controllers -->
<!-- Backward compatibility -->
Expand Down
21 changes: 21 additions & 0 deletions project/standard/templates/web/src/main/webapp/WEB-INF/web.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,27 @@
<url-pattern>*.js</url-pattern>
</filter-mapping>

<!-- Cache management -->
<filter>
<filter-name>noCacheFilter</filter-name>
<filter-class>it.geosolutions.mapstore.filters.NoCacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>noCacheFilter</filter-name>
<url-pattern>/</url-pattern> <!-- index.html -->
</filter-mapping>
<filter-mapping>
<filter-name>noCacheFilter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>noCacheFilter</filter-name>
<url-pattern>*.json</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>noCacheFilter</filter-name>
<url-pattern>*.txt</url-pattern>
</filter-mapping>
<!-- Backend Spring MVC controllers -->
<!-- Backward compatibility -->
<servlet>
Expand Down