Backend Development 7 min read

Master Spring Boot: Unified Paths, Static Resources, Validation, and More

Learn how to configure Spring Boot 2.7.16 for unified API prefixes, custom static resource locations, annotation‑based and custom parameter validation, global exception handling, request inspection via HttpEntity, CORS filtering, custom error pages, and reliable ServletContext access using ApplicationListener.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Master Spring Boot: Unified Paths, Static Resources, Validation, and More

Environment: SpringBoot 2.7.16

1. Unified Path

To give all controller endpoints a common prefix, configure a WebFluxConfigurer that adds the "/api" prefix to every request.

<code>@Configuration
public class WebConfig implements WebFluxConfigurer {
    @Override
    public void configurePathMatching(PathMatchConfigurer configurer) {
        configurer.addPathPrefix("/api", t -> true);
    }
}</code>

This forces every controller request to start with "/api".

2. Static Resource Registration

Spring Boot by default serves static resources from classpath:/META-INF/resources/ , classpath:/resources/ , classpath:/static/ , and classpath:/public/ . To register a custom location, implement WebMvcConfigurer:

<code>@Component
public class StaticResourceConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // Local file system path, prefix must be "file:"
        registry.addResourceHandler("/static/**")
                .addResourceLocations("file:D:/images/");
    }
}</code>

3. Parameter Validation

Include spring-boot-starter-validation to use annotation‑based validation with @Validated or @Valid . For custom validation logic, register your own validator:

<code>@RestController
@RequestMapping("/users")
public class UserController {
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.addValidators(new UserValidator());
    }
}

// UserValidator implementation
public class UserValidator implements Validator {
    @Override
    public boolean supports(Class<?> clazz) {
        return clazz.isAssignableFrom(User.class);
    }

    @Override
    public void validate(Object target, Errors errors) {
        User user = (User) target;
        if (user.getAge() > 150) {
            errors.reject("age", "年龄不能超过150");
        }
        if (user.getName() == null || user.getName().equals("")) {
            errors.reject("name", "姓名不能为空");
        }
    }
}</code>

4. Exception Handling

Define a global exception handler with @RestControllerAdvice and @ExceptionHandler . You can also extend Spring's ResponseEntityExceptionHandler to customize handling of common exceptions:

<code>@Component
public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers,
                                                             HttpStatus status, WebRequest request) {
        // Implement custom logic
        return new ResponseEntity<>(ex.getMessage(), headers, status);
    }
}</code>

Default exception handling options are shown in the following diagram:

5. Retrieve Full Request Information

Use HttpEntity&lt;T&gt; in a controller method to access both request headers and body:

<code>@RestController
@RequestMapping("/users")
public class UserController {
    @PostMapping("")
    public Object save(HttpEntity<User> entity) {
        // Through HttpEntity you can obtain body and header information.
    }
}</code>

6. Built‑in CORS Filter

Spring Web provides a CORS filter that can be registered as a bean:

<code>@Bean
CorsFilter corsFilter() {
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("http://www.pack.com");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}</code>

7. Customize Default Error Page

Spring Boot maps /error to a default error page. Implement a custom ErrorController and adjust server.error.path in configuration:

<code>@RestController
@RequestMapping("/error")
public class PackErrorController implements ErrorController {
    @GetMapping("")
    public Object e() {
        return "error...";
    }
}</code>
<code>server:
  error:
    # Ensure the custom ErrorController matches this path
    path: /pack/error</code>

8. Correctly Obtain ServletContext

In an embedded container, ServletContext is not reliably available during bean initialization. Listen for ApplicationStartedEvent to capture it after the server starts:

<code>@Component
public class PackComponent implements ApplicationListener<ApplicationStartedEvent> {
    private ServletContext servletContext;

    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        ApplicationContext applicationContext = event.getApplicationContext();
        this.servletContext = ((WebApplicationContext) applicationContext).getServletContext();
    }
}</code>

The ApplicationStartedEvent is published after the application is essentially ready, before any CommandLineRunner or ApplicationRunner callbacks.

These are all the techniques covered in this article.

backendconfigurationvalidationCORSSpringBootExceptionHandlingServletContext
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.