开始还以为是uri匹配的不对,后来查阅文档才明白,Grails的过滤器只对controller有效,对静态资源无能为力(包括网站的各种图标)
引用
Static resources aren't served by a controller, so Grails filters (which are wrappers for Spring controller interceptors) won't fire for requests for them.
解决办法,回归原本
1. 在src/java或src/groovy下创建一个过滤器,可以让它什么都不做
package myoa
import javax.servlet.*
class StaticFilter implements Filter {
@Override
void init(FilterConfig filterConfig) {
println('StaticFilter init')
}
@Override
void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) {
println('StaticFilter doFilter')
}
@Override
void destroy() {
println('StaticFilter destroy')
}
}
2. 创建配置文件
grails install-templates
编辑之
src/templates/war/web.xml
这样就做好了一个最简单的静态资源过滤器,uri在file-store文件夹的所有资源将被禁止访问。
3. 再进一步,可以完善这个doFilter功能,其实这就是Grails的过滤器的本质。 这里倒是有了个小心得,越本质的东西,看起来复杂,理解起来容易(好比是Servlet);封装过的东西,用起来简单,理解起来困难(好比是Grails)。所以要两者兼顾,先实用主义,把东西先做出来,然后慢慢体会最本质的东西,好歹现在都是open source的,看源码比看文档来得更透彻。
void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) {
println('StaticFilter doFilter')
HttpServletRequest request = (HttpServletRequest) servletRequest
HttpServletResponse response = (HttpServletResponse) servletResponse
HttpSession session = request.getSession(false) //若存在会话则返回该会话,否则返回NULL
if (session?.getAttribute('loginUser')) {
chain.doFilter(servletRequest, servletResponse);//放行。让其走到下个链或目标资源中
} else {
println('please login')
response.sendRedirect(request.getContextPath() + "/user/login")
}
}
====有待研究====
staticFilter无效
http://localhost:8080/myoa/static/download/expense-multi-month.xls
staticFilter有效
http://localhost:8080/myoa/download/expense-multi-month.xls