Unlocking Spring 6’s @HttpExchange: Modern Ways to Define API Controllers
This article reviews traditional Spring MVC controller definitions, introduces the new @HttpExchange annotation introduced in Spring 6 for declaring HTTP interfaces, demonstrates its usage with code examples, and shows how to generate client proxies for type‑safe HTTP calls.
Environment: SpringBoot 3.2.5
1. Review of interface definition methods
1.1 Regular definition
@RestController
@RequestMapping("/users")
public class UsersController {
@PostMapping()
public Object save(@RequestBody Users users) {
// ...
}
}1.2 Curious definition
@Component("/games/api")
public class CustomController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
response.setContentType("text/html;charset=utf8");
PrintWriter out = response.getWriter();
out.print("<h1>Controller接口</h1>");
out.close();
return null;
}
}1.3 Show‑off definition
@Component("/zhuangbi/api")
public class ControllerHttpRequestHandler implements HttpRequestHandler {
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf8");
PrintWriter out = response.getWriter();
out.print("<h1>你好,HttpRequestHandler</h1>");
out.close();
}
}These are various ways to define API endpoints in Spring MVC (excluding pure Servlets).
2. New definition method
Starting with Spring 6, a new annotation @HttpExchange can declare a class or method as an HTTP interface.
Declare the interface
@HttpExchange("/persons")
interface PersonService {
@GetExchange("/{id}")
Person getPerson(@PathVariable Long id);
@PostExchange
void add(@RequestBody Person person);
}
// Person object
public class Person {
private Long id;
private String name;
// getters, setters
}Implement the interface
@RestController
public class PersonController implements PersonService {
public Person getPerson(@PathVariable Long id) {
return new Person(id, "姓名 - " + id);
}
@ResponseStatus(HttpStatus.CREATED)
public void add(@RequestBody Person person) {
// TODO
}
}The implementation class is also annotated with @RestController like a normal controller.
Other exchange annotations include @DeleteExchange , @PatchExchange , and @PutExchange , which can be used on methods similarly to @RequestMapping.
3. Real purpose of @HttpExchange
The main goal of @HttpExchange is to generate a proxy that abstracts HTTP client calls.
@Configuration
public class PersonServiceClient {
@Bean
PersonService personServiceProxy() {
RestClient restClient = RestClient.builder().baseUrl("http://localhost:8088").build();
RestClientAdapter adapter = RestClientAdapter.create(restClient);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
PersonService personService = factory.createClient(PersonService.class);
return personService;
}
}Inject the proxy and use it like a regular service:
@Resource
private PersonService personServiceProxy;
@GetMapping("/persons")
public List<Person> list() {
return this.personServiceProxy.listPerson();
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
