小菜鸟

java菜鸟号正在起航

Struts2 入门示例:从配置到请求处理的完整流程

Struts2 是一款经典的 Java Web MVC 框架,通过拦截器机制处理请求,将业务逻辑与视图展示分离。本文基于提供的示例代码,详细讲解 Struts2 的第一个应用如何搭建,包括核心依赖、配置文件、Action 类编写及请求访问流程。

环境准备与核心依赖

1. 导入 Struts2 核心包

使用 Maven 构建项目时,需在pom.xml中添加 Struts2 核心依赖:

<dependency>
  <groupId>org.apache.struts</groupId>
  <artifactId>struts2-core</artifactId>
  <version>2.5.22</version> <!-- 版本需根据实际需求选择 -->
</dependency>

该依赖包含 Struts2 的核心类(如拦截器、Action 支持类)和默认配置文件(如struts-default.xml)。

Web.xml 配置:Struts2 拦截器的注册

Struts2 通过拦截器接收所有 Web 请求,因此需在web.xml中配置其核心过滤器StrutsPrepareAndExecuteFilter

阅读全文 »

XML 格式验证:DTD 与 XML Schema 详解

XML(可扩展标记语言)的灵活性使其广泛应用于数据交换和存储,但这种灵活性也带来了格式混乱的风险。为确保 XML 文档的结构合法性和数据有效性,需要通过语义约束机制进行验证。目前主流的 XML 验证方式有两种:DTD(文档类型定义)XML Schema(XML 模式)

DTD(Document Type Definition,文档类型定义)

DTD 是最早的 XML 语义约束标准,通过定义元素、属性、实体等规则,规范 XML 文档的结构。它语法简单,易于理解,但功能有限。

DTD 的引入方式

DTD 可以嵌入 XML 文档内部,或作为外部文件引用,主要有三种引入方式:

(1)内部 DTD

DTD 规则直接定义在 XML 文档内部,仅对当前文档有效。

语法格式

<?xml version="1.0"?>
<!DOCTYPE 根元素 [
  <!-- DTD规则定义 -->
]>
<!-- XML文档内容 -->

示例

<?xml version="1.0"?>
<!DOCTYPE note [
  <!ELEMENT note (to, from, body)>  <!-- note元素必须包含to、from、body子元素,顺序固定 -->
  <!ELEMENT to (#PCDATA)>          <!-- to元素只能包含文本 -->
  <!ELEMENT from (#PCDATA)>        <!-- from元素只能包含文本 -->
  <!ELEMENT body (#PCDATA)>        <!-- body元素只能包含文本 -->
]>
<note>
  <to>ll</to>
  <from>zh</from>
  <body>hello</body>
</note>
(2)外部 DTD

DTD 规则存储在独立的.dtd文件中,可被多个 XML 文档共享,便于维护。

语法格式

<?xml version="1.0"?>
<!DOCTYPE 根元素 SYSTEM "外部DTD文件路径">
<!-- XML文档内容 -->
阅读全文 »

MapReduce 数据清洗:脏数据进来,干净数据出去,连 Reduce 都省了

数据清洗是数据分析的第一步,也是最重要的一步——“垃圾进,垃圾出”,数据不干净,后面的分析全是错的。

清洗就是三件事:

  1. 过滤掉坏数据(格式错、字段缺、值不对)
  2. 标准化好数据(日期统一、大小写统一)
  3. 去掉重复的

在 MapReduce 里做数据清洗有个特别的优势:只需要 Mapper,不需要 Reducer。

因为清洗是逐条处理——每条数据独立判断、独立转换,不需要聚合。省掉 Reduce 阶段,就省掉了 Shuffle,数据直接从 Mapper 写到 HDFS,快得多。

为什么数据清洗不需要 Reduce?

MapReduce 的标准流程是 Map → Shuffle → Reduce。但清洗场景不需要分组、不需要聚合。

每条数据独立处理,过滤掉坏的,转换好的,然后直接输出。

flowchart TD
    A[原始数据HDFS] --> B[InputFormat 分片]  
    B --> C[Mapper 读取并清洗数据]  
    C -->|过滤/转换| D[符合条件的数据输出]  
    D --> E[OutputFormat 写入 HDFS]

所以配置就是一句话:

job.setNumReduceTasks(0);

Reduce 数量设成 0,Shuffle 就不会发生,数据直接走 Mapper → OutputFormat → HDFS。

省掉了排序、省掉了网络传输、省掉了磁盘溢写——对于只需要”过滤+转换”的作业,这是最大的性能优化。

一个例子:清洗 Nginx 日志

原始日志:

192.168.1.1 - [2023-10-01 12:00:00] "GET /index.html" 200 1024
192.168.1.2 - [2023-10-01 12:01:00] "GET /error.html" 404 512
192.168.1.3 - [2023-10-01 12:02:00] "POST /submit" 200 2048
阅读全文 »

ReduceTask 工作机制:拉数据、排序、分组、计算——一个 Reduce 任务的完整一生

Map 阶段干完活了,输出了一堆中间文件,散落在各个节点上。Reduce 的任务就是:把这些数据拉过来,按 Key 分组,然后执行你的业务逻辑。

ReduceTask 走四个阶段:

Copy → Merge → Sort → Reduce

  • Copy:从各个 Map 节点把属于自己的数据拉过来
  • Merge:把拉过来的数据合并、排序
  • Sort:最终按 Key 排好,分好组
  • Reduce:跑你的业务逻辑,输出结果
flowchart TD
    A[Map 输出文件] -->|Copy 阶段| B[ReduceTask 拉取分区数据]  
    B -->|Merge 阶段| C[内存/磁盘合并数据]  
    C -->|Sort 阶段| D[按 Key 分组排序]  
    D -->|Reduce 阶段| E[执行 reduce 函数输出结果]  
    E --> F[写入 HDFS 最终结果]
阅读全文 »

JMS(Java 消息服务)详解:规范、模型与实践

JMS(Java Message Service,Java 消息服务)是 Sun 公司定义的一套面向消息中间件的 Java 规范,旨在为 Java 应用程序提供统一的消息通信接口。它类似于 JDBC(数据库访问规范),屏蔽了不同消息中间件(如 ActiveMQ、RabbitMQ)的实现差异,使开发者能通过统一的 API 进行跨平台、跨组件的异步通信。

JMS 核心概念与作用

核心目标

JMS 的核心是实现应用程序之间的异步、可靠通信,通过消息中间件作为中介,解除发送方与接收方的直接耦合:

  • 发送方只需将消息发送到消息中间件,无需关心接收方是否在线或如何处理消息。
  • 接收方可在合适时机从中间件获取消息,实现 “发送即忘” 的异步通信模式。

消息系统的优势

  • 解耦:服务间无需直接依赖,通过消息间接通信,降低系统耦合度。
  • 异步:发送方无需等待接收方处理完成,提高系统响应速度。
  • 可靠:消息中间件确保消息不丢失、不重复,支持事务和持久化。
  • 削峰填谷:应对突发流量(如秒杀场景),通过消息队列缓冲请求,避免系统过载。

JMS 编程模型:六大核心组件

JMS 定义了一套标准化的组件,所有 JMS 应用程序都基于这些组件构建,确保跨平台兼容性。

系统管理对象(Administered Objects)

由消息中间件管理员配置,客户端通过 JNDI(Java 命名和目录接口)获取,包括连接工厂目标对象

阅读全文 »
0%