SpringMVC控制器与视图层深入解析
立即解锁
发布时间: 2025-08-18 00:45:35 阅读量: 2 订阅数: 5 

### Spring MVC 控制器与视图层深入解析
#### 1. 控制器相关内容
在请求处理过程中,验证工作以分步的方式进行。当用户在向导中逐步操作时,每一步仅对命令 Bean 的部分内容进行验证。在向导的最后一步,会按顺序再次执行所有验证,从而对完整的命令 Bean 进行有效验证。不过,这种控制器不适用于任意工作流,对于复杂的状态变化和页面流程处理,建议使用 Spring Web Flow。
##### 1.1 ThrowawayController
对于请求/响应类型的 Web 框架建模,存在两种不同的观点。一种观点认为应将请求传递给无状态的处理程序,这正是 Servlet 和控制器的工作方式;另一种观点则主张使用命令模式对请求进行建模并直接执行,WebWork 就是这种方式的典型代表。Spring MVC 提供了 `org.springframework.web.servlet.mvc.throwaway.ThrowawayController` 来实现命令模式的请求处理。
传统的控制器通常是系统中的无状态单例,直接处理 `HttpServletRequest` 和 `HttpServletResponse` 对象以处理请求。而 `ThrowawayController` 则不同,它封装了请求的状态和行为,并且是原型 Bean,即每个请求都会创建一个新的实例,因此它甚至没有实现 `Controller` 接口。
以下是 `ThrowawayController` 接口的定义:
```java
public interface ThrowawayController {
ModelAndView execute() throws Exception;
}
```
请求参数会像绑定到命令 Bean 一样绑定到具体的子类。绑定完成且没有错误时,将调用 `execute()` 方法。需要注意的是,该控制器无法访问 `ServletRequest` 或 `HttpSession` 等 Servlet API 类,如果需要这些类,则应使用 `Controller` 接口。不过,这种设计也有好处,它使得该类的测试更加容易,无需创建 `MockHttpServletRequest` 来测试控制器。
那么,何时适合使用 `ThrowawayController` 呢?
- 当你希望将请求视为真正的命令对象时,`ThrowawayController` 是理想之选,它便于在系统中路由请求,并能调用控制器的方法来影响其状态。
- 如果控制器非常简单,且不需要访问 `HttpServletRequest` 和 `HttpServletResponse` 类,使用它可以更轻松地进行测试。
但在某些情况下,可能不适合使用该控制器:
- 当请求是只读的且不提交任何数据时,通常不需要状态,也就无需使用命令模式实现。
- 虽然可以使用 `ThrowawayController` 实现每个请求处理程序,但可能会导致更高的垃圾回收率,不过在现代 JVM 中,这种开销通常可以忽略不计。此外,它没有实现任何表单工作流,处理表单、验证和错误等操作会比较繁琐。
下面是一个 `ThrowawayController` 的示例——`CancelAccountController`:
```java
public class CancelAccountController implements ThrowawayController {
private AccountService accountService;
private String username;
public void setUsername(String username) {
this.username = username;
}
public void setAccountService(AccountService accountService) {
this.accountService = accountService;
}
public ModelAndView execute() throws Exception {
if (!StringUtils.hasText(username)) {
return new ModelAndView("cancelAccount", "errorMessage",
"Username must not be blank.");
}
try {
accountService.cancelAccount(username);
return new ModelAndView("cancelAccountSuccess");
} catch(AccountNotFoundException e) {
return new ModelAndView("cancelAccount", "errorMessage",
"No account found with username " + username);
}
}
}
```
配置该控制器时,需要在 Bean 定义中指定 `singleton="false"`,以确保每个请求都创建一个新实例。以下是 `CancelAccountController` 的 Bean 定义:
```xml
<bean name="/cancelAccount" singleton="false"
class="com.apress.expertspringmvc.flight.web.CancelAccountController">
<property name="accountService" ref="accountService" />
</bean>
```
需要注意的是,`ThrowawayController` 需要自己的 `ThrowawayControllerHandlerAdapter` 才能正常工作。如果在 `WebApplicationContext` 中指定并配置了一个或多个处理程序适配器,使用 `ThrowawayController` 时也需要包含 `ThrowawayControllerHandlerAdapter`。默认情况下,`DispatcherServlet` 会包含 `SimpleControllerHandlerAdapter` 和 `ThrowawayControllerHandlerAdapter`,但如果在 `WebApplicationContext` 中显式声明了至少一个处理程序适配
0
0
复制全文
相关推荐










