成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

別只會(huì)用 @RequestMapping!Spring Boot 接口定義的八種解法大賞

開發(fā) 前端
本文以 Spring Boot 3.4.2 為基礎(chǔ),從多種角度出發(fā),帶你認(rèn)識(shí)八種在實(shí)際開發(fā)中可選的接口定義方式。每種方式都結(jié)合具體示例,從傳統(tǒng)控制器注解到函數(shù)式接口再到底層 Servlet 注冊,不論你是想要代碼更具語義性,還是希望繞開 Spring MVC 的重量框架獲得更直接的控制權(quán),都能在這些方案中找到適合的實(shí)現(xiàn)。

在日常的 Spring Boot 項(xiàng)目開發(fā)中,很多人定義接口時(shí)幾乎只會(huì)用 @RestController 搭配 @RequestMapping 或 @GetMapping、@PostMapping 等注解。久而久之,形成了路徑即控制器的固有思維模式。然而,Spring Boot 實(shí)際上為接口定義提供了遠(yuǎn)不止這一種方式。掌握多種接口聲明技巧,不僅能讓我們在面對不同場景時(shí)更加游刃有余,還能幫助團(tuán)隊(duì)構(gòu)建出更具擴(kuò)展性和清晰結(jié)構(gòu)的代碼架構(gòu)。

本文以 Spring Boot 3.4.2 為基礎(chǔ),從多種角度出發(fā),帶你認(rèn)識(shí)八種在實(shí)際開發(fā)中可選的接口定義方式。每種方式都結(jié)合具體示例,從傳統(tǒng)控制器注解到函數(shù)式接口再到底層 Servlet 注冊,不論你是想要代碼更具語義性,還是希望繞開 Spring MVC 的重量框架獲得更直接的控制權(quán),都能在這些方案中找到適合的實(shí)現(xiàn)。

傳統(tǒng)的 @Controller/@RestController + RequestMapping 模式

這是最常見的方式。

@RestController
@RequestMapping("/api")
public class ApiController {


    @GetMapping("")
    public ResponseEntity<?> query() {
        return ResponseEntity.ok(new User("Pack", 22));
    }
}

返回視圖頁面的方式:

@Controller
public class ApiController {


    @GetMapping("/home/index")
    public ModelAndView index() {
        return new ModelAndView("index");
    }
}

直接實(shí)現(xiàn) Controller 接口

這種方式有點(diǎn)像早期的 Struts Action 或原始 Servlet。

@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>直接實(shí)現(xiàn) Controller 接口</h1>");
        return null;
    }
}

適合需要直接操作請求和響應(yīng)對象的情況。

實(shí)現(xiàn) HttpRequestHandler 接口

更輕量的處理方式,與 Servlet 的邏輯結(jié)構(gòu)非常接近。

@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>實(shí)現(xiàn) HttpRequestHandler 接口</h3>");
    }
}

和 Controller 接口方式類似,但沒有返回視圖。

注冊 HttpRequestHandlerServlet 代理 HttpRequestHandler Bean

你也可以將請求委托給注冊的 Bean 實(shí)例處理。

@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>HttpRequestHandlerServlet 代理模式</h3>");
    }
}


@Bean
public ServletRegistrationBean<HttpRequestHandlerServlet> userHandlerServlet() {
    ServletRegistrationBean<HttpRequestHandlerServlet> registrar = new ServletRegistrationBean<>();
    registrar.setServlet(new HttpRequestHandlerServlet());
    registrar.setName("userHttpHandler");
    registrar.addUrlMappings("/user/handler");
    return registrar;
}

注意:setName 要與 Bean 名稱一致!

直接注冊 HttpServlet(老派寫法)

經(jīng)典 Servlet 的寫法依然可行,只不過現(xiàn)在更方便了。

@Component("/products")
public class ProductServlet extends HttpServlet {


    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> products = List.of(
                new Product("Spring Boot3實(shí)戰(zhàn)案例150講", BigDecimal.valueOf(70)),
                new Product("Spring全家桶源碼詳解", BigDecimal.valueOf(70))
        );


        resp.getWriter().println(objectMapper.writeValueAsString(products));
    }


    public static record Product(String name, BigDecimal price) {}
}

默認(rèn)不能直接訪問,需額外定義適配器:

@Bean
public SimpleServletHandlerAdapter simpleServletHandlerAdapter() {
    return new SimpleServletHandlerAdapter();
}

也可使用 @WebServlet("/products") 并配合 @ServletComponentScan 啟動(dòng)掃描。

函數(shù)式接口:實(shí)現(xiàn) HandlerFunction + RouterFunction

函數(shù)式 API 適合喜歡函數(shù)編程范式的開發(fā)者,Spring WebFlux 風(fēng)格,但在 MVC 中一樣可用。

@Component
public class StorageHandler implements HandlerFunction<ServerResponse> {


    @Override
    public ServerResponse handle(ServerRequest request) throws Exception {
        String id = request.pathVariable("id");
        return ServerResponse.ok()
                .body("庫存編號【" + id + "】的信息");
    }
}

然后注冊路由:

@Bean
public RouterFunction<ServerResponse> storageRouter(StorageHandler storageHandler) {
    return RouterFunctions.route()
            .GET("/storages/{id}", storageHandler)
            .build();
}

這種方式清晰、可組合、利于單元測試。

基于接口契約的 @HttpExchange(Http 客戶端方式)

該注解主要用于客戶端接口,但也可以作為接口規(guī)范在服務(wù)端實(shí)現(xiàn)。

@HttpExchange("/persons")
interface PersonService {


    @GetExchange("/{id}")
    Person getPerson(@PathVariable Long id);


    record Person(Long id, String name) {}
}

服務(wù)端實(shí)現(xiàn)它:

@RestController
public class PersonController implements PersonService {


    @Override
    public Person getPerson(@PathVariable Long id) {
        return new Person(id, "姓名 - " + id);
    }
}

不僅約定清晰,還能方便客戶端調(diào)用。

  • 對外開放本地靜態(tài)資源

如需暴露本地磁盤目錄作為資源目錄,只需簡單配置。

@Configuration
public class WebApiConfig implements WebMvcConfigurer {


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pack/resources/**")
                .addResourceLocations("file:/home/images/");
    }
}

這樣訪問 /pack/resources/img.jpg 就能映射到 /home/images/img.jpg 文件。

總結(jié)

Spring Boot 提供了多樣化的 Web 接口定義方式,不只是 @RequestMapping。你可以根據(jù)項(xiàng)目特點(diǎn)選擇最合適的方案:

方式

場景適用

@RestController

最常用,簡潔快捷

Controller 接口

需要原始請求控制

HttpRequestHandler

精簡 Servlet 方式

HttpServlet 注冊

兼容傳統(tǒng) Servlet 開發(fā)

HandlerFunction

函數(shù)式開發(fā)、高內(nèi)聚

@HttpExchange

接口規(guī)范復(fù)用,便于客戶端調(diào)用

靜態(tài)資源

文件預(yù)覽、圖片服務(wù)等

多掌握幾種方式,不僅提升工程適應(yīng)能力,也能寫出更優(yōu)雅靈活的接口代碼。

責(zé)任編輯:武曉燕 來源: 路條編程
相關(guān)推薦

2025-06-09 02:00:00

項(xiàng)目技術(shù)棧Spring

2022-04-28 21:53:52

TypeScriptany類型

2022-12-22 08:57:29

Redis數(shù)據(jù)存儲(chǔ)

2020-10-10 06:25:36

日志原理搜索

2025-06-06 08:28:56

2025-06-04 02:15:00

數(shù)據(jù)庫連接方式JDBC

2023-01-28 09:38:48

接口SpringMVC

2025-06-12 02:00:00

Spring簽到打卡

2022-08-26 01:02:31

接口privateSpring

2022-12-12 11:42:12

定義接口private

2021-04-16 11:02:40

Spring BootprivateJava

2024-06-12 12:13:48

2024-08-29 09:01:39

2021-08-31 10:26:24

存儲(chǔ)

2024-07-10 11:40:15

2025-02-12 08:47:07

SpringAPI接口

2020-08-05 08:30:25

Spring BootJavaSE代碼

2023-10-16 11:12:29

2025-03-03 13:08:36

2021-11-30 10:38:09

splitStringTokenJava
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 午夜视频一区二区 | 国产精品爱久久久久久久 | 国产精品久久精品 | 99热视| 午夜精 | 青青草网 | 欧美在线视频一区二区 | 99亚洲精品 | 91视频进入 | 爱爱视频在线观看 | 国产成人精品综合 | 精品一区二区三区在线观看国产 | 欧美一区二区三区久久精品 | 成人免费日韩 | 欧美专区日韩专区 | 免费黄网站在线观看 | 国内精品久久久久 | 欧美成人激情 | 亚洲免费一区 | 最新中文字幕久久 | av香蕉| 国产中文字幕在线 | 国产福利二区 | 激情国产 | 四虎影视一区二区 | 国产一区二区三区免费 | 久久精品aaa | 中文字幕在线视频精品 | 久久曰视频 | 欧美午夜影院 | 久草高清视频 | 亚洲三区在线观看 | 国产精品a一区二区三区网址 | 人人干人人草 | 国产精品视频免费观看 | 午夜精品一区二区三区在线观看 | 精品综合久久 | 一区二区三区国产精品 | 亚州精品天堂中文字幕 | 国产精品久久精品 | 亚洲欧美激情网 |