我正在使用默认的JSF servlet和RestEasy servlet来提供URI请求(Wildfly 8.1)。我希望使用@SessionScoped
辅助bean记录每个URI请求。 CDI bean(@Named
)或ManagedBean(@ManagedBean
),以便我可以记录来自此访问者的http请求。
我的要求:
Visit
。 Visit
对象存储:
我的问题:
Visit
? 当然,url-pattern /*
上已有一个servlet-mapping,而/restresources/*
上有一个servlet映射。对于同一条路径,无法注册2个过滤器,是吗? :
<filter>
<filter-name>UriLogger</filter-name>
<filter-class>com.doe.filters.UriAccessLogger</filter-class>
</filter>
<filter-mapping>
<filter-name>UriLogger</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
答案 0 :(得分:0)
好。对于其他想要记录每个页面和REST资源访问的人来说。
在web.xml文件中创建过滤器。
<filter>
<filter-name>UriLogger</filter-name>
<filter-class>com.doe.filters.UriLoggingFilter </filter-class>
</filter>
<filter-mapping>
<filter-name>UriLogger</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
另外,创建过滤器类。
package com.doe.webapp.controller.general.filters;
import java.io.IOException;
import java.io.Serializable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import com.doe.webapp.controller.general.VisitController;
@Named
@SessionScoped
public class UriLoggingFilter implements Serializable, Filter {
private static final long serialVersionUID = 1472782644963167647L;
private static Logger LOGGER = Logger.getLogger(UriLoggingFilter.class);
private String lastLoggedUri = "";
FilterConfig filterConfig = null;
@Inject
VisitController visitController;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
/**
* Log requests of interest with the VisitController.
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException,
ServletException {
// Run the other filters.
filterChain.doFilter(request, response);
if (request instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String uri = httpServletRequest.getRequestURI();
String regex = "((/{1}\\w+$)|(/{1}\\w+\\.jsf$))";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(uri);
while (m.find()) {
LOGGER.info("match " + m.group());
if (!lastLoggedUri.equals(uri)) {
visitController.saveUriRequest(httpServletRequest);
lastLoggedUri = uri;
} else {
LOGGER.warn("Multiple URI access to the same resource of the same user: " + uri);
}
break;
}
}
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
在此代码中,我删除了重复请求的日志记录。仅记录jsf页面请求和REST资源请求。因此,没有图像,css或js请求。根据您自己的需要调整RegEx。我使用saveUriRequest
注释了EJB函数@Asynchronous
,以避免响应延迟延迟。
回答我自己的问题:
Filter
注释为CDI bean。现在,每个访问者都有一个过滤器。注意事项 - 如果您拥有大量不同的用户,请不要这样做。这将迅速带来您可用的记忆。或者,您可以将其标记为@ApplicationScoped并从ServletRequest request
标头实例获取访客ID,并将请求分配给访问者。此外,这很容易遭到拒绝服务攻击。 (我只是出于内部目的使用它。)ServletRequest request
来区分会话。希望这对某人也有帮助。