动态

详情 返回 返回

Resteasy 基於 Tomcat 開發 - 动态 详情

1. JAX-RS 規範

JAX-RS(Java API for RESTful Web Services)是 Java 平台的一項規範,旨在為開發 RESTful Web 服務提供支持。JAX-RS 定義了一組標準的 API 和註解,使得開發者可以通過簡單的註解方式來開發基於 REST 架構風格的 Web 服務。

實現 JAX-RS 規範的產品有很多,例如:Oracle 開發的 Jersey、JBoss(Red Hat)開發的 Resteasy、Apache CXF、Restlet 等等。

1.1. 特性

  1. 註解驅動: JAX-RS 提供了一組註解,如 @Path@GET@POST@PUT@DELETE@Produces@Consumes 等,用於簡化 RESTful 服務的開發。
  2. HTTP 方法支持: 直接映射 HTTP 方法到 Java 方法,使得開發者能夠輕鬆實現 RESTful 服務的核心操作。
  3. 內容協商: 支持通過 @Produces@Consumes 註解定義支持的媒體類型(如 JSON、XML),從而實現請求和響應的內容協商。
  4. 參數綁定: 提供對 URI 路徑、查詢參數、表單參數、請求頭等的簡便綁定方式。
  5. 異常處理: 提供了一種機制來處理 Web 應用中的異常,使得錯誤處理更為集中和一致。
  6. 過濾器和攔截器: 允許開發者定義過濾器和攔截器來處理請求和響應的通用邏輯,如身份驗證、日誌記錄等。

1.2. Spring MVC 相似

JAX-RS 和 Spring MVC 都是用於構建 Web 服務的框架,它們提供的註解在功能和命名上確實有許多相似之處。這種相似性主要是因為它們都遵循 REST 架構風格,並且都需要處理 HTTP 請求和響應。

1. 相似之處
  1. 註解驅動:

    • 兩者都使用註解來簡化 Web 服務的開發。
    • 例如,JAX-RS 使用 @Path 來定義資源路徑,Spring MVC 使用 @RequestMapping@GetMapping@PostMapping 等來定義請求路徑和方法。
  2. HTTP 方法支持:

    • JAX-RS 提供 @GET@POST@PUT@DELETE 等註解,直接映射到 HTTP 方法。
    • Spring MVC 提供 @GetMapping@PostMapping@PutMapping@DeleteMapping 等註解,功能類似。
  3. 參數綁定:

    • JAX-RS 使用 @PathParam@QueryParam@FormParam 等來綁定請求參數。
    • Spring MVC 使用 @PathVariable@RequestParam@RequestBody 等來實現類似功能。
  4. 內容協商:

    • JAX-RS 使用 @Produces@Consumes 註解來指定支持的媒體類型。
    • Spring MVC 使用 @RequestMappingproducesconsumes 屬性來實現相同的目的。
2. 不同之處
  1. 規範 vs 框架:

    • JAX-RS 是 Java EE 規範的一部分,定義了構建 RESTful 服務的標準接口。
    • Spring MVC 是 Spring 框架的一部分,提供了完整的 Web 應用開發解決方案,並不僅限於 RESTful 服務。
  2. 生態系統和集成:

    • JAX-RS 實現(如 Jersey、Resteasy)通常與 Java EE 應用服務器(如 WildFly、GlassFish)集成得很好。
    • Spring MVC 是 Spring 框架的一部分,與 Spring 的其他模塊(如 Spring Boot、Spring Data、Spring Security)集成緊密,廣泛用於 Spring 應用程序。
  3. 靈活性和擴展性:

    • Spring MVC 提供了更為靈活的配置和擴展能力,適合需要複雜業務邏輯和集成需求的應用。
    • JAX-RS 專注於 RESTful 服務,通常用於構建輕量級的 Web 服務。

JAX-RS 和 Spring MVC 之間沒有直接的依賴關係或繼承關係,它們是獨立發展的技術棧。但由於它們都旨在解決類似的問題(即構建 Web 服務),因此在設計上出現了許多相似的理念和實現方式。Spring MVC 在 JAX-RS 發佈之前就已經存在,但隨着 RESTful 風格的普及,Spring MVC 也逐步演變以更好地支持 RESTful API。

2. Resteasy 開發組件

Resteasy 是一個開源框架,專門用於實現 JAX-RS(Java API for RESTful Web Services)規範。它由 JBoss(現為 Red Hat 的一部分)開發和維護,是 WildFly 應用服務器的默認 JAX-RS 實現。Resteasy 提供了一套完整的工具和功能,用於構建 RESTful Web 服務。

Resteasy 提供了一組靈活且強大的組件和模塊,使開發者能夠高效地構建和擴展 RESTful 服務應用。通過理解和正確使用這些組件,開發者可以定製 JAX-RS 應用的行為,以滿足各種業務需求。無論是處理複雜的請求和響應格式,還是集成異步處理和客户端功能,Resteasy 都能提供全面的支持。

1. ResteasyDeployment
  • 功能作用:

    • ResteasyDeployment 是 Resteasy 的核心配置類,負責管理和配置 JAX-RS 應用程序的各個方面。
    • 它用於定義和註冊資源類、提供者(providers)、異步執行器和其他 JAX-RS 組件。
    • 在應用啓動時,ResteasyDeployment 會被初始化,並用於構建 RESTful 服務的運行時環境。
  • 典型用法:

    • 在配置 Resteasy 時,通常會創建一個 ResteasyDeployment 實例,並通過它註冊資源和提供者。
    • 可以通過程序化方式或通過 XML 配置文件進行配置。
2. Resource
  • 功能作用:

    • Resource 代表 JAX-RS 中的資源類。資源類是包含業務邏輯的 Java 類,用於處理 HTTP 請求。
    • 每個資源類通過 @Path 註解定義一個 URI 路徑,並通過方法級別的註解(如 @GET@POST 等)定義具體的操作。
  • 典型用法:

    • 開發者創建資源類來實現具體的 RESTful API 端點。
    • 在資源類中使用註解來綁定 URI 路徑、HTTP 方法和請求參數。
3. Provider
  • 功能作用:

    • Provider 是用於擴展和定製 JAX-RS 運行時行為的組件。
    • 它可以用於消息體讀寫(如 JSON、XML 的序列化和反序列化)、異常映射、上下文解析等。
    • 通過實現特定接口並使用 @Provider 註解註冊,開發者可以創建自定義的提供者。
  • 典型用法:

    • 自定義 MessageBodyReaderMessageBodyWriter 用於處理特定格式的請求和響應。
    • 實現 ExceptionMapper 接口用於統一處理應用程序中的異常。
    • 使用 ContextResolver 提供自定義的配置或對象給 JAX-RS 運行時。
4. Interceptors and Filters
  • 功能作用:

    • 攔截器和過濾器用於在請求處理的不同階段插入自定義邏輯。
    • 攔截器可以圍繞具體的方法調用進行操作,而過濾器通常用於請求和響應的全局處理。
  • 典型用法:

    • 實現 ContainerRequestFilterContainerResponseFilter 來對請求和響應進行預處理和後處理,如身份驗證、日誌記錄。
    • 使用 @PreMatching 註解在資源匹配之前執行過濾器邏輯。
5. Async and Client Modules
  • 功能作用:

    • 異步模塊支持非阻塞的請求處理,提高應用的響應性能和可擴展性。
    • 客户端模塊提供功能強大的 API,用於從 Java 應用程序中調用外部 RESTful 服務。
  • 典型用法:

    • 使用 @SuspendedAsyncResponse 處理異步請求。
    • 使用 ResteasyClient 類創建和配置 RESTful 客户端。
6. ResourceFactory
  • 功能作用:

    • ResourceFactory 是一個接口,負責創建和管理資源類的實例。
    • 它允許開發者控制資源類的生命週期,特別是在需要自定義實例創建邏輯或支持不同的作用域(如請求作用域、會話作用域)時。
  • 典型用法:

    • 自定義 ResourceFactory 可以用於在實例化資源類之前進行依賴注入或其他初始化操作。
    • 在配置 Resteasy 時,可以將自定義的 ResourceFactory 註冊到 ResteasyDeployment 中。
7. ServletConfig
  • 功能作用:

    • ServletConfig 是 Servlet 規範中的一個接口,提供對 Servlet 的配置信息的訪問。
    • 在 Resteasy 中,ServletConfig 可以用於獲取初始化參數和 Servlet 上下文,從而在配置 RESTful 服務時使用。
  • 典型用法:

    • 在 Resteasy 的 HttpServletDispatcher 中,ServletConfig 用於獲取應用的配置參數。
    • 開發者可以通過 web.xml 文件配置初始化參數,並在應用啓動時讀取這些參數。
8. Dispatcher
  • 功能作用:

    • Dispatcher 是 Resteasy 的核心組件之一,負責將 HTTP 請求分派到相應的 JAX-RS 資源類和方法。
    • 它處理請求的路由、參數解析、異常處理等。
  • 典型用法:

    • Resteasy 在內部使用 Dispatcher 來管理請求的整個生命週期。
    • 開發者通常不需要直接與 Dispatcher 交互,但可以通過擴展其行為來定製請求處理過程。
9. Registry
  • 功能作用:

    • Registry 是一個接口,用於管理和註冊 JAX-RS 資源和提供者。
    • 它允許動態添加或移除資源類和提供者,支持應用的熱部署和配置更新。
  • 典型用法:

    • 在應用啓動時,通過 ResteasyDeployment 註冊資源和提供者。
    • 在應用運行時,可以通過 Registry 接口動態更新配置。
10. ResteasyProviderFactory
  • 功能作用:

    • ResteasyProviderFactory 是一個工廠類,負責創建和管理 JAX-RS 提供者(如 MessageBodyReaderMessageBodyWriter)。
    • 它維護一個提供者的註冊表,並提供方法來查找和獲取合適的提供者實例。
  • 典型用法:

    • 開發者可以通過 ResteasyProviderFactory 註冊自定義的提供者。
    • 在請求處理過程中,Resteasy 使用 ResteasyProviderFactory 來選擇合適的提供者進行請求和響應的序列化和反序列化。
11. HttpServletDispatcher
  • 功能作用:

    • HttpServletDispatcher 是 Resteasy 提供的一個 Servlet,負責將 HTTP 請求分派到 JAX-RS 資源。
    • 它集成了 Servlet API 和 JAX-RS API,使得 Resteasy 可以在任何 Servlet 容器中運行。
  • 典型用法:

    • web.xml 中配置 HttpServletDispatcher,以便將請求轉發到 Resteasy 管理的資源。
    • 開發者可以通過 web.xml 配置初始化參數和 URL 映射。

下面通過一些示例看看如何使用 Resteasy

3. 示例

3.1. Tomcat 示例1

1. maven
            <dependency>
                <groupId>org.jboss.resteasy</groupId>
                <artifactId>resteasy-servlet-initializer</artifactId>
                <version>3.0.7.Final</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-core</artifactId>
                <version>8.5.95</version>
            </dependency>
2. POJO
@NoArgsConstructor
@AllArgsConstructor
@Data
public class CustomVO {
    private String name;
    private Integer value;
}
3. Resource

定義一個 GET 方法,映射路徑是 /example,返回對象是 CustomVO。

@Path("/example")
public class MyResource {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public CustomVO getCustomObject() {
        return new CustomVO("SampleName", 42);
    }
}
4. Provider

針對 CustomVO 對象,定義序列化內容。
其實如果是常見的 JSON 轉換,可以不用針對每個 POJO 定義 Provider,可以通過引入 resteasy-jackson2-provider 依賴默認實現。

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class MyProvider implements MessageBodyWriter<CustomVO> {

    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return type == CustomVO.class;
    }

    @Override
    public long getSize(CustomVO myCustomObject, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return -1;
    }

    @Override
    public void writeTo(CustomVO myCustomObject, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
                        MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException {
        String json = "{\"name\":\"" + myCustomObject.getName() + "\", \"value\":" + myCustomObject.getValue() + "}";
        entityStream.write(json.getBytes());
    }
}
5. 啓動類
public class App {
    public static void main(String[] args) throws Exception {
        ResteasyDeployment deployment = new ResteasyDeployment();

        Tomcat tomcat = new Tomcat();
        tomcat.setPort(8080);
        Context ctx = tomcat.addContext("", null);
        Tomcat.addServlet(ctx, "ResteasyServlet", new HttpServletDispatcher());
        ctx.addServletMappingDecoded("/*", "ResteasyServlet");
        ctx.getServletContext().setAttribute(ResteasyDeployment.class.getName(), deployment);
        tomcat.start();
        
        deployment.setResourceClasses(Arrays.asList(MyResource.class.getName()));
        deployment.setProviderClasses(Arrays.asList(MyProvider.class.getName()));
        
        tomcat.getServer().await();
    }
}
6. 運行結果

執行 main 方法,tomcat 啓動之後,然後在 tomcat 服務器上部署了 HttpServletDispatcher 的 Servlet,Resteasy 中配置了一個 Resource。

GET方法請求 http://localhost:8080/example 可以獲得 Provider 序列化後的結果。

ResteasyDeployment 類中的 setResourceClassessetProviderClasses 方法用於配置不同類型的組件:

  • setResourceClasses:用於註冊 JAX-RS 資源類。資源類定義了 RESTful API 的端點和業務邏輯。
  • setProviderClasses:用於註冊 JAX-RS 提供者類。提供者類用於擴展和定製 JAX-RS 的行為,例如消息體的讀寫、異常映射、上下文解析等。

3.2. Tomcat 示例2

這個示例要稍微複雜一點,但實際可以擴展的功能要更豐富些。為什麼要單獨拿出來這個示例,因為在看 Dubbo 框架 RestProtocol協議的實現方法時,看到就是這麼使用的。

具體細節可以看看com.alibaba.dubbo.rpc.protocol.rest.DubboHttpServer 中有關 Resteasy 的部署使用,示例中就保留對 Resteasy 組件的使用,通過簡單的 Demo 來執行。

1. maven
            <dependency>
                <groupId>org.jboss.resteasy</groupId>
                <artifactId>resteasy-servlet-initializer</artifactId>
                <version>3.0.7.Final</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-core</artifactId>
                <version>8.5.95</version>
            </dependency>
2. POJO
@NoArgsConstructor
@AllArgsConstructor
@Data
public class UserVO {
    private String name;
    private Integer age;
}
3. Provider
@Provider
@Produces(MediaType.TEXT_PLAIN)
public class UserProvider implements MessageBodyWriter<UserVO> {

    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return type == UserVO.class;
    }

    @Override
    public long getSize(UserVO myCustomObject, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return -1;
    }

    @Override
    public void writeTo(UserVO userVO, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
                        MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException {
        String json = userVO.getName()+"'s age is "+userVO.getAge() ;
        entityStream.write(json.getBytes());
    }

}
4. Resource 1
@Path("/say")
public class SayResource {

    @GET
    @Path("/hello")
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello!";
    }

    @GET
    @Path("/world")
    @Produces(MediaType.TEXT_PLAIN)
    public String world() {
        return "World!";
    }

    @GET
    @Path("/user")
    public UserVO user(){
        return new UserVO("Tom", 12);
    }
}
5. Resource 2
@Path("/action")
public class ActionResource {
    @GET
    @Path("/run")
    @Produces(MediaType.TEXT_PLAIN)
    public String run() {
        return "Run!";
    }

    @GET
    @Path("/fly")
    @Produces(MediaType.TEXT_PLAIN)
    public String fly() {
        return "Fly!";
    }
}
6. ServletConfig
public class CustomServletConfig implements ServletConfig {
    private final Map<String, String> initParameters;
    private final ServletContext servletContext;

    public CustomServletConfig(ServletContext servletContext) {
        this.servletContext = servletContext;
        this.initParameters = new HashMap<>();
    }
    @Override
    public String getServletName() {
        return "ResteasyServlet";
    }

    @Override
    public ServletContext getServletContext() {
        return servletContext;
    }

    /**
     * org.apache.catalina.servlets.DefaultServlet#init() 等實現類,會調用該方法讀取環境屬性配置
     *
     * @param name the name of the initialization parameter whose value to
     *             get
     * @return Parameter
     */
    @Override
    public String getInitParameter(String name) {
        return initParameters.get(name);
    }

    @Override
    public Enumeration<String> getInitParameterNames() {
        return new Vector<>(initParameters.keySet()).elements();
    }
}
7. HttpServletDispatcher
public class DispatcherServlet extends HttpServlet {
    private final HttpServletDispatcher dispatcher;

    public DispatcherServlet(HttpServletDispatcher dispatcher) {
        this.dispatcher = dispatcher;
    }

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        dispatcher.service(request,response);
    }
}
8. 啓動類
public class Main {

    public static void main(String[] args) throws Exception {
        ResteasyDeployment deployment = new ResteasyDeployment();
        HttpServletDispatcher servletDispatcher = new HttpServletDispatcher();
        
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(8080);
        Context context = tomcat.addContext("", null);
        Tomcat.addServlet(context, "servletDispatcher", new DispatcherServlet(servletDispatcher));
        context.addServletMappingDecoded("/*", "servletDispatcher");
        ServletContext servletContext = context.getServletContext();
        tomcat.start();
        
        servletContext.setAttribute(ResteasyDeployment.class.getName(), deployment);
        ServletConfig servletConfig = new CustomServletConfig(servletContext);
        servletDispatcher.init(servletConfig);
        deployment.getRegistry().addResourceFactory(new SingletonResource(new SayResource()));
        deployment.getRegistry().addResourceFactory(new SingletonResource(new ActionResource()));
        deployment.getProviderFactory().registerProviderInstance(new UserProvider());
        tomcat.getServer().await();
    }
}
9. 執行結果

訪問 http://localhost:8080 下列路徑均可訪問:

  • /say/hello
  • /say/world
  • /say/user
  • /action/run
  • /action/fly

4. Resteasy 特點

4.1. 單一Servlet

示例2中,配置了2個 Resource,每個 Resource 又有多個方法映射不同 @Path。但對於 Tomcat 服務器來説,其實就部署了一個 Servlet - HttpServletDispatcher

在使用 Resteasy 和嵌入式 Tomcat 的情況下,無論你添加多少個 JAX-RS 資源,它們通常都部署在同一個 Servlet 上。這是因為 Resteasy 的 HttpServletDispatcher 作為一個單一的 Servlet 來處理所有的 JAX-RS 請求。

4.1.1. 工作機制

  1. 單一 Servlet:

    • Resteasy 使用 HttpServletDispatcher 作為一個統一的前端控制器(Front Controller)。
    • 這個 Servlet 負責攔截所有傳入的 HTTP 請求,並將它們路由到適當的 JAX-RS 資源方法。如:示例2中 ctx.addServletMappingDecoded("/*", "ResteasyServlet"),攔截所有 /* 路徑下的請求。
  2. 路徑解析:

    • 每個 JAX-RS 資源類和方法上的 @Path 註解定義了該資源處理的 URI 路徑。
    • HttpServletDispatcher 通過解析請求的 URI 路徑,將請求映射到相應的資源類和方法。
  3. 集中管理:

    • 通過這種集中式的請求處理機制,開發者只需要在應用中配置一個 HttpServletDispatcher,而不必為每個資源類單獨配置 Servlet。
    • 這種方式簡化了配置、應用的部署和管理,使應用更易於擴展和維護。

4.1.2. 好處

通過使用單一的 HttpServletDispatcher,Resteasy 提供了一種高效、簡潔和靈活的方式來管理和處理 Web 服務請求。這種設計模式不僅降低了開發和維護的複雜性,還提高了應用的性能和可擴展性。對於開發者來説,這意味着可以更專注於業務邏輯的實現,而不必過多關注底層的請求管理細節。

1. 簡化配置
  • 集中管理: 只需要配置一個 HttpServletDispatcher,無需為每個資源類單獨配置 Servlet。這減少了配置的複雜性,特別是在大型應用中,管理多個資源類時更加方便。
2. 易於維護和擴展
  • 統一入口: 所有請求都通過同一個入口處理,使得日誌記錄、錯誤處理、身份驗證等跨切面邏輯可以在一個地方統一管理和應用。
  • 易於擴展: 添加新的資源類和路徑只需在代碼中進行,無需額外的配置更改。
3. 提高性能
  • 優化資源使用: 通過集中管理,可以更有效地使用服務器資源,因為只需一個 Servlet 實例來處理所有請求。
  • 減少上下文切換: 由於所有請求都通過同一個 Servlet 處理,減少了不同 Servlet 之間的上下文切換開銷。
4. 增強靈活性
  • 路徑映射靈活性: 通過 @Path 註解,可以靈活地定義 URI 路徑,使得應用程序的路由更加直觀和可維護。
  • 中間件集成: 由於有一個統一的入口,集成諸如安全、事務管理、監控等中間件變得更加簡單和一致。
5. 支持跨切面功能
  • 過濾器和攔截器: 可以在 HttpServletDispatcher 層面應用全局的過濾器和攔截器,處理請求和響應的通用邏輯,如身份驗證、日誌記錄、CORS 處理等。
  • 異常處理: 提供集中化的異常處理機制,通過全局異常映射器可以一致地處理應用中的異常。
6. 與 JAX-RS 標準兼容
  • 標準化: Resteasy 作為 JAX-RS 的實現,使用 HttpServletDispatcher 保持了與 JAX-RS 標準的兼容性,使得應用可以在不同的 JAX-RS 實現之間更容易地移植。

4.2. Spring MVC 相似

之前在內嵌 Tomcat 的文章中講過,SpringBoot 的實現也是部署一個 Servlet。那 SpringBoot 和 Dubbo 一樣,也是用 Resteasy 實現的嗎?

Spring MVC 的 DispatcherServlet 和 Resteasy 的 HttpServletDispatcher 都是用於處理 HTTP 請求的核心組件,雖然它們屬於不同的框架並服務於不同的架構模式,但它們之間仍然有一些相似之處和不同之處。以下是它們的詳細比較:

1. 相似點
  1. HTTP 請求處理:

    • 兩者都是基於 Servlet 的實現,用於接收和處理 HTTP 請求。
  2. 請求路由:

    • 都負責將請求路由到合適的處理器(Spring 中是控制器方法,Resteasy 中是 JAX-RS 資源方法)。
  3. 擴展支持:

    • 都支持通過註解配置來簡化請求的映射和處理。
    • 都可以通過註冊擴展(如提供者或攔截器)來增強功能。
  4. Servlet 機制:

    • 都是作為 Servlet 在應用服務器(如 Tomcat)中運行,利用 Servlet 規範的生命週期和配置機制。
2. 不同點
  1. 框架背景與目標:

    • DispatcherServlet:

      • 屬於 Spring MVC 框架的一部分,主要用於構建 Web 應用,尤其是支持 MVC 模式的應用。
      • 提供了視圖解析、數據綁定、驗證等豐富功能。
    • HttpServletDispatcher:

      • 屬於 JAX-RS 的實現之一(Resteasy),專注於構建 RESTful API 服務。
      • 主要處理 RESTful 請求,關注於 HTTP 方法和路徑的映射。
  2. 配置與自動化:

    • DispatcherServlet:

      • Spring Boot 提供了自動配置,開發者通常不需要手動配置。
      • 高度可配置,通過 Spring 配置文件或 Java 配置類進行調整。
    • HttpServletDispatcher:

      • 通常需要手動配置,特別是在嵌入式服務器環境中。
      • 配置相對簡單,以註解驅動的方式為主。
  3. 功能範圍:

    • DispatcherServlet:

      • 提供全面的 Web 應用支持,包括會話管理、模板渲染、國際化等。
      • 支持複雜的 Web 應用場景。
    • HttpServletDispatcher:

      • 專注於 RESTful 風格的服務,處理 JSON/XML 等數據格式。
      • 適合輕量級服務和 API 開發。
  4. 生態系統與集成:

    • DispatcherServlet:

      • 支持 Spring 的整個生態系統,包括 Spring Security、Spring Data 等。
      • 適合構建複雜的企業級應用。
    • HttpServletDispatcher:

      • 集成 JAX-RS 標準,適用於與其他 JAX-RS 實現的互操作。
      • 更專注於服務和 API 的開發。
user avatar lazytimes 头像 aipaobudehoutao 头像
点赞 2 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.