Explore 8 Ways to Define Web Interfaces in Spring Boot 3 – Practical Code Samples
This article presents a comprehensive collection of 124 Spring Boot 3 practical cases, detailing eight distinct methods for defining web interfaces—including @Controller, @RestController, HttpRequestHandler, ServletRegistrationBean, HandlerFunction, @HttpExchange, and static resource registration—complete with code snippets, configuration steps, and usage explanations.
Introduction
In Spring Boot projects, using @RestController or @Controller annotations to define interfaces is common, but there are many other ways to expose web endpoints. This article explores eight distinct methods supported by Spring Boot, describing their scenarios, advantages, and code examples.
Practical Cases
2.1 Using @Controller Annotation
The @Controller annotation marks a class as a controller component. It works together with @RequestMapping to map request paths, which is the most common way to define interfaces.
<code>@RestController
@RequestMapping("/api")
public class ApiController {
@GetMapping("")
public ResponseEntity<?> query() {
return ResponseEntity.ok(new User("Pack", 22));
}
}
</code>The above returns JSON data. The following example returns a view:
<code>@Controller
public class ApiController {
@GetMapping("/home/index")
public ModelAndView index() {
return new ModelAndView("index");
}
}
</code>2.2 Implementing the Controller Interface
By implementing org.springframework.web.servlet.mvc.Controller , a class can handle HttpServletRequest and HttpServletResponse directly, similar to a Struts Action.
<code>@Component("/controller/api")
public class ApiController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("<h1>Implement Controller Interface to Define Web Interface</h1>");
return null;
}
}
</code>2.3 Implementing HttpRequestHandler Interface
HttpRequestHandler is a lightweight handler similar to a servlet. It declares only handleRequest and can be used in any jakarta.servlet.http.HttpServlet implementation.
<code>@Component("/handler/api")
public class HttpHandlerController implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("<h3>Implement HttpRequestHandler Interface to Define Web Interface</h3>");
}
}
</code>2.4 Registering HttpRequestHandlerServlet
Define a bean for the handler and register it with ServletRegistrationBean so that the servlet delegates to the handler bean.
<code>@Component
public class UserHttpHandler implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("<h3>Register HttpRequestHandlerServlet to Define Interface</h3>");
}
}
@Bean
public ServletRegistrationBean<HttpRequestHandlerServlet> userHandlerServlet() {
ServletRegistrationBean<HttpRequestHandlerServlet> registrar = new ServletRegistrationBean<>();
registrar.setServlet(new HttpRequestHandlerServlet());
registrar.setName("userHttpHandler");
registrar.addUrlMappings("/user/handler");
return registrar;
}
</code>2.5 Implementing a Servlet Directly
Traditional servlet implementation can still be used; Spring Boot registers it via annotations or configuration.
<code>@Component("/products")
public class ProductServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private final ObjectMapper objectMapper;
public ProductServlet(ObjectMapper objectMapper) { this.objectMapper = objectMapper; }
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("application/json;charset=utf-8");
List<Product> datas = List.of(
new Product("Spring Boot3 Practical Cases 150", BigDecimal.valueOf(70)),
new Product("Spring Full Stack Source Code", BigDecimal.valueOf(70))
);
String result = objectMapper.writeValueAsString(datas);
resp.getWriter().println(result);
}
public static record Product(String name, BigDecimal price) {}
}
</code>To make the servlet reachable, register a SimpleServletHandlerAdapter and optionally use @WebServlet with @ServletComponentScan :
<code>@Bean
public SimpleServletHandlerAdapter simpleServletHandlerAdapter() {
return new SimpleServletHandlerAdapter();
}
// Alternative registration
@WebServlet("/products")
public class ProductServlet extends HttpServlet { }
@SpringBootApplication
@ServletComponentScan
public class SpringBootComprehensiveApplication { }
</code>2.6 Implementing HandlerFunction Interface
HandlerFunction is a functional interface for handling requests in a functional style.
<code>@FunctionalInterface
public interface HandlerFunction<T extends ServerResponse> {
T handle(ServerRequest request) throws Exception;
}
</code>Example implementation:
<code>@Component
public class StorageHandler implements HandlerFunction<ServerResponse> {
@Override
public ServerResponse handle(ServerRequest request) throws Exception {
String id = request.pathVariable("id");
return ServerResponse.ok().body("Query storage info for id [" + id + "]");
}
}
</code>Register the route:
<code>@Bean
public RouterFunction<ServerResponse> storageRouter(StorageHandler storageHandler) {
return RouterFunctions.route()
.GET("/storages/{id}", storageHandler)
.build();
}
</code>2.7 Using @HttpExchange Annotation
Although primarily for client-side proxies, @HttpExchange can also define server-side contracts.
<code>@HttpExchange("/persons")
interface PersonService {
@GetExchange("/{id}")
Person getPerson(@PathVariable Long id);
record Person(Long id, String name) {}
}
@RestController
public class PersonController implements PersonService {
@Override
public Person getPerson(Long id) {
return new Person(id, "Name - " + id);
}
}
</code>2.8 Registering Static Resources
Spring Boot can serve static resources from any directory by configuring a resource handler.
<code>@Configuration
public class WebApiConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pack/resources/**")
.addResourceLocations("file:/d:/images/");
}
}
</code>The article concludes with a reminder to like, share, and collect the content.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.