Я новичок в использовании 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());
}
}
}
Я надеюсь, что кто-нибудь может мне помочь и большое спасибо.