Java EE/Jakarta EE范畴一览

Java EE(Java Platform, Enterprise Edition)现在已经改名为Jakarta EE,是一套用于开发企业级应用的标准Java平台。它扩展了Java SE(Standard Edition),添加了支持大规模、多层次、可靠、安全、可伸缩和可管理企业应用程序的库和API。这里简要概述一下Java EE的主要组成部分和标准:

核心组件

Servlet API

用于构建Web应用程序的基础,处理HTTP请求和响应。

Servlet API 是 Java EE 规范的一个核心部分,主要用于构建基于 Web 的应用程序。它提供了一种在服务器端接收和响应客户端(如 Web 浏览器)请求的方式。Servlet 是 Java 编写的小程序,运行在服务器上,并通过 Servlet API 与客户端进行通信。

基本概念

  • Servlet:一个 Java 类,用于扩展服务器的功能,处理来自 Web 客户端的请求,并对其进行响应。
  • 请求处理 :Servlet 通过 HttpServletRequest 对象接收请求数据,使用 HttpServletResponse 对象生成响应。

Servlet 生命周期

  1. 加载和实例化:Servlet 容器(如 Apache Tomcat)首先加载 Servlet 类,并创建其实例。
  2. 初始化 :通过调用 init 方法初始化 Servlet。这个方法只执行一次,主要用于一次性设置工作。
  3. 请求处理 :对于每个客户端请求,Servlet 容器调用 service 方法。此方法根据请求的类型(GET、POST 等)进一步调用 doGetdoPost 等方法。
  4. 终止 :当需要从服务中移除 Servlet 时,容器调用 destroy 方法,进行资源释放和清理工作。这个方法也只执行一次。

创建一个基础 Servlet

以下是一个简单的 Servlet 示例,展示了如何处理 GET 请求:

java 复制代码
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;

public class SimpleServlet extends HttpServlet {
    public void init() throws ServletException {
        // 初始化代码
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<html><body>");
        out.println("<h1>Hello, World!</h1>");
        out.println("</body></html>");
    }

    public void destroy() {
        // 清理资源代码
    }
}

部署 Servlet

为了运行上述 Servlet,你需要将其部署到一个支持 Servlet API 的 Web 容器中,如 Apache Tomcat 或 Jetty。部署通常涉及到编写一些配置(如在 web.xml 文件中配置 Servlet 和 URL 映射),或者在使用新版本 Servlet 容器时,可以通过注解自动完成。

总结

Servlet API 提供了一种强大的方式来创建动态 Web 应用程序,通过接收、处理 HTTP 请求和生成响应。它是 Java Web 开发的基石,其他很多 Java Web 技术和框架(如 Spring MVC、JSF)都是建立在 Servlet 的基础之上。

JavaServer Pages (JSP)

允许在HTML页面中嵌入Java代码,用于动态生成Web内容。

JavaServer Pages (JSP) 是一个帮助开发者创建动态生成的web页面的技术,它允许开发者将Java代码嵌入到HTML页面中。JSP 被广泛用于简化网页内容的动态生成,特别是当页面内容依赖于用户的请求或需要从数据库检索信息时。JSP 最终是被服务器解释并执行,返回纯 HTML 输出到客户端(浏览器)。

JSP 工作原理

  1. 请求处理:当用户访问一个 JSP 页面时,请求首先被发送到服务器。
  2. JSP 到 Servlet 的转换:在后台,JSP 页面被转换成一个 Servlet。这一转换通常在第一次请求时完成,或者在开发者修改 JSP 后的第一次请求时完成。
  3. 代码编译:生成的 Servlet 代码被编译成可执行的 Java 类。
  4. 执行:Servlet 类被加载到 JVM 中并执行。执行过程中,它读取请求,处理请求,并生成响应。
  5. 生成 HTML:JSP 页面中的静态内容被直接写入到响应中,而嵌入的 Java 代码则根据其逻辑动态生成内容。生成的内容也写入响应中。
  6. 发送响应:最终,服务器将完整的 HTML 响应发送回客户端浏览器。

JSP 的主要组成部分

  • 指令(Directives) :这些指令用于设置与整个 JSP 页面相关的属性,如页面编码、引入文件等。
    • 例如:<%@ page language="java" contentType="text/html; charset=UTF-8" %>
  • 脚本元素
    • 声明(Declarations) :用于声明变量和方法。声明的代码片段在 JSP 转换成 Servlet 时被放入 Servlet 类的类体中。
      • 例如:<%! int i = 0; %>
    • 表达式(Expressions) :用于在页面中输出内容,替代了 out.print() 方法。
      • 例如:<%= "Hello, " + name %>
    • 脚本片段(Scriptlets) :包含任意的 Java 代码,这些代码在请求处理阶段执行。
      • 例如:<% for (int i = 0; i < 10; i++) { out.println(i); } %>
  • 动作(Actions) :使用 XML 标记对执行特定操作的内置功能进行编码,如实例化 JavaBeans、执行重定向等。
    • 例如:<jsp:forward page="/nextPage.jsp" />
  • 隐含对象 :JSP 支持多种隐含对象,为开发者提供请求、响应等环境的直接访问,如 request, response, session, application 等。

优点和缺点

优点

  • 简化了网页内容的动态生成。
  • 支持重用代码和使用 JavaBeans 简化组件模型。
  • 与 Servlet 技术无缝集成,可以轻松访问底层的 HTTP 信息。

缺点

  • 由于 JSP 页面中的 Java 代码和 HTML 混合,可能导致维护困难。
  • 大量的逻辑放在 JSP 中会使页面复杂和难以管理,违反了 MVC 设计模式的理念。

JSP 技术现在已经逐渐被现代的 MVC 框架所取代,如 Spring MVC,这些框架提供了更清晰的分层和分离逻辑,但在某些遗留系统和特定应用场景中,JSP 仍然是一种有用的技术。

JavaServer Faces (JSF)

一个Web应用程序框架,简化了用户界面(UI)的开发,支持可重用组件和MVC架构。

JavaServer Faces (JSF) 是一个用于构建基于服务器的用户界面的 Java Web 应用程序框架。JSF 是 Java EE 的官方标准,专为简化企业级应用的用户界面开发而设计。它使用基于组件的方法,允许开发者通过拖放组件来创建视图,从而简化了 Web 应用程序的开发过程。

JSF 的核心特性

  1. 组件基础架构:JSF 提供了一套丰富的预定义界面组件,如文本框、按钮、链接等,并支持自定义组件的开发。
  2. 事件驱动:JSF 支持事件驱动编程模型,类似于桌面应用程序。组件可以生成用户交互事件(例如点击和选择),并且可以关联到服务器端的事件处理器。
  3. 导航管理:JSF 包括一个定义页面间导航逻辑的框架,使得开发者可以管理页面如何根据事件结果进行转换。
  4. 数据绑定:JSF 支持将页面组件与数据模型直接绑定,简化了数据从用户界面到应用程序后端的流动。
  5. 依赖注入:JSF 与 Java EE 的依赖注入和上下文管理无缝整合,特别是与 CDI (Contexts and Dependency Injection) 的集成。
  6. 面向方面的编程:通过使用拦截器和装饰器,开发者可以在不修改现有业务逻辑的情况下增加额外的行为。

JSF 的架构组件

  • 面生命周期:JSF 应用遵循一个明确的请求处理生命周期,包括恢复视图、处理组件事件、验证组件数据、更新模型值和渲染视图等步骤。
  • 托管 Bean:这些是用于在 JSF 页面和后端逻辑之间进行数据传递和控制页面逻辑的服务器端对象。
  • 表达式语言 (EL):JSF 使用 EL 来绑定组件的属性到 Bean 的属性或方法上,允许在页面上简洁地引用动态值。
  • 转换器和验证器:JSF 支持使用转换器将用户输入转换为应用程序中的数据类型,以及使用验证器来确保用户输入的数据有效。
  • AJAX:JSF 允许开发者通过 AJAX 增强用户界面的交互性,而无需直接编写 JavaScript 代码。

开发环境

JSF 应用通常在支持 Java EE 的应用服务器上运行,如 WildFly, Payara, 或者 Tomcat(通过添加 JSF 支持)。开发过程可以通过 IDE(如 Eclipse, IntelliJ IDEA 或 NetBeans)进行,这些 IDE 提供了对 JSF 的丰富支持,包括视图设计、自动完成和调试。

示例代码

下面是一个简单的 JSF 页面示例,演示了如何使用托管 Bean 和组件:

java 复制代码
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
<head>
    <title>Simple JSF Example</title>
</head>
<body>
    <h:form>
        <h:outputLabel value="Enter your name: "/>
        <h:inputText value="#{userBean.name}"/>
        <h:commandButton value="Submit" action="#{userBean.sayHello}"/>
        <h:outputText value="#{userBean.message}"/>
    </h:form>
</body>
</html>

在上述示例中,userBean 是一个托管 Bean,包含用户的名称和一个方法来生成问候语。

总结

JSF 是一个强大的框架,专为简化复杂的用户界面开发设计。通过其组件化、事件驱动和模型视图控制器 (MVC) 设计,JSF 成为开发大型企业级 Web 应用的理想选择。然而,随着单页应用 (SPA) 框架的兴起,如 Angular、React 和 Vue.js,传统的 JSF 正在逐渐被这些现代框架所替代,特别是在需要高度动态的用户界面和前端驱动的交互中。

Java Persistence API (JPA)

处理关系数据管理的标准方式,提供了对象-关系映射(ORM)来管理数据库。

Java Persistence API (JPA) 是 Java EE 和现在的 Jakarta EE 平台中用于管理关系数据的标准 API。JPA 主要是为了简化实体数据的持久化即数据保存到数据库的处理过程,通过提供一个对象关系映射 (ORM) 框架,将 Java 对象映射到数据库表。它旨在克服传统 JDBC 直接操作数据库时的复杂性和繁琐性,提供一个更高级和面向对象的数据管理方式。

JPA 核心概念

  1. 实体(Entity) :是持久化数据的核心概念,任何可以持久化到数据库的对象都称为实体。在 Java 类中通过使用 @Entity 注解来标识。

  2. 实体管理器(Entity Manager) :是 JPA 中用于管理实体包括实体的生命周期的组件。实体管理器通过 EntityManager 接口实现,提供了创建、读取、删除和更新实体的操作。

  3. 持久化单元(Persistence Unit) :在 persistence.xml 配置文件中定义,指定了一组实体类和管理这些实体类的配置,包括数据库连接和特定的 ORM 设置。

  4. 事务(Transaction):用于确保数据一致性和完整性的方式。JPA 支持事务操作,允许一组操作要么全部成功,要么全部失败。

JPA 操作流程

  • 定义实体类:首先,定义表示数据库表的实体类,并使用注解标识其映射关系。
  • 配置持久化单元 :在 persistence.xml 文件中配置数据库和实体管理的相关属性。
  • 进行 CRUD 操作 :通过 EntityManager 实例进行创建、读取、更新和删除操作。

示例代码

下面是一个简单的 JPA 实体类和基本的 CRUD 操作示例。

实体类定义
复制代码
java 复制代码
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    private Long id;
    private String name;

    // 构造函数、getter 和 setter
}
持久化操作示例
复制代码
java 复制代码
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Main {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-persistence-unit");
        EntityManager em = emf.createEntityManager();

        em.getTransaction().begin();

        User user = new User();
        user.setId(1L);
        user.setName("John Doe");

        em.persist(user); // 创建一个新用户
        user.setName("Jane Doe"); // 更新这个用户
        em.merge(user); // 合并更改到数据库

        User foundUser = em.find(User.class, 1L); // 读取用户
        System.out.println(foundUser.getName());

        em.remove(user); // 删除用户

        em.getTransaction().commit();
        em.close();
        emf.close();
    }
}

总结

JPA 提供了一个与数据库技术无关的数据持久化方式,使开发者能够以面向对象的视角来处理数据库操作,避免繁琐的 SQL 代码,同时自动处理很多数据库交互的复杂性。JPA 是现代 Java 应用中数据持久化的推荐方法,尤其适用于企业级应用。

Enterprise JavaBeans (EJB)

用于封装业务逻辑的可重用组件,支持事务处理、安全性和并发处理。

Enterprise JavaBeans (EJB) 是一种服务器端软件组件模型,它简化了企业应用的开发,特别是在需要处理事务、安全性和并发操作的应用程序。EJB 是 Java EE 规范的一部分,设计目的是让开发者能够快速开发可扩展、安全、可复用的业务逻辑组件。

EJB 的主要特性

  1. 事务管理:EJB 容器可以自动管理事务,确保数据完整性和一致性。开发者可以通过声明式事务管理来指定方法的事务行为,而无需编写具体的事务处理代码。

  2. 安全性:EJB 支持基于角色的安全访问控制,允许企业设置谁可以访问哪些 EJB。这种安全策略是通过声明式安全来实现的,使得开发者可以在没有编写复杂安全代码的情况下保护应用。

  3. 并发处理:EJB 容器管理并发访问,确保EJB实例的线程安全,允许多个客户端同时访问同一个 EJB。

  4. 生命周期管理:EJB 容器负责管理 EJB 的生命周期,包括实例化、持久化和销毁。

EJB 的类型

EJB 有三种主要类型,每种类型都针对不同的企业应用需求:

  1. Session Beans

    • Stateless Session Beans:不保持客户端状态,适用于执行不依赖于以前调用状态信息的操作。
    • Stateful Session Beans:保持与特定客户端的会话状态,适用于需要跨多个方法调用或事务保持信息的操作。
    • Singleton Session Beans:为整个应用提供一个共享的业务逻辑组件实例,适合实现共享配置或缓存。
  2. Message-driven Beans (MDB):允许 EJB 通过使用消息队列进行异步通信,适用于处理如 JMS 消息的应用。

  3. Entity Beans(已被 Java Persistence API (JPA) 替代):早期的 EJB 规范包括了 Entity Beans,用于表示持久化到数据库中的业务数据。现在,这一功能由 JPA 完全取代。

开发和部署 EJB

EJB 组件在部署时需要配置描述文件(通常是 XML 文件),描述文件指定了 EJB 的属性、事务管理策略和安全策略等。这些组件被部署在支持 EJB 的应用服务器中(如 WildFly, IBM WebSphere, Oracle WebLogic 等)。

示例:一个简单的 Stateless Session Bean

复制代码
java 复制代码
import javax.ejb.Stateless;

@Stateless
public class HelloBean implements HelloBeanRemote {

    public String sayHello(String name) {
        return "Hello, " + name + "!";
    }
}

在上面的示例中,HelloBean 是一个无状态的会话 Bean,提供了一个简单的方法 sayHello,该方法接收一个字符串参数并返回一个问候语。

总结

EJB 提供了一个强大的架构,用于开发分布式、事务性、多用户企业级应用程序。它抽象了许多复杂性,如事务管理、安全性、并发处理等,允许开发者专注于业务逻辑的实现。随着时间的推移,一些 EJB 的功能已经被更现代的 Java EE/Jakarta EE 技术如 CDI, JPA 等所取代,但 EJB 仍然在很多遗留系统中发挥着重要作用。

Java Message Service (JMS)

允许应用程序通过创建、发送、接收和读取数据(消息)来进行通信,支持可靠的异步通信。

Java Message Service (JMS) 是一个 Java 平台上的 API,专门用于在两个应用程序之间,或分布式系统中的组件之间,发送消息,实现异步通信。JMS 是一种中间件服务的形式,可以用来解耦应用程序组件,使它们可以独立地处理消息。

JMS 的主要特点

  1. 异步性:JMS 允许客户端继续进行其它处理,而不需要等待消息的发送或接收响应。
  2. 可靠性:提供了可靠的消息传递机制,确保消息可以成功送达,即使在消息系统失败的情况下也不会丢失消息。
  3. 解耦:发送者和接收者不需要同时在线,消息可以存储在消息队列中,直到接收者可用。
  4. 灵活性:支持点对点(Queue)和发布/订阅(Topic)两种消息传递模型。

JMS 的两种消息模型

  1. 点对点(Point-to-Point, P2P)

    • 使用队列(Queue)作为中介。
    • 每个消息只能有一个消费者(即一个消息被一个消费者接收)。
    • 发送者和接收者之间没有时间依赖性,即发送者不需要在接收者接收时处于活动状态,反之亦然。
  2. 发布/订阅(Publish/Subscribe, Pub/Sub)

    • 使用主题(Topic)作为中介。
    • 消息可以有多个消费者。
    • 通常用于实现信息的广播。

JMS 的主要组件

  • JMS 提供者:实现 JMS 接口以提供消息服务的系统或中间件。
  • JMS 客户端:生产(发送)和消费(接收)消息的应用程序。
  • 消息:在应用程序之间传输的数据。
  • 消息生产者:创建并发送消息的对象。
  • 消息消费者:接收消息的对象。
  • 消息队列/主题:存储消息的中间实体,直到它们被消费。

示例代码

以下是一个简单的 JMS 发送和接收消息的示例,假设使用了一个 JMS 兼容的消息代理。

发送消息
复制代码
java 复制代码
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSContext;
import javax.jms.JMSProducer;
import javax.jms.Queue;
import javax.naming.InitialContext;

public class JmsSender {
    public static void main(String[] args) throws Exception {
        InitialContext ctx = new InitialContext();
        ConnectionFactory factory = (ConnectionFactory) ctx.lookup("myConnectionFactory");
        Queue queue = (Queue) ctx.lookup("myQueue");

        try (JMSContext context = factory.createContext()) {
            JMSProducer producer = context.createProducer();
            producer.send(queue, "Hello, JMS!");
        }
    }
}
接收消息
复制代码
java 复制代码
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSConsumer;
import javax.jms.JMSContext;
import javax.jms.Queue;
import javax.naming.InitialContext;

public class JmsReceiver {
    public static void main(String[] args) throws Exception {
        InitialContext ctx = new InitialContext();
        ConnectionFactory factory = (ConnectionFactory) ctx.lookup("myConnectionFactory");
        Queue queue = (Queue) ctx.lookup("myQueue");

        try (JMSContext context = factory.createContext()) {
            JMSConsumer consumer = context.createConsumer(queue);
            String receivedMessage = consumer.receiveBody(String.class);
            System.out.println("Received Message: " + receivedMessage);
        }
    }
}

总结

JMS 是一个强大的工具,用于在 Java 应用程序中实现消息传递。它支持复杂的分布式系统中的异步通信和解耦,适合处理各种从简单的工作队列到复杂的事件处理系统的场景。

Java Transaction API (JTA)

管理多个资源(如数据库或消息服务)的事务处理。

Java Transaction API (JTA) 是一个 Java EE API,它允许应用程序执行跨多个资源(如数据库和消息服务)的分布式事务处理。JTA 是一个高级的事务管理接口,它抽象了底层的事务处理机制,提供统一的方法来控制事务的开始、提交和回滚。

JTA 的主要特性

  1. 分布式事务:JTA 支持分布式事务,这意味着事务可以跨多个网络分布的资源。例如,一个事务可能涉及两个数据库和一个消息队列。
  2. 事务管理器:JTA 定义了一个事务管理器,它是负责协调资源和管理事务边界的中心实体。
  3. 资源管理器:资源管理器是实际控制如数据库或JMS服务器资源的实体。JTA 通过资源管理器与这些资源进行交互。
  4. 两阶段提交:JTA 事务通常使用两阶段提交协议,以确保所有参与的资源都同意事务的最终结果。这是确保数据完整性和一致性的关键。

JTA 的工作流程

  • 开始事务:事务管理器开始一个新的事务。
  • 业务操作:应用程序执行涉及一个或多个资源(如数据库操作、消息发送等)的业务操作。
  • 阶段一:准备:事务管理器询问所有参与的资源管理器是否可以提交事务。每个资源管理器都会锁定在此事务中涉及的资源并准备提交。
  • 阶段二:提交/回滚
    • 如果所有资源管理器都准备好提交,事务管理器指示它们提交事务。
    • 如果任何一个资源管理器无法准备好提交,事务管理器将指示所有资源管理器回滚事务。

使用 JTA 的场景

  • 企业级应用:在需要确保数据完整性和一致性的企业级应用中,尤其是涉及多个数据库或者需要与其他企业系统集成时。
  • 高可靠性系统:在金融服务、电子商务、供应链管理等领域,事务必须准确无误,因此需要强大的事务管理支持。

示例代码

在 Java EE 环境中,使用 JTA 通常不需要开发者直接与 JTA API 交互,因为容器(如 WildFly, WebLogic 等)提供了对事务的自动管理。但如果需要,可以手动管理事务,例如:

复制代码
java 复制代码
import javax.transaction.UserTransaction;

@Resource
private UserTransaction utx;

public void executeTransaction() {
    try {
        utx.begin();
        // 执行数据库操作
        database.updateSomething();
        // 执行其他资源操作
        jms.sendSomeMessage();
        utx.commit();
    } catch (Exception e) {
        try {
            utx.rollback();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        e.printStackTrace();
    }
}

在上面的例子中,UserTransaction 用于明确开始、提交或回滚事务。这种方式给开发者提供了对事务控制的显式管理。

总结

JTA 提供了一个强大的机制,用于管理复杂的分布式事务。通过抽象底层的事务处理细节,JTA 允许开发者专注于业务逻辑,同时确保数据的一致性和完整性。在 Java EE 应用程序中,JTA 是处理事务性操作的标准方法,尤其是在涉及多个后端资源时。

JavaMail

在Java应用程序中集成电子邮件服务的API。

JavaMail 是一个为发送和接收电子邮件提供支持的 Java API,它定义了一套可用于构建邮件客户端的标准类和接口。JavaMail API 是独立于协议的,尽管它主要用于通过 SMTP(用于发送邮件)、POP3(用于接收邮件)、和 IMAP(用于接收邮件)协议与邮件服务器进行交互。

JavaMail 的核心组件

  1. Session:代表邮件会话,包含与邮件服务器交互所需的配置信息。
  2. Message:代表一封电子邮件,可以包含文本、附件等内容。
  3. Transport:用于发送邮件的类。
  4. Store:用于从邮件服务器接收邮件的类。

JavaMail 的主要特性

  • 灵活性:JavaMail API 支持扩展,可以使用任何邮件协议(如 SMTP, POP3, IMAP)。
  • 易用性:API 提供了简单的方法来发送和接收邮件,使得开发邮件相关的应用变得容易。
  • 功能丰富:支持创建、发送、接收和解析邮件,包括多部分内容和附件。

示例代码:发送简单的电子邮件

下面是一个使用 JavaMail API 发送简单电子邮件的示例。这个例子假设你已经有一个可用的 SMTP 服务器。

复制代码
java 复制代码
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;

public class SendEmail {
    public static void main(String[] args) {
        // 设置邮件服务器
        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.example.com"); // SMTP Host
        props.put("mail.smtp.port", "587"); // TLS Port
        props.put("mail.smtp.auth", "true"); // Enable Authentication
        props.put("mail.smtp.starttls.enable", "true"); // Enable StartTLS

        // 创建会话
        Session session = Session.getInstance(props, new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("username", "password");
            }
        });

        try {
            // 创建邮件消息
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("from@example.com"));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("to@example.com"));
            message.setSubject("Test Subject");
            message.setText("Hello, this is a test email!");

            // 发送邮件
            Transport.send(message);

            System.out.println("Mail sent successfully!");

        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

JavaMail 在实际应用中的使用

JavaMail 被广泛用于需要邮件功能的企业应用中,包括:

  • 自动发送通知邮件。
  • 开发邮件客户端应用程序。
  • 集成邮件功能到企业应用中,如自动订单确认邮件。

总结

JavaMail API 提供了一个功能强大、灵活且易于使用的平台,以编程方式发送和接收邮件。它支持丰富的内容类型,包括纯文本邮件和带附件的复杂邮件。对于需要集成邮件功能的 Java 应用程序,JavaMail 是一个理想的选择。

安全性

Java Authentication and Authorization Service (JAAS)

用于Java应用程序的安全框架,支持用户认证和授权。

Java Authentication and Authorization Service (JAAS) 是一个 Java SE 安全技术,用于对用户进行认证(Authentication)和授权(Authorization)。JAAS 提供了一种灵活的、独立于平台的方式,允许 Java 应用程序在保持安全的同时,对用户进行身份验证和权限控制。这种机制使得 Java 应用能够在多种认证技术(如用户名/密码、智能卡等)之间进行选择和扩展。

JAAS 的关键概念

  1. 认证(Authentication)

    • 认证是确定某个实体(通常是用户)的身份的过程。JAAS 通过 LoginModule 接口实现认证。应用程序可以通过使用不同的 LoginModule 来支持不同类型的认证机制。
  2. 授权(Authorization)

    • 授权是在认证成功后,决定用户可以访问的资源和操作的过程。JAAS 使用 Principal(身份标识)和权限集合(权限)来进行授权。
  3. 主体(Principal)

    • 在 JAAS 中,主体是一个标识符,用于表示一个个体(如用户或用户组)。主体通常通过登录过程被验证其身份。
  4. 策略(Policy)

    • JAAS 使用安全策略来控制对资源的访问。策略定义了哪些主体可以执行哪些操作。

JAAS 认证流程

  1. 应用程序调用 LoginContext

    • LoginContext 是 JAAS 认证的起点,负责协调不同的 LoginModule
  2. 加载配置的 LoginModule

    • 应用程序在 JAAS 配置文件中指定了使用哪些 LoginModule。每个模块可以独立地尝试认证用户,例如,通过用户名和密码、指纹识别等方式。
  3. 尝试认证

    • 每个 LoginModule 尝试验证用户的凭据。如果某个模块成功验证用户,则认证过程可以继续或结束,取决于配置文件中的选项。
  4. 提交或回滚

    • 如果认证成功,LoginContext 将调用每个 LoginModulecommit 方法,允许它们将相关的主体和凭据添加到 Subject 中。
    • 如果认证失败,则调用 abort 方法来清理状态。

JAAS 授权流程

  • 在认证成功后,Subject 被填充了认证的主体和凭证信息。当应用程序需要执行受保护的操作时,它将检查 Subject 是否拥有执行该操作的足够权限。

示例代码

以下是使用 JAAS 进行认证的简单示例代码:

复制代码
java 复制代码
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

public class JaasAuthentication {
    public static void main(String[] args) {
        try {
            // 创建 LoginContext,"MyLoginConfig" 是 JAAS 配置文件中的配置名
            LoginContext lc = new LoginContext("MyLoginConfig");
            // 尝试登录
            lc.login();
            System.out.println("Authentication successful.");
        } catch (LoginException e) {
            System.out.println("Authentication failed: " + e.getMessage());
        }
    }
}

总结

JAAS 提供了一个强大的框架,用于在 Java 应用程序中实现认证和授权。它的设计允许开发者插入自定义的认证技术,同时提供了一套完善的方法来控制对资源的访问。这使得 JAAS 成为 Java 安全体系中非常关键的一部分,广泛应用于需要严格安全控制的企业级应用程序。

Web服务

JAX-RS (Java API for RESTful Web Services)

支持REST风格Web服务的创建。

JAX-RS(Java API for RESTful Web Services)是一套用于开发遵循REST架构风格的Web服务的Java编程语言API。JAX-RS是Java EE的一部分,其目的是提供一个易于使用的方式来开发轻量级的Web服务。通过使用JAX-RS,开发者可以快速构建基于HTTP协议的Web服务,这些服务可以输出和接受XML、JSON等多种格式的数据。

JAX-RS的核心组件

  1. 资源类(Resource Classes)

    • 资源类是带有@Path注解的POJO(Plain Old Java Object),用于处理Web服务的特定资源。
  2. HTTP方法注解

    • JAX-RS提供了一系列注解来表示HTTP请求方法,如@GET@POST@PUT@DELETE等,这些注解用于资源类的方法上,表明该方法应响应哪种HTTP方法。
  3. 路径和参数注解

    • @Path用于指定资源的URI。
    • @PathParam@QueryParam@HeaderParam等注解用于将HTTP请求中的参数映射到资源方法的参数上。
  4. 响应构建

    • JAX-RS中,可以通过Response类构建HTTP响应,包括状态码、响应头和响应体。
  5. 异常处理

    • 通过ExceptionMapper接口可以处理应用中未捕获的异常,返回适当的HTTP响应。

开发JAX-RS应用

开发一个JAX-RS应用通常涉及以下步骤:

  1. 创建资源类

    • 定义一个类,并使用@Path注解标注以指定基础URI。
    • 在类中定义方法,并使用@GET@POST等注解来处理对应的HTTP请求。
  2. 部署应用

    • 在Java EE容器中部署应用,如使用Tomcat、WildFly等服务器。JAX-RS应用可以打包为WAR文件进行部署。

示例代码

以下是一个简单的JAX-RS示例,展示了一个处理HTTP GET请求的资源类:

复制代码
java 复制代码
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class HelloResource {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getHello() {
        return "Hello, JAX-RS!";
    }
}

在这个例子中,HelloResource类定义了一个处理对/hello路径GET请求的方法。@Produces注解指定了返回内容的MIME类型。

总结

JAX-RS是开发RESTful Web服务的强大工具,其注解驱动的方法简化了Web服务的开发过程。通过JAX-RS,开发者可以轻松创建支持多种数据格式的Web API,并可以在多种Java EE兼容的应用服务器上运行。JAX-RS也支持客户端API,使得从Java客户端程序调用RESTful服务变得简单。这使得JAX-RS成为构建现代Web应用程序和微服务架构的理想选择。

JAX-WS (Java API for XML Web Services)

支持SOAP风格Web服务的创建。

JAX-WS(Java API for XML Web Services)是用于创建遵循SOAP(Simple Object Access Protocol)标准的Web服务的一套Java API。它是JAX-RPC(Java API for XML-Based RPC)的后续版本,提供了一个方便的方法来开发和发布Web服务以及创建Web服务客户端。JAX-WS支持SOAP 1.1、SOAP 1.2和XML消息的传输,并能处理WSDL(Web Services Description Language)文件来描述网络服务。

JAX-WS的核心功能

  1. SOAP Web服务支持

    • JAX-WS允许开发者通过Java编程语言构建基于SOAP的服务,这些服务可以通过网络交换XML格式的数据。
  2. WSDL支持

    • 通过JAX-WS,服务定义可以通过WSDL文档自动产生,也可以从现有的WSDL创建服务。
  3. 注解简化开发

    • JAX-WS使用Java注解简化了Web服务的开发,这些注解用于绑定Java类和方法到WSDL文件。
  4. 消息处理器

    • JAX-WS允许插入自定义的消息处理器,用于在SOAP消息传输过程中进行监控或修改。
  5. 客户端API

    • JAX-WS提供了一个客户端API,使得生成和调用Web服务的客户端代码变得简单。

开发JAX-WS Web服务

开发一个JAX-WS Web服务通常涉及以下步骤:

  1. 定义服务接口

    • 使用@WebService注解标记一个接口或类,将其定义为一个Web服务。
  2. 实现服务接口

    • 实现上述接口,使用@WebMethod注解标记服务操作。
  3. 部署Web服务

    • 在Java EE服务器上部署Web服务,如GlassFish、WildFly等,这些服务器提供了对JAX-WS的内置支持。

示例代码

以下是一个简单的JAX-WS Web服务示例:

复制代码
java 复制代码
import javax.jws.WebService;
import javax.jws.WebMethod;

@WebService
public class CalculatorService {
    @WebMethod
    public int add(int a, int b) {
        return a + b;
    }
}

在这个示例中,CalculatorService类定义了一个Web服务,其中包含一个名为add的方法,用于执行加法运算,该方法通过网络可被远程调用。

发布Web服务

对于开发完成的Web服务,还需要进行发布,以便可以被远程访问。这通常在部署到服务器上后自动完成,服务器会为Web服务生成WSDL文件,客户端可以通过这个WSDL了解如何与服务交互。

总结

JAX-WS是一个强大的API,用于在Java环境中创建和部署基于SOAP的Web服务。它提供了完整的支持,从服务的创建到客户端的生成,都可以利用Java的注解和简便的API来实现。JAX-WS特别适用于需要严格的服务定义和复杂交互的企业级应用,而且它支持Web服务的标准和协议,保证了广泛的兼容性和互操作性。

其他API和组件

Contexts and Dependency Injection (CDI)

一种依赖注入机制,用于在运行时管理对象的依赖关系,增强模块间的解耦。

Contexts and Dependency Injection (CDI) 是 Java EE 现在被称为 Jakarta EE 的核心规范之一,它为企业级 Java 应用提供了一种类型安全的依赖注入机制。CDI 的设计目的是简化企业应用的开发,通过提供一致的方法来管理服务的生命周期,处理依赖注入(DI),并实现不同组件之间的松耦合。

CDI 的主要特点

  1. 依赖注入

    • CDI 支持基于类型的依赖注入。开发者可以通过注解将类标记为可被注入的候选者,并在需要时自动由容器注入。
  2. 上下文管理

    • CDI 管理不同的上下文(例如请求、会话、应用),并确保组件在其生命周期内正确地创建和销毁。
  3. 事件处理

    • CDI 提供了一个事件模型,允许组件观察和响应应用内的事件,从而促进了组件之间的解耦。
  4. 类型安全

    • CDI 使用类型安全的方法来处理注入和事件,提供编译时检查,避免运行时的类型错误。
  5. 拦截器和装饰器

    • 支持拦截器和装饰器模式,使得在不修改现有类代码的情况下,增强类的行为成为可能。
  6. 扩展机制

    • CDI 容器可以通过 SPI(服务提供接口)被扩展,允许开发者自定义容器的行为。

CDI 中的核心注解

  • @Inject:标记在类的构造函数、方法或字段上,用于注入依赖。
  • @Produces:标记在方法上,表明该方法用于生产可以被注入的对象。
  • @Qualifier:用于区分同一类型的不同实现。
  • @Scope:标记在类上,定义了被注解的bean的生命周期(如@RequestScoped, @SessionScoped, @ApplicationScoped)。
  • @Named:提供一个可在 EL 表达式中引用的名字,用于解耦 Java 代码和 UI 模板。

示例代码

下面是一个使用 CDI 的简单示例,展示了依赖注入和作用域的使用:

复制代码
import javax.inject.Inject;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;

@SessionScoped
public class ShoppingCart implements Serializable {
    private List<Item> items = new ArrayList<>();

    @Inject
    private ItemService itemService;

    public void addItemById(String itemId) {
        Item item = itemService.findItemById(itemId);
        if (item != null) {
            items.add(item);
        }
    }
    
    // Getter 和 Setter
}

集成和使用

CDI 在 Java EE 和 Jakarta EE 环境中是自动启用的。在 Java SE 或者轻量级容器中,如Tomcat中使用CDI时,可能需要额外的设置或集成第三方库(如Weld)。

总结

CDI 提供了一个强大的框架,用于管理依赖注入和组件生命周期,极大地简化了 Java EE 应用的开发。通过它的使用,开发者可以更容易地编写可测试、可维护和松耦合的代码。CDI 的事件模型和拦截器机制也提供了额外的灵活性,用于处理跨应用程序的交互和业务逻辑的增强。

Bean Validation

​​​​​​​一种用于对Java Beans进行约束验证的API。

Bean Validation 是 Java 平台的一个规范,旨在提供一种标准化的方法来验证 JavaBeans 的数据约束。这个 API,通常指的是 Jakarta Bean Validation(之前称为 Java Bean Validation),定义了一套简单且可扩展的约束声明和验证规则,可以应用于 Java 对象上,从而确保这些对象的数据满足业务规则的要求。

核心特点

  1. 标准化:Bean Validation 是一个标准的 Java API,可以与 JPA, JAX-RS, JSF 等 Java EE/Jakarta EE 技术无缝集成。
  2. 注解驱动:使用注解来声明约束,使得代码易于阅读和维护。
  3. 可扩展性:除了内置的标准约束外,还可以定义自己的约束。
  4. 自动和手动验证:支持在不同层自动验证 JavaBeans,也可以在需要时手动触发验证。

常用的约束注解

Bean Validation 提供了一系列的内置约束注解,包括:

  • @NotNull:确保字段不是 null。
  • @Min@Max:验证数字值的范围。
  • @Size:验证元素(如字符串、集合)的大小。
  • @Pattern:确保字符串值匹配一个正则表达式。
  • @Email:验证字符串是一个格式有效的电子邮件地址。
  • @Positive@PositiveOrZero:验证数值是正数或零。
  • @Negative@NegativeOrZero:验证数值是负数或零。

验证过程

  1. 定义约束:在 JavaBean 属性或类上使用注解来定义约束。
  2. 触发验证:在应用的业务逻辑中,可以通过验证引擎手动触发验证,或者在某些框架中(如 JPA 或 Spring)自动进行。
  3. 处理验证结果:验证过程可以产生一系列的约束违规,开发者需要相应地处理这些错误,例如,向用户显示错误消息。

示例代码

下面是一个使用 Bean Validation 注解的简单 JavaBean 示例:

复制代码
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class User {

    @NotNull(message = "Name cannot be null")
    @Size(min = 2, max = 100)
    private String name;

    @Min(value = 18, message = "Age must be greater than or equal to 18")
    private int age;

    // 构造函数、getter 和 setter 省略
}

集成和使用

Bean Validation 可以集成到任何使用 JavaBeans 的 Java 应用中。在 Java EE 环境中,这通常是自动配置的;在 Spring Framework 中,可以通过配置类或 XML 来启用 Bean Validation 支持。

例如,在一个 JAX-RS 应用中,Bean Validation 可以自动应用于传入的请求实体,无需任何额外配置:

复制代码
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.validation.Valid;

@Path("/users")
public class UserController {

    @POST
    public Response addUser(@Valid User user) {
        // 如果 User 对象中的数据不满足注解定义的约束,这里不会执行
        // 处理 user 存储逻辑
        return Response.ok().build();
    }
}

总结

Bean Validation 是一个强大的工具,用于在 Java 应用程序中实现数据有效性检验。通过其注解驱动的方式,开发者可以方便地在各个层次上应用一致的验证逻辑,保证数据的准确性和业务规则的一致性。

Java EE的这些组件和API共同构成了一个强大的平台,使得开发者能够构建处理大量数据和交易、需要高度安全和可靠性的企业级应用程序。从Java EE 8开始,该平台逐渐过渡到了由Eclipse Foundation管理的Jakarta EE,以保持开源生态系统的持续发展。

相关推荐
V+zmm1013430 分钟前
基于微信小程序的乡村政务服务系统springboot+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm
Oneforlove_twoforjob1 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
xmh-sxh-13141 小时前
常用的缓存技术都有哪些
java
AiFlutter1 小时前
Flutter-底部分享弹窗(showModalBottomSheet)
java·前端·flutter
J不A秃V头A2 小时前
IntelliJ IDEA中设置激活的profile
java·intellij-idea
DARLING Zero two♡2 小时前
【优选算法】Pointer-Slice:双指针的算法切片(下)
java·数据结构·c++·算法·leetcode
小池先生2 小时前
springboot启动不了 因一个spring-boot-starter-web底下的tomcat-embed-core依赖丢失
java·spring boot·后端
CodeClimb2 小时前
【华为OD-E卷-木板 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
程序员厉飞雨2 小时前
Android R8 耗时优化
android·java·前端
odng2 小时前
IDEA自己常用的几个快捷方式(自己的习惯)
java·ide·intellij-idea