в SpringBoot 2.x (2.1.0) пользовательский фильтр обрабатывается один раз, но выдает дублированные данные - PullRequest
0 голосов
/ 13 декабря 2018

Я новичок в использовании SpringBoot 2.1.0 с JSP (по некоторым причинам) для разработки веб-приложений.

Я использую фильтр для сохранения информации о доступе в базе данных, которая соответствует URL одного типа.
Но есть некоторые проблемы :
1.Когда я нажимаю на ссылку в меню, страница открывается в браузере заново, но выводится дважды, это указывает на то, что метод doFilterInternal , выполненный дважды, эта ситуация НЕ верна;

2018-12-13 13:43:07.405  WARN 14912 --- [nio-8096-exec-2] c.y.l.c.filters.rpt.AccessMenuFilter     : ---------------------------- Access Once ----------------------------------------
2018-12-13 13:43:07.405  WARN 14912 --- [nio-8096-exec-3] c.y.l.c.filters.rpt.AccessMenuFilter     : ---------------------------- Access Once ----------------------------------------  

2.Затем я щелкаю правой кнопкой мыши по открытой странице на первом шаге и выбираю обновить iframe, регистрирует вывод только один раз, это указывает на то, что метод doFilterInternal выполнен один раз, эта ситуация верна, на первом шаге он должен быть выполнен один разтоже.

2018-12-13 13:44:02.118  WARN 14912 --- [nio-8096-exec-1] c.y.l.c.filters.rpt.AccessMenuFilter     : ---------------------------- Access Once ----------------------------------------  

вставить две записи в базу данных на первом шаге, одну запись на втором шаге

Фильтр распространяется на OncePerRequestFilter , см. Из другихсообщений, это может вызвать вызов дважды, но почему на шаге 2 фильтр вызовет один раз.

Я выкладываю основные коды ниже:

POM.xml
https://github.com/richard20427176/pom-config/blob/master/pom.xml

Ниже находится основной из SpringBootConfig код:

@SpringBootConfiguration
public class SpringBootConfig implements WebMvcConfigurer {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {

        configurer.setUseSuffixPatternMatch(false);
//        configurer.setUseTrailingSlashMatch(false); 
        configurer.setUseRegisteredSuffixPatternMatch(true);
    }

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(true)
                .favorParameter(true)
                .parameterName("format")
                .ignoreAcceptHeader(true)
                .defaultContentType(MediaType.TEXT_HTML)
                .mediaType("html", MediaType.TEXT_HTML)
                .mediaType("json", MediaType.APPLICATION_JSON)
                .mediaType("xls", MediaType.valueOf("application/vnd.ms-excel"))
                .mediaType("xlsx", MediaType.valueOf("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
    }

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        Set<String> modelKeys=new HashSet<>();
        modelKeys.add("list");
        modelKeys.add("table");

        registry.jsp("/views/", ".jsp");
        registry.enableContentNegotiation(new MappingJackson2JsonView());

        XlsView xlsView=new XlsView();
        xlsView.setModelKeys(modelKeys);
        registry.enableContentNegotiation(xlsView);

        XlsxView xlsxView=new XlsxView();
        xlsxView.setModelKeys(modelKeys);
        registry.enableContentNegotiation(xlsxView);
    }
}

И ниже Конфигурация фильтра код:

@Configuration
public class FilterConfig implements WebMvcConfigurer {

    @Bean
    public FilterRegistrationBean shiroDelegatingFilterProxy() {
        DelegatingFilterProxy proxy = new DelegatingFilterProxy();
        proxy.setTargetFilterLifecycle(true);
        proxy.setTargetBeanName("shiroFilter");

        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(proxy);

        return filterRegistrationBean;
    }
}

Последнее, ниже, это реализация Фильтр кода:

@Component
public class AccessMenuFilter extends OncePerRequestFilter {
    private static final Logger LOGGER= LoggerFactory.getLogger(AccessMenuFilter.class);

    @Autowired
    private MonitorService monitorService;
    @Autowired
    private MenuService menuService;
    private Set<MenuIsMonitorVo> monitorMenus=new HashSet<>();
    private Map<String, RequestMatcher> menuRequestMatcherMap=new ConcurrentHashMap<>();


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try {
            String pageNumber = request.getParameter(Page.PAGE_NUMBER_REQUEST_PARAM_NAME);
            // If page no greater than 2, then skip
            if(StringUtils.isBlank(pageNumber) || pageNumber.compareTo("1")<=0) {
                for(Map.Entry<String,RequestMatcher> entry:menuRequestMatcherMap.entrySet()) {
                    if (entry.getValue().matches(request)) {

                        String username = ShiroBaseService.getLoginUser().getUsername();

                        UserAgent userAgent=UserAgent.parseUserAgentString(request.getHeader(HttpHeaders.USER_AGENT));
                        String browser= WebUtil.getBrowserName(userAgent);

                        CreateAccessMenuDto createAccessMenuDto = new CreateAccessMenuDto();
                        createAccessMenuDto.setMenuId(entry.getKey());
                        createAccessMenuDto.setUserName(username);
                        createAccessMenuDto.setOsName(userAgent.getOperatingSystem().getName());
                        createAccessMenuDto.setBrowserName(browser);
                        createAccessMenuDto.setIpAddress(RemoteIpHelper.getRemoteIpFrom(request));
                        createAccessMenuDto.setRequestLocale(request.getLocale().getDisplayName());
                        createAccessMenuDto.setCreateTime(new Date());

                        monitorService.asyncCreateAccessMenu(createAccessMenuDto);

                        LOGGER.warn("---------------------------- Access Once ----------------------------------------");

                        LOGGER.debug("Successfully add user access log:[SessionId:{};Username:{};platform:{};Browser:{};IPAddress:{};MenuId:{}]. The request url is {}",
                                request.getSession(false).getId(),
                                username,
                                userAgent.getOperatingSystem().getName(),
                                browser,
                                RemoteIpHelper.getRemoteIpFrom(request),
                                entry.getKey(),
                                request.getRequestURL());
                        break;
                    }
                }
            }
        } catch (Exception ex) {
            LOGGER.error("User Access fail due to the reason:"+ex.getMessage());
        } finally {
            filterChain.doFilter(request,response);
        }
    }

    @Override
    protected void initFilterBean() throws ServletException {
        if (monitorMenus != null && monitorMenus.size() > 0) {
            RequestMatcher matcher;
            for (MenuIsMonitorVo menu : monitorMenus) {
                if (menu.getIsMonitor().equals("1")) {
                    String pattern = menu.getMenuUrl();
                    if (!pattern.startsWith("/")) {
                        pattern = "/" + pattern;
                    }
                    if (pattern.indexOf("?") != -1) {
                        pattern = pattern.substring(0, pattern.indexOf("?"));
                    }

                    LOGGER.info("Add menu[MenuId:{},pattern:{}] to access log monitor candidate map.", menu.getMenuId(), pattern);

                    matcher = new AntPathRequestMatcher(pattern);
                    menuRequestMatcherMap.put(menu.getMenuId(), matcher);
                }
            }
        } else {
            monitorMenus = menuService.menuIsMonitor().stream().collect(Collectors.toSet());
        }
    }
}  

Я надеюсь, что кто-нибудь может мне помочь и большое спасибо.

1 Ответ

0 голосов
/ 14 декабря 2018

Я совершенно уверен, что запросы OPTIONS выполняют эти дополнительные вызовы фильтров для вас.

Пожалуйста, проверьте http://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS для получения дополнительной информации.Это должно быть видно на вкладке сети вашего браузера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...