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 请求:

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 和组件:

<!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 操作示例。

实体类定义
 
import javax.persistence.Entity;
import javax.persistence.Id;@Entity
public class User {@Idprivate Long id;private String name;// 构造函数、getter 和 setter
}

持久化操作示例
 
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

 
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 兼容的消息代理。

发送消息
 
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!");}}
}

接收消息
 
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 等)提供了对事务的自动管理。但如果需要,可以手动管理事务,例如:

 
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 服务器。

 
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 Hostprops.put("mail.smtp.port", "587"); // TLS Portprops.put("mail.smtp.auth", "true"); // Enable Authenticationprops.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 进行认证的简单示例代码:

 
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请求的资源类:

 
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服务示例:

 
import javax.jws.WebService;
import javax.jws.WebMethod;@WebService
public class CalculatorService {@WebMethodpublic 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<>();@Injectprivate 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 {@POSTpublic Response addUser(@Valid User user) {// 如果 User 对象中的数据不满足注解定义的约束,这里不会执行// 处理 user 存储逻辑return Response.ok().build();}
}

总结

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/7890.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

脸爱云一脸通智慧管理平台 SystemMng 管理用户信息泄露漏洞(XVE-2024-9382)

0x01 产品简介 脸爱云一脸通智慧管理平台是一套功能强大,运行稳定,操作简单方便,用户界面美观,轻松统计数据的一脸通系统。无需安装,只需在后台配置即可在浏览器登录。 功能包括:系统管理中心、人员信息管理中心、设备管理中心、消费管理子系统、订餐管理子系统、水控管…

树莓派的几种登录方式、及登录失败解决方式

使用TF卡安装树莓派的系统后&#xff0c;可以通过编辑TF卡里的文件来设置和启用 “ VNC ” 、“ SSH ” 和 “ 串口 ” 功能。不过&#xff0c;在使用中打开VNC和SSH可能并不直观或方便&#xff0c;因为这些服务通常在树莓派的系统内部配置和启动。但你可以通过以下步骤来设置和…

OpenCV 入门(三)—— 车牌筛选

OpenCV 入门系列&#xff1a; OpenCV 入门&#xff08;一&#xff09;—— OpenCV 基础 OpenCV 入门&#xff08;二&#xff09;—— 车牌定位 OpenCV 入门&#xff08;三&#xff09;—— 车牌筛选 OpenCV 入门&#xff08;四&#xff09;—— 车牌号识别 OpenCV 入门&#xf…

C++11 设计模式7 策略模式 ,Strategy

策略模式的概念&#xff1a; 策略模式&#xff08;Strategy Pattern&#xff09;是 C 中常用的一种行为设计模式&#xff0c;它能在运行时改变对象的行为。在策略模式中&#xff0c;一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为模式。 在策略模式中&…

每日一题 礼物的最大价值

题目描述 礼物的最大价值_牛客题霸_牛客网 解题思路 这是一个典型的动态规划问题。我们可以使用一个二维数组 dp[][] 来存储到达每个格子时可以获得的最大价值。状态转移方程为 dp[i][j] max(dp[i-1][j], dp[i][j-1]) grid[i][j]&#xff0c;表示到达当前格子的最大价值是从…

Windows PC上从零开始部署ChatGML-6B-int4量化模型

引言 ChatGLM-6B是清华大学知识工程和数据挖掘小组&#xff08;Knowledge Engineering Group (KEG) & Data Mining at Tsinghua University&#xff09;发布的一个开源的对话机器人。6B表示这是ChatGLM模型的60亿参数的小规模版本&#xff0c;约60亿参数。 ChatGML-6B-in…

面试 Java 基础八股文十问十答第三十一期

面试 Java 基础八股文十问十答第三十一期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01;关注专栏后就能收到持续更新&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;TreeMap 有了解过吗…

knife4j-openapi3 使用笔记

knife4j官方文档&#xff1a;https://doc.xiaominfo.com/docs/quick-start/start-knife4j-version 增强模式文档&#xff1a;https://doc.xiaominfo.com/docs/features/enhance 1.用法 &#xff08;1&#xff09;控制层 Tag(name “用户信息管理”) Tag(name "用户信…

代码随想录第四十六天|单词拆分

题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09;

STM32F4xx开发学习_SysTick

SysTick系统定时器 SysTick属于CM4内核外设&#xff0c;有关寄存器的定义和部分库函数都在core_cm4.h这个头文件中实现&#xff0c;可用于操作系统&#xff0c;提供必要的时钟节拍 SysTick简介 SysTick是一个 24 位向下定时器&#xff0c;属于CM4内核中的一个外设&#xff0c;…

无卤素产品是什么?有什么作用?

无卤素产品&#xff0c;即在生产过程中完全不使用卤素元素——氟、氯、溴、碘等——的产品。 卤素元素&#xff0c;虽然在电子设备、材料等领域应用广泛&#xff0c;却也可能潜藏危害。其阻燃剂&#xff0c;一旦在产品生命周期结束后释放&#xff0c;将对土壤和水体造成污染&a…

Python-100-Days: Day11 Files and Exception

1.读取csv文件 读取文本文件时&#xff0c;需要在使用open函数时指定好带路径的文件名&#xff08;可以使用相对路径或绝对路径&#xff09;并将文件模式设置为r&#xff08;如果不指定&#xff0c;默认值也是r&#xff09;&#xff0c;然后通过encoding参数指定编码&#xf…

MyBatis入门例子

1、建立与数据库对应的POJO类 2、建立mybatis的配置文件 修改后如下&#xff1a; 3、创建POJO对象和Mysql数据的表之间的映射配置 4、建一个测试方法 实现从数据库中取数一条数据&#xff0c;封装成User对象返回 注意点&#xff1a; 这点&#xff0c;大家应该不陌生了&#x…

照片太大上传不了怎么缩小?教你几招压缩图片

在日常的工作和学习中&#xff0c;我们经常要用到一些图片文件&#xff0c;储存的图片多了之后&#xff0c;会对我们的电脑或者手机有影响&#xff0c;需要我们使用图片处理工具来压缩图片大小&#xff0c;那么有没有比较简单的图片压缩的方法呢&#xff1f;试试今天分享的几个…

【管理咨询宝藏94】某国际咨询公司供应链财务数字化转型方案

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏94】某国际咨询公司供应链&财务数字化转型方案 【格式】PDF版本 【关键词】国际咨询公司、制造型企业转型、数字化转型 【核心观点】 - 172…

VS2019编译 Qt5.15.12 和 Qt6.5.3

参考链接: Windows平台编译Qt5.15.12、6.5.3过程记录_qt 5.15 版本-CSDN博客 软件环境准备 Windows&#xff1a;MSDN系统库&#xff0d;致力于原版windows生态服务 Visual Studio 2022&#xff1a;下载 Visual Studio Tools - 免费安装 Windows、Mac、Linux cmake&am…

synchronized与volatile关键字

1.synchronized的特性 1.1互斥 synchronized 会起到互斥效果, 某个线程执行到某个对象的 synchronized 中时, 其他线程如果也执行到 同一个对象 synchronized 就会阻塞等待. 进入 synchronized 修饰的代码块, 相当于 加锁 退出 synchronized 修饰的代码块, 相当于 解锁 syn…

3行代码,实现一个取色器

前言 今天发现了一个很好玩的 API ——EyeDropper。 EyeDropper API 提供了一种创建拾色器工具的机制。使用该工具,用户可以从屏幕上取样颜色,包括浏览器窗口之外的区域。 这是 MDN 上对它的介绍,可以取包括浏览器窗口之外的区域。我们一起看看是怎么个事 什么是取色器 取…

611. 有效三角形的个数(双指针)

文章目录 前言一、题目解析二、代码原理1.暴力解法2.双指针优化 三、代码编写总结 前言 在本篇文章中&#xff0c;我们将会带着大家解决一下611. 有效三角形的个数这道题目&#xff0c;本道题木将会用双指针的方法解决。 一、题目解析 给定一个包含非负整数的数组 nums &…

关于Oracle 23ai 你要知道的几件事情

1.版本生命周期 23ai发布后的Oracle版本生命周期图&#xff0c;可以看到23ai是长期支持版本可以到2032年。 引申 Oracle版本分为两类 Innovation Release--创新版本&#xff0c;一般提供至少两年技术支持 Long Term Release --长期支持版本&#xff0c;一般提供5年premier和…