1.MVC设计模式
MVC(Model-View-Controller)是一种常用的软件设计模式,用于将应用程序的逻辑和用户界面分离,以提高代码的可维护性和可扩展性。MVC模式由三个核心组件组成:Controller(控制器)、Model(模型)和View(视图)。
-
Controller(控制器):控制器负责接收和处理用户的输入,并根据输入调用相应的模型逻辑进行处理。它充当了模型和视图之间的中间人,协调模型和视图之间的交互。控制器通常包含各种处理用户请求的方法,接收来自视图的用户输入,并根据具体业务逻辑调用相关的模型进行数据处理或状态更新。
-
Model(模型):模型表示应用程序的数据和业务逻辑。它负责处理数据的读取、存储、验证以及业务规则的实现。模型通常包含数据对象、数据访问层(如数据库操作)、业务逻辑处理等。模型不关心用户界面的展示方式,它独立于视图和控制器,可以被多个视图共享。
-
View(视图):视图负责将模型的数据可视化展示给用户,并接收用户的输入。它通常是用户界面的实现,可以是Web页面、桌面应用程序的界面、移动应用程序的界面等。视图从模型中获取数据,并将其以用户友好的方式呈现给用户。视图可以向控制器发送用户输入的事件,以便控制器做出相应的处理。
MVC模式的优点包括:
- 分离关注点:MVC模式将应用程序的逻辑、数据和展示分离,使得每个组件都可以独立变化,易于维护和扩展。
- 可复用性:模型和视图之间的解耦使得它们可以被独立地开发和测试,并且可以在不同的场景中重用。
- 可测试性:由于各个组件之间的松耦合关系,可以更容易地对模型、视图和控制器进行单元测试。
- 并行开发:MVC模式允许开发团队中的不同成员同时开发不同的组件,提高开发效率。
总结来说,MVC模式通过将应用程序划分为三个独立的部分,即模型、视图和控制器,以实现逻辑与界面的分离。这种分离使得代码更加清晰、可维护,并促进了并行开发和测试。
2.spring提供的web框架
Spring提供了一个基于MVC设计理念的Web框架,称为Spring MVC。它是Spring框架的一部分,具有以下特点:
-
基于MVC设计理念:Spring MVC遵循经典的MVC(Model-View-Controller)模式,将应用程序的不同部分分离开来,使代码更加清晰和可维护。
-
松耦合可插拔的组件结构:Spring MVC提供了一组可插拔的组件,如控制器、视图解析器、处理器映射器等,这些组件可以根据需要进行配置和替换,使开发人员能够根据具体需求进行灵活的定制。
-
优越的扩展性和灵活性:Spring MVC采用了一种灵活的扩展机制,允许开发人员根据应用程序的特定需求进行定制和扩展。它支持各种视图技术(如JSP、Thymeleaf、Freemarker等),并且可以轻松集成其他框架和技术,如Hibernate、JPA、Spring Security等。
-
与Spring的无缝集成性:Spring MVC与Spring框架无缝集成,可以充分利用Spring框架的功能,如依赖注入、AOP等。它可以与其他Spring模块(如Spring Boot、Spring Data等)一起使用,形成一个完整的应用程序开发框架。
-
性能优越:Spring MVC通过使用轻量级的Servlet容器,如Tomcat或Jetty,以及优化的请求处理机制,提供了出色的性能和响应能力。它还支持异步请求处理,可以处理高并发的场景。
总而言之,Spring MVC是一个功能强大、灵活且性能优越的Web框架,它提供了丰富的特性和工具,使开发人员能够快速构建可扩展和可维护的Web应用程序。
3.Spring MVC体系结构
Spring MVC的体系结构主要由DispatcherServlet、框架结构和请求处理流程组成。
-
DispatcherServlet:
DispatcherServlet是Spring MVC的核心组件,负责接收所有的HTTP请求并将请求分发给相应的处理器。它作为前端控制器(Front Controller)处理所有的请求,并进行统一的请求处理流程管理。 -
框架结构:
Spring MVC的框架结构由多个组件组成,包括控制器(Controller)、模型(Model)、视图(View)、处理器映射器(Handler Mapping)、视图解析器(View Resolver)等。- 控制器(Controller):负责处理请求和构建模型数据。
- 模型(Model):用于封装和传递数据给视图。
- 视图(View):负责渲染模型数据并将结果返回给客户端。
- 处理器映射器(Handler Mapping):根据请求的URL映射到相应的控制器。
- 视图解析器(View Resolver):根据视图名称解析出真正的视图对象。
-
请求处理流程:
Spring MVC的请求处理流程包括以下步骤:- 客户端发送HTTP请求到服务器,请求被DispatcherServlet拦截。
- DispatcherServlet根据请求的URL通过处理器映射器找到对应的控制器。
- 控制器处理请求,并将处理结果封装到模型中。
- 控制器将模型和视图名称返回给DispatcherServlet。
- DispatcherServlet通过视图解析器解析出真正的视图对象。
- DispatcherServlet将模型数据传递给视图进行渲染。
- 视图将渲染结果返回给DispatcherServlet。
- DispatcherServlet将渲染结果返回给客户端。
总结起来,Spring MVC的体系结构由DispatcherServlet、多个组件和请求处理流程组成。DispatcherServlet作为前端控制器负责接收和分发请求,各个组件协作完成请求处理和视图渲染的过程。
2.基于注解的控制器
1.Contorller和View之间的映射
Controller和View之间的映射可以通过注解和配置来实现。
- 注解方式:
- @Controller:用于标识一个类为Controller组件,处理HTTP请求。
- @RequestMapping:用于将请求URL映射到Controller的方法上。
- @GetMapping:用于映射HTTP GET请求到Controller的方法上。
- @PostMapping:用于映射HTTP POST请求到Controller的方法上。
- @DeleteMapping:用于映射HTTP DELETE请求到Controller的方法上。
示例代码如下:
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public String getUser(@PathVariable("id") int id, Model model) {
User user = userService.getUserById(id);
model.addAttribute("user", user);
return "user"; // 返回视图名
}
@PostMapping("/")
public String createUser(User user) {
userService.createUser(user);
return "redirect:/users"; // 重定向到指定URL
}
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable("id") int id) {
userService.deleteUser(id);
return "redirect:/users"; // 重定向到指定URL
}
}
2.XML配置方式:
通过配置文件(如springmvc-servlet.xml)来进行映射配置。
示例配置如下:
<mvc:annotation-driven/> <!-- 启用注解驱动 -->
<bean id="userController" class="com.example.UserController"/>
<mvc:controller>
<mvc:mapping path="/users/**"/>
<mvc:view-controller path="/users" view-name="users"/> <!-- 配置默认视图 -->
<mvc:view-controller path="/users/{id}" view-name="user"/>
</mvc:controller>
在上述示例中,@Controller
注解标识UserController类为Controller组件。@RequestMapping
注解将URL路径"/users"映射到UserController类上。@GetMapping
、@PostMapping
、@DeleteMapping
注解分别将HTTP请求映射到对应的方法上。方法中使用Model
对象将数据传递给视图。最后,通过返回视图名或使用redirect:
进行重定向。
在XML配置中,<mvc:annotation-driven/>
标签启用注解驱动,<mvc:controller>
标签配置URL和视图的映射关系。
无论是注解方式还是XML配置方式,都可以实现Controller和View之间的映射。
3.入参处理
在Spring MVC中,可以通过多种方式处理方法的入参,包括使用Servlet API入参以及使用注解如@RequestParam、@ModelAttribute等。
- Servlet API入参:可以直接在方法参数中声明Servlet API相关的类型,如HttpServletRequest、HttpServletResponse等。例如:
@RequestMapping("/example")
public String example(HttpServletRequest request, HttpServletResponse response) {
// 处理请求和响应
return "view";
}
通过使用Servlet API入参,可以获得更底层的HTTP请求和响应对象,并进行相应的操作。
- @RequestParam注解:用于获取请求参数的值。可以将请求参数绑定到方法的参数上。例如:
@RequestMapping("/example")
public String example(@RequestParam("name") String name, @RequestParam(value = "age", required = false) Integer age) {
// 使用请求参数进行处理
return "view";
}
@RequestParam注解的常用属性包括name、value、required和defaultValue。其中,name和value可以指定要绑定的参数名,required指定参数是否是必需的,默认为true,defaultValue指定参数的默认值。
- @ModelAttribute注解:用于绑定请求参数到方法的参数或方法的返回值上。可以用于从表单中获取数据、转换数据类型等。例如:
@RequestMapping("/example")
public String example(@ModelAttribute User user) {
// 使用User对象进行处理
return "view";
}
在这个例子中,@ModelAttribute注解将会从请求中获取与User对象属性相匹配的参数,并将其绑定到User对象上。
通过使用Servlet API入参、@RequestParam注解和@ModelAttribute注解,可以方便地处理方法的入参,并根据具体需求获取请求参数、进行数据类型转换等操作。这些功能使得处理用户请求变得更加灵活和方便。
4.出参处理
出参处理是指在Spring MVC中处理Controller方法的返回值。Spring MVC提供了多种方式来处理出参,包括ModelAndView对象、Model对象和Map对象。
- ModelAndView对象:
ModelAndView对象是一种包含模型数据和视图名称的容器,用于将数据传递给视图并指定要渲染的视图。
示例代码如下:
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public ModelAndView getUser(@PathVariable("id") int id) {
User user = userService.getUserById(id);
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("user"); // 设置视图名称
modelAndView.addObject("user", user); // 添加模型数据
return modelAndView;
}
}
在上述示例中,通过创建一个ModelAndView对象,可以设置视图名称和添加模型数据,然后将其返回给Spring MVC框架。
- Model对象:
Model对象是一个接口,用于存储和传递模型数据给视图。它是Spring MVC框架中最常用的一种出参处理方式。
示例代码如下:
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public String getUser(@PathVariable("id") int id, Model model) {
User user = userService.getUserById(id);
model.addAttribute("user", user); // 添加模型数据
return "user"; // 返回视图名称
}
}
在上述示例中,通过方法参数中的Model对象,可以使用addAttribute()方法将模型数据添加到Model中,然后将视图名称返回给Spring MVC框架。
- Map对象:
Map对象可以用于存储和传递模型数据给视图,类似于Model对象。
示例代码如下:
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public String getUser(@PathVariable("id") int id, Map<String, Object> model) {
User user = userService.getUserById(id);
model.put("user", user); // 添加模型数据
return "user"; // 返回视图名称
}
}
在上述示例中,通过方法参数中的Map对象,可以使用put()方法将模型数据添加到Map中,然后将视图名称返回给Spring MVC框架。
以上是处理出参的几种常用方式,可以根据实际需求选择合适的方式来处理出参。
3.单例模式
单例模式是一种设计模式,用于确保一个类只有一个实例,并提供一个全局访问点来获取该实例。
- 懒汉模式(Lazy initialization):
在懒汉模式中,实例对象在第一次使用时才被创建。懒汉模式的特点是延迟加载,即在需要使用实例时才进行初始化。
示例代码如下:
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {
// 私有构造方法
}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
在上述示例中,LazySingleton类的实例对象在getInstance()方法中被创建,使用了synchronized关键字来保证线程安全。
- 饿汉模式(Eager initialization):
在饿汉模式中,实例对象在类加载时就被创建,无论是否使用。
示例代码如下:
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {
// 私有构造方法
}
public static EagerSingleton getInstance() {
return instance;
}
}
在上述示例中,EagerSingleton类的实例对象在类加载时就被创建,因此它是线程安全的。
区别:
- 懒汉模式是延迟加载的,只有在需要时才创建实例,但在多线程环境下需要考虑线程安全问题。
- 饿汉模式是在类加载时就创建实例,因此不存在线程安全问题,但可能会造成资源浪费,特别是在实例对象较大或需要耗费较多资源时。
选择:
- 如果对资源消耗较为敏感,或者希望实现延迟加载,可以选择懒汉模式。
- 如果希望简单且线程安全,并且实例对象较小,可以选择饿汉模式。
4.异常处理
1.局部异常处理
局部异常处理通过使用@ExceptionHandler注解来捕获和处理特定的异常。它可以在控制器类或者控制器方法上使用,用于处理该类或方法中抛出的异常。当异常被捕获时,可以执行一些特定的操作,例如返回一个错误页面或者返回一个错误信息。
示例代码:
@Controller
public class MyController {
@ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception ex) {
ModelAndView modelAndView = new ModelAndView("error");
modelAndView.addObject("errorMessage", "An error occurred: " + ex.getMessage());
return modelAndView;
}
@GetMapping("/example")
public String example() throws Exception {
// 业务逻辑代码
throw new Exception("Something went wrong");
}
}
上述代码中,handleException
方法使用了@ExceptionHandler
注解,用于捕获Exception
类型的异常。当example
方法中抛出异常时,该异常会被handleException
方法捕获并处理。处理结果会返回一个包含错误信息的ModelAndView
对象,用于渲染错误页面。
2.全局异常处理
全局异常处理通过使用SimpleMappingExceptionResolver
来捕获和处理整个应用程序中的异常。它可以配置在Spring的配置文件中,当应用程序中出现未处理的异常时,会被该处理器捕获并处理。
示例配置:
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.Exception">error</prop>
</props>
</property>
<property name="defaultErrorView" value="defaultError"/>
</bean>
上述配置中,exceptionMappings
属性指定了异常类型和对应的错误视图。当出现java.lang.Exception
类型的异常时,会返回名为error
的视图。defaultErrorView
属性指定了默认的错误视图,用于处理其他未匹配到的异常。
全局异常处理器可以处理整个应用程序中的异常,无需在每个控制器或方法上都添加异常处理的代码。但它可能会导致一些异常无法被捕获,例如404错误、请求方法不匹配等。因此,局部异常处理和全局异常处理可以结合使用,以提供更全面的异常处理能力。