Skip to main content
Version: 4.6.1-saas

Java Agent

Overview

The NetFUNNEL Java agent is a dedicated client that communicates with the NetFUNNEL server from Java-based Spring Boot servers.

Minimum Requirements

  • Java 1.7 or later
  • Spring Boot 3.x or later

External Dependencies

  • gson: Library for JSON serialization/deserialization
  • jackson-module-kotlin: Library required for Kotlin (when using Java)

Operation Flow

Queue control points can be configured via segment trigger rules in the NetFUNNEL console. The queue is applied when the URL of the page the user accesses matches the trigger rules.

Before waiting: Page load → Agent initialization → Trigger rule match While waiting: Request to NetFUNNEL server → NetFUNNEL key issued → Redirect to waiting room page After waiting: Enter service page → Return NetFUNNEL key

Agent Installation

Add Library

Kotlin DSL (build.gradle.kts)

implementation(files'libs/netfunnel-agent.jar')
implementation(com.google.code.gson:gson:2.9.1)
implementation (com.fasterxml.jackson.module:jackson-module-kotlin)

Groovy DSL (build.gradle)

implementation files('libs/netfunnel-agent.jar')
implementation 'com.google.code.gson:gson:2.9.1'
// When using Java
implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'

Applying an Interceptor

warning

Choose only one of Interceptor or Filter to match your project structure. Both provide the same NetFUNNEL queue control behavior, so you do not need to implement both.

In the Interceptor that receives requests first, add code as follows.

Kotlin

@Component
public class DemoInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
NetFunnelInitializer initializer = getNetFunnelInitializer(requestUrl);
Netfunnel netfunnel = new Netfunnel(initializer, new NetFunnelServletService(request, response));
return netfunnel.run();
}

private NetFunnelInitializer getNetFunnelInitializer(String requestUrl) {
return NetFunnelInitializer.builder()
.clientId("{{CLIENT_ID}}")
.secretKey("{{SECRET_KEY}}")
.build();
}
}

Java

import com.stclab.Netfunnel;
import com.stclab.servlet.NetFunnelServletService;
import com.stclab.utils.NetFunnelInitialize;

@Component
public class DemoInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
NetFunnelInitialize config = NetFunnelInitialize.Companion.builder()
.clientId("{{CLIENT_ID}}")
.secretKey("{{SECRET_KEY}}")
.build();

Netfunnel netfunnel = new Netfunnel(config, new NetFunnelServletService(request, response), null, null);
return netfunnel.run();
}
}

Register the Interceptor by overriding the addInterceptors method of WebMvcConfigurer.

Kotlin

@Configuration
public class WebConfig implements WebMvcConfigurer {

private final DemoInterceptor demoInterceptor;

@Autowired
public WebConfig(DemoInterceptor demoInterceptor) {
this.demoInterceptor = demoInterceptor;
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(demoInterceptor);
}
}

Java

@Configuration
public class WebConfig implements WebMvcConfigurer {

private final DemoInterceptor demoInterceptor;

@Autowired
public WebConfig(DemoInterceptor demoInterceptor) {
this.demoInterceptor = demoInterceptor;
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(demoInterceptor)
.addPathPatterns("/**");
}
}

Applying a Filter

In the Filter that receives requests first, add code as follows.

Kotlin

@Component
public class DemoFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;

NetFunnelInitializer initializer = getNetFunnelInitializer(requestUrl);
Netfunnel netfunnel = new Netfunnel(initializer, new NetFunnelServletService(request, response));

if (netfunnel.run()) {
chain.doFilter(servletRequest, servletResponse);
}
}

private NetFunnelInitializer getNetFunnelInitializer(String requestUrl) {
return NetFunnelInitializer.builder()
.clientId("{{CLIENT_ID}}")
.secretKey("{{SECRET_KEY}}")
.build();
}
}

Java

import com.stclab.Netfunnel;
import com.stclab.servlet.NetFunnelServletService;
import com.stclab.utils.NetFunnelInitialize;

public class DemoFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;

NetFunnelInitialize config = NetFunnelInitialize.Companion.builder()
.clientId("{{CLIENT_ID}}")
.secretKey("{{SECRET_KEY}}")
.build();

Netfunnel netfunnel = new Netfunnel(config, new NetFunnelServletService(request, response), null, null);

if (!netfunnel.run()) {
return;
}

chain.doFilter(servletRequest, servletResponse);
}
}

Register the Filter as a bean.

Kotlin

@Configuration
@RequiredArgsConstructor
public class FilterConfig {
private final DemoFilter demoFilter;

@Bean
public FilterRegistrationBean<Filter> filterRegistrationBean() {
return new FilterRegistrationBean<>(demoFilter);
}
}

Java

@Configuration
@RequiredArgsConstructor
public class FilterConfig {

@Bean
public FilterRegistrationBean<Filter> filterRegistrationBean() {
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
registration.setFilter(new DemoFilter());
registration.addUrlPatterns("/*");
registration.setOrder(1);
return registration;
}
}

Initialize Settings

FieldDefaultRequiredDescriptionAgent version
clientIdN/AOEnter the client ID issued from the console.4.0.1 or later
secretKeyN/AOEnter the secret key issued from the console.4.0.1 or later
serverUrlN/AXURL of the NetFUNNEL server. Use when accessing the server via a custom URL instead of a clientId-based URL or when not using CNAME. <br />(Supported for backward compatibility.)4.0.1 or later
settingUrlN/AXURL of the NetFUNNEL environment configuration file. Use when loading the config via a custom URL instead of a clientId-based URL or when not using CNAME. <br />(Supported for backward compatibility.)4.0.1 or later
vwrPageUrlN/AXURL of the NetFUNNEL VWR page. Use when redirecting to the waiting room via a custom URL instead of a clientId-based URL.4.0.1 or later
returnKeytrueXWhen the user passes the queue and enters the page, the next user can enter immediately.<br />If disabled, the next user waits for a period even after the user has entered. <br />(Timeout is configured in Console: Segment settings > Advanced.)4.0.1 or later
logLevelLevel.OFFXSet log level based on ch.qos.logback.classic.Level; that dependency must be added.<br />Levels: ERROR, WARN, INFO, DEBUG, TRACE, OFF4.0.1 or later
goodBotsN/AXExclude good bots (e.g. search engines) from NetFUNNEL entry. Pass an array of strings.<br />Example: ["Googlebot", "Bingbot"]4.0.1 or later
userIdN/AXWhen set, this ID is used for whitelist and permanent block.<br />The ID configured in Console > Repeated request block > User settings > Visitor management is applied.4.0.1 or later
vwrPageDomainN/AXUse when building the VWR page URL with only the CNAME domain.<br />Example: https://vwr.example.com4.0.1 or later
cookieDomainN/AXSet the domain of the NetFUNNEL cookie explicitly.4.0.1 or later

Agent Application

Queue control points can be configured via segment trigger rules in the NetFUNNEL console. The queue is applied when the URL of the page the user accesses matches the trigger rules.

Configuration Options

  • Logical Operator: When creating two or more trigger rules, defines their relationship with and or or.
  • Validator: Defines the top-level scope for the trigger rule (e.g. URL only).
  • Component: Within the scope defined by the Validator, specifies the target in more detail (e.g. full URL or path).
  • Negate: Use to apply the opposite of the configured condition (e.g. when the condition is not true).
  • Match: Defines the type of condition (e.g. Equals, Exists) for when the rule applies.
  • Value: The value to compare against when the rule is evaluated; used together with Match.
  • Aa: Whether to match Value case-sensitively.

Match Options

  • Exists: Checks whether the Component exists in the URL. (Only when Component is Path.)
  • Equals: Checks whether the Component value exactly matches Value.
  • Contains: Checks whether the Component value contains Value.
  • StartsWith: Checks whether the Component value starts with Value.
  • EndsWith: Checks whether the Component value ends with Value.

Testing Trigger Rules

You can test in advance whether the URLs where you want to apply the queue match the trigger rules.