当前位置: 首页 > 知识库问答 >
问题:

如何使用JSF servlet和rest servlet记录每个URI访问

公羊光明
2023-03-14

我正在使用默认的JSF servlet和RestEasy servlet来服务URI请求(Wildfly 8.1)。我希望每个URI请求都使用@SessionScoped支持bean记录。无论是CDI bean(@命名)还是ManagedBean(@ManagedBean),以便我可以记录来自该访问者的超文本传输协议请求。

我的要求:

  • 我不想从每个JSF页面调用访问日志,也不想从每个REST资源Java文件调用访问日志
  • 每个请求都必须能够链接到@SessionScoped带注释的支持beanVisit访问对象存储:
    • 用户(如果已识别)
    • 参观开始
    • IP地址
    • n列表中的URI请求:JSF资源请求和rest资源请求

    我的问题:

    1. 如何在web中注册过滤器。将两个请求(无论是JSF还是REST)记录到@SessionScoped带注释的支持beanVisit

    当然,在url模式/*上已经有一个servlet映射,在/restresources/*上有一个servlet映射,不能为同一路径注册两个筛选器,可以吗?:

    <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>
    

共有1个答案

扶高歌
2023-03-14

可以对于其他希望记录每个页面并访问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请求。根据自己的需要调整正则表达式。EJB函数saveUriRequest我用@Asynchronous进行了注释,以避免响应延迟。

回答我自己的问题:

  1. 过滤器将接收每一个http请求——无论是JSF页面还是REST资源调用。将过滤器注释为带有@Named和@SessionScoped的CDIBean。现在每个访客都有一个过滤器。警告一句——如果你有大量不同的用户,不要这样做。这将迅速降低你的可用内存。或者,您可以将其标记为@ApplicationScoped,并从ServletRequest头实例中获取访客id,然后将请求分配给访客。此外,这很容易导致否认服务攻击。(我只是出于内部目的使用这个。)
  2. 是的,web容器通过jsessionid在会话之间进行分配,jsessionid也来自ServletRequest请求

希望这也能帮助到某人。

 类似资料:
  • 问题内容: 我想获得表中每个记录的最小日期,该记录具有一个主键的多个日期条目。看看我的桌子: 我想要这样的结果: 我想获取每个CaseNo的最短日期记录在我的桌子上。 我尝试了这段代码: 结果是这样的: 该代码删除没有最小日期的行。我想显示所有记录的最小日期为Min_date。 问题答案: 试试这个

  • 我正在努力处理mongo查询。我需要在单个查询中查找文档集合。集合应包含每个用户在单个查询中使用的最新日期(字段创建日期)的文档。 在斯波克有一个测试案例来演示我想要实现的目标: 我发现不同的方法是<代码>2.1.0的一部分。M1版本,因此尚未提供。 我也在尝试注释,但留档(下面的链接)没有指定如何创建像我这样的查询。 https://docs.spring.io/spring-data/data

  • ,日志记录将进入一个文件; (路径)/service_name/service_name.log 我想用logback复制这种行为,但在logback.xml配置中获取“logger”名称时遇到了真正的困难。它可以在log encoder.pattern中看到,即“%d%-5level%logger{35}-%msg%n”。

  • 目前在spring Boot1.3中,我们只能将访问日志记录到文件系统中的一个文件。有没有办法实际使用自定义记录器(像log4j2)来记录访问日志? 我目前正在使用undertow和spring boot,但是在检查spring boot源代码之后,undertow记录器是用DefaultAccessLogReceiver初始化的,它正在写入文件。如果可能的话,我希望使用AccessLogHand

  • 在spring中提供了三种不同的方法来连接响应端: 我的目标是记录每个响应(标题状态代码),不管结果如何。 我怎样才能知道上述哪种方法是正确的?

  • 问题内容: 我有一个JSONArray如下。如何按顺序访问每个键和值。 问题答案: 您可以尝试以下代码: