请编写一个拦截器,该拦截器可以获得用户输入的用户名这个数据,业务逻辑为逐个判断用户名中是否包含“你”,“我”,“他”三个数据,如果包含则直接返回输入页面,如果不包含则运行至 PersonAction 。(除代码外,要给出拦截器和 Action 的配置文件) 提示:判断一个字符串是否包含指定的字符串,可以使用字符串对象的 contains 方法。
时间: 2025-08-08 13:29:17 浏览: 4
<think>嗯,用户想创建一个Struts拦截器,用来检查用户名是否包含特定字符,比如“你”、“我”、“他”。如果包含的话就返回输入页面,否则继续执行到PersonAction。我需要先理清楚Struts拦截器的基本结构,然后考虑如何获取用户输入的用户名,再进行检查。
首先,拦截器需要继承AbstractInterceptor或者实现Interceptor接口。这里可能用AbstractInterceptor更方便,因为可能不需要处理init和destroy方法。然后,在intercept方法中,要获取ActionContext,从而访问请求参数。根据引用[4],ActionContext是通过请求创建的,里面存放了session、参数等数据,以Map形式存在。所以可以通过ActionContext来获取参数。用户输入的用户名应该是在请求参数中的一个字段,比如username。需要从parameters中获取这个值。但是要注意,Struts中的参数是通过ActionContext.getContext().getParameters()获取的,这可能是一个Map<String, Object>,而每个参数可能是一个字符串数组,比如parameters.get("username")返回的是String[]。所以需要取第一个元素,或者转换成字符串。接下来,检查这个用户名是否包含“你”、“我”、“他”中的任何一个字符。可以用Java的String的contains方法,逐个检查。或者用正则表达式来匹配,可能会更高效一些。例如,使用Pattern和Matcher,判断是否匹配[你我他]。如果检测到有这些字符,就需要返回一个结果,比如"input",这样Struts就会跳转到对应的输入页面。否则,继续执行后续的拦截器和Action。这可以通过调用invocation.invoke()来继续执行,而如果要中断,就返回一个字符串结果,对应struts.xml中的result配置。然后,配置拦截器。在struts.xml中,需要定义拦截器,并在action中引用它。根据引用[2],拦截器链是按照配置顺序执行的,所以需要将自定义拦截器添加到action的拦截器栈中。注意,如果使用了自定义拦截器,默认的拦截器栈可能不会被自动包含,所以可能需要显式引用默认栈,如defaultStack,然后再添加自己的拦截器。另外,用户可能需要处理类型转换或者参数获取的问题,比如如果username参数不存在,或者获取时出现异常,应该如何处理。可能需要添加一些错误处理,比如返回一个错误页面或者日志记录。
最后,编写拦截器的代码,实现上述逻辑,并配置到struts.xml中。测试的时候,需要确保当用户名包含特定字符时,确实返回输入页面,否则继续执行PersonAction。可能还需要考虑拦截器的顺序,确保在参数准备好之后执行,比如在params拦截器之后。因为params拦截器负责将请求参数设置到Action中,如果自定义拦截器在params之前执行,可能无法获取到参数。所以需要在配置拦截器时,将自定义拦截器放在params之后,或者使用默认栈,然后添加自己的拦截器,因为默认栈已经包含params拦截器。
总结一下步骤:创建拦截器类,重写intercept方法,获取username参数,检查是否包含特定字符,根据结果返回相应的结果或者继续执行。配置拦截器和action,确保拦截器正确应用。</think>### 分步解决方案:创建自定义用户名验证拦截器
#### 一、创建拦截器类
```java
package com.example.interceptor;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class UsernameValidatorInterceptor extends AbstractInterceptor {
private static final Pattern INVALID_CHARS = Pattern.compile("[你我他]");
@Override
public String intercept(ActionInvocation invocation) throws Exception {
// 获取请求参数Map[^4]
Map<String, Object> parameters = ActionContext.getContext().getParameters();
// 获取用户名参数(注意处理数组类型)
String[] usernameArr = (String[]) parameters.get("username");
if (usernameArr == null || usernameArr.length == 0) {
return "input"; // 返回输入页面
}
String username = usernameArr[0];
// 检查非法字符
if (INVALID_CHARS.matcher(username).find()) {
return "input"; // 返回输入页面
}
return invocation.invoke(); // 继续执行PersonAction
}
}
```
#### 二、配置struts.xml
```xml
<struts>
<package name="user" extends="struts-default">
<!-- 定义拦截器 -->
<interceptors>
<interceptor name="usernameValidator"
class="com.example.interceptor.UsernameValidatorInterceptor"/>
<!-- 创建包含默认拦截器栈和自定义拦截器的栈 -->
<interceptor-stack name="customStack">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="usernameValidator"/>
</interceptor-stack>
</interceptors>
<!-- 配置PersonAction -->
<action name="personAction" class="com.example.action.PersonAction">
<interceptor-ref name="customStack"/>
<result name="input">/user-input.jsp</result>
<result name="success">/person.jsp</result>
</action>
</package>
</struts>
```
#### 三、关键实现原理
1. **参数获取机制**
- 通过`ActionContext.getContext().getParameters()`获取请求参数Map[^4]
- 参数以`String[]`形式存储,需转换为数组后取第一个元素
2. **正则表达式验证**
使用预编译正则表达式提高效率:
$$ \text{正则模式} = [你我他] $$
匹配到任意禁用字符时返回输入页面
3. **拦截器执行流程**
```mermaid
sequenceDiagram
用户请求->>拦截器: 触发personAction
拦截器->>拦截器: 检查username参数
alt 包含禁用字符
拦截器-->>用户: 返回user-input.jsp
else 参数合法
拦截器->>PersonAction: 执行业务逻辑
PersonAction-->>用户: 返回person.jsp
end
```
#### 四、增强建议
1. **错误信息国际化**
在资源文件中定义错误提示:
```properties
username.invalid=用户名包含非法字符
```
在拦截器中添加错误信息:
```java
ActionContext.getContext().addFieldError("username",
getText("username.invalid"));
```
2. **动态配置禁用字符**
通过拦截器参数实现可配置化:
```xml
<interceptor-ref name="usernameValidator">
<param name="forbiddenChars">你我他</param>
</interceptor-ref>
```
拦截器类添加参数接收:
```java
private String forbiddenChars;
// 自动接收配置参数
public void setForbiddenChars(String forbiddenChars) {
this.INVALID_CHARS = Pattern.compile("[" + forbiddenChars + "]");
}
```
阅读全文