当前位置: 首页 > news >正文

第十二章 Spring MVC 框架扩展和SSM框架整合(2023版本IDEA)

学习目标

  • 12.1 Spring MVC 框架处理JSON数据
    • 12.1.1 JSON数据的传递处理
    • 12.1.2 JSON数据传递过程中的中文乱码和日期问题
    • 12.1.3 多视图解析器
  • 12.2 Spring MVC 框架中的数据格式转换
    • 12.2.1 Spring MVC 框架数据转换流程
    • 12.2.2 编写自定义转换器
    • 12.2.3 使用@InitBinder装配自定义编辑器
  • 12.3 SSM框架整合
    • 12.3.1 SSM 框架简介
    • 12.3.2 SSM框架搭建

  前面章节中,系统的升级改造过程中遗留了一些和异步请求相关的功能,本章将完善这些内容,并学习Spring MVC 框架中数据转换、数据格式化处理的相关知识。(如果没有了解可以去我主页看看 第一至十一章的内容来学习)通过学习本章内容,我们将理解Spring MVC 框架处理JSON时间传递、多视图解析器的工作原理和数据格式转换的基本概念及流程,完成Spring MVC+Spring+MyBatis(SSM)框架的搭建工作。

12.1 Spring MVC 框架处理JSON数据

  JSON格式数据在现阶段的Web项目开发中扮演着非常重要的角色。在前端页面和后台交互的过程中,需要一种格式清晰、高效且两端都可以轻松使用的数据格式做交互的媒介,JSON正可以满足这一需求。

12.1.1 JSON数据的传递处理

在Java中处理JSON数据的传递通常涉及到序列化和反序列化操作。序列化是将Java对象转换为JSON格式的字符串,以便可以将其存储或通过网络传输;反序列化则是将JSON格式的字符串转换回Java对象。在Java中,有很多库可以帮助我们完成这些操作,如Jackson、Gson等。

以下是一个使用Jackson库进行JSON数据传递处理的简单示例。

1. 添加Jackson依赖
首先,你需要在你的项目中添加Jackson的依赖。如果你使用的是Maven,可以在pom.xml文件中添加如下依赖:

<dependency>  <groupId>com.fasterxml.jackson.core</groupId>  <artifactId>jackson-databind</artifactId>  <version>2.13.0</version>  
</dependency>

2. 创建一个Java类
接下来,创建一个Java类,用于表示你要序列化和反序列化的数据。

public class User {  private String name;  private int age;  // 构造方法、getter和setter省略  public User(String name, int age) {  this.name = name;  this.age = age;  }  // 省略getter和setter方法  @Override  public String toString() {  return "User{" +  "name='" + name + '\'' +  ", age=" + age +  '}';  }  
}

3. 序列化Java对象为JSON字符串
现在,你可以使用Jackson的ObjectMapper类来将User对象序列化为JSON字符串。

import com.fasterxml.jackson.databind.ObjectMapper;  public class JsonSerializerExample {  public static void main(String[] args) {  try {  User user = new User("John Doe", 30);  ObjectMapper objectMapper = new ObjectMapper();  String jsonString = objectMapper.writeValueAsString(user);  System.out.println(jsonString);  } catch (Exception e) {  e.printStackTrace();  }  }  
}

4. 反序列化JSON字符串为Java对象
同样地,你可以使用ObjectMapper类将JSON字符串反序列化为Java对象。

import com.fasterxml.jackson.databind.ObjectMapper;  public class JsonDeserializerExample {  public static void main(String[] args) {  try {  String jsonString = "{\"name\":\"Jane Doe\",\"age\":28}";  ObjectMapper objectMapper = new ObjectMapper();  User user = objectMapper.readValue(jsonString, User.class);  System.out.println(user);  } catch (Exception e) {  e.printStackTrace();  }  }  
}

以上代码展示了如何在Java中使用Jackson库来处理JSON数据的序列化和反序列化。当然,你也可以选择使用Gson等其他库来完成这些操作,不同的库在使用上可能略有不同,但基本思想是一致的。

12.1.2 JSON数据传递过程中的中文乱码和日期问题

在处理JSON数据传递时,中文乱码和日期格式问题是很常见的。这些问题通常发生在数据被序列化为JSON字符串,或者从JSON字符串反序列化为Java对象的过程中。以下是如何在Java中处理这些问题的示例,这里仍然使用Jackson库。

1. 中文乱码问题
中文乱码问题通常是因为字符集不匹配导致的。在Java中,确保你的源数据(如字符串、文件等)和目标环境(如JSON库、网络传输等)都使用UTF-8或其他支持中文的字符集。Jackson库默认使用UTF-8编码,所以通常不需要额外配置。

但是,如果你在处理文件或网络传输时遇到了中文乱码,请确保在读写这些资源时也使用了正确的字符集。

2. 日期格式问题
日期格式问题通常是因为JSON字符串中的日期格式与Java对象中的日期类型(如java.util.Date、java.time.LocalDate等)不匹配。Jackson提供了多种方式来处理这个问题,包括自定义序列化器和反序列化器,以及使用@JsonFormat注解。

使用@JsonFormat注解
你可以在你的Java对象的日期字段上使用@JsonFormat注解来指定日期格式。这样,Jackson在序列化和反序列化时就会按照指定的格式来处理这些字段。

import com.fasterxml.jackson.annotation.JsonFormat;  
import java.util.Date;  public class Event {  private String name;  @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")  private Date startTime;  // 构造方法、getter和setter省略  
}

在这个例子中,startTime字段会被序列化为"yyyy-MM-dd HH:mm:ss"格式的字符串,并且在反序列化时也会按照这个格式来解析。

自定义序列化器和反序列化器
对于更复杂的日期处理,你可能需要自定义序列化器和反序列化器。这可以通过继承JsonSerializer和JsonDeserializer类,并实现相应的方法来完成。

但是,对于大多数常见情况,使用@JsonFormat注解已经足够。

完整示例
下面是一个完整的示例,展示了如何序列化一个包含中文和日期的Java对象为JSON字符串,并反序列化回来。

import com.fasterxml.jackson.annotation.JsonFormat;  
import com.fasterxml.jackson.databind.ObjectMapper;  import java.io.IOException;  
import java.text.ParseException;  
import java.text.SimpleDateFormat;  
import java.util.Date;  public class JsonExample {  public static void main(String[] args) {  try {  Event event = new Event("活动名称", new Date());  ObjectMapper objectMapper = new ObjectMapper();  String jsonString = objectMapper.writeValueAsString(event);  System.out.println(jsonString);  Event deserializedEvent = objectMapper.readValue(jsonString, Event.class);  System.out.println(deserializedEvent);  } catch (IOException e) {  e.printStackTrace();  }  }  static class Event {  private String name;  @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")  private Date startTime;  public Event(String name, Date startTime) {  this.name = name;  this.startTime = startTime;  }  // 省略getter和setter方法  @Override  public String toString() {  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  sdf.setTimeZone(java.util.TimeZone.getTimeZone("GMT+8"));  return "Event{" +  "name='" + name + '\'' +  ", startTime=" + sdf.format(startTime) +  '}';  }  }  
}

请注意,我在@JsonFormat注解中添加了timezone = "GMT+8"属性来确保日期时间按照东八区的时间来格式化。同时,在toString方法中,我也使用了SimpleDateFormat来格式化日期,并设置了相同的时区,以确保打印出的日期时间与JSON中的一致。

12.1.3 多视图解析器

在Java Web开发中,特别是使用Spring MVC框架时,多视图解析器(Multiple View Resolvers)允许你根据请求的不同类型或条件来解析不同的视图。例如,你可能想要对于JSON请求使用JSON视图解析器,而对于HTML请求使用JSP或Thymeleaf等模板引擎。

下面是一个使用Spring MVC配置多视图解析器的简单示例。这个示例将包括两个视图解析器:一个用于JSP文件,另一个假设是一个用于某种非HTML视图(如JSON)的自定义视图解析器(实际上,对于JSON,你可能不需要专门的视图解析器,因为你可以直接在Controller中返回数据,并使用@ResponseBody注解)。但这里为了演示目的,我将展示如何配置两个视图解析器。

首先,你需要在Spring配置文件中(或者如果你使用的是Java配置,则在配置类中)配置视图解析器。

Java配置示例
如果你使用的是Java配置(基于@Configuration的类),可以像下面这样配置多视图解析器:

import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.web.servlet.ViewResolver;  
import org.springframework.web.servlet.view.InternalResourceViewResolver;  
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;  import java.util.Properties;  @Configuration  
public class ViewResolverConfig {  @Bean  public InternalResourceViewResolver internalResourceViewResolver() {  InternalResourceViewResolver resolver = new InternalResourceViewResolver();  resolver.setPrefix("/WEB-INF/views/");  resolver.setSuffix(".jsp");  return resolver;  }  // 注意:实际上对于JSON,你可能不需要专门的ViewResolver  // 这里仅作为示例,展示如何配置另一个ViewResolver  @Bean  public ViewResolver jsonViewResolver() {  // 自定义的ViewResolver,这里用MappingJackson2JsonView作为示例  // 但在实际中,你可能直接在Controller中返回数据并使用@ResponseBody  return new ViewResolver() {  @Override  public View resolveViewName(String viewName, Locale locale) throws Exception {  // 这里可以根据viewName或其他条件来返回不同的View  // 但对于JSON,这通常不是必需的  MappingJackson2JsonView jsonView = new MappingJackson2JsonView();  // 可以设置一些属性,比如是否美化JSON输出等  jsonView.setPrettyPrint(true);  return jsonView;  }  };  }  // 注意:上面的jsonViewResolver实际上并不常用,因为Spring MVC提供了  // 更好的方式来处理JSON响应,即直接在Controller中返回对象并使用@ResponseBody注解。  
}

注意事项

  1. 对于JSON:如上所述,你通常不需要为JSON响应配置专门的视图解析器。相反,你可以在Controller方法上使用@ResponseBody注解,并直接返回对象或ResponseEntity,Spring MVC会自动使用配置的HttpMessageConverter(如MappingJackson2HttpMessageConverter)来将对象序列化为JSON。
  2. 视图解析器顺序:如果有多个视图解析器,Spring MVC会按照配置的顺序尝试它们,直到找到能解析给定视图名的解析器为止。
  3. 自定义视图解析器:如果你需要特殊的视图处理逻辑(例如,基于请求参数动态选择视图),你可以实现自己的ViewResolver。但请注意,对于大多数用例,Spring MVC提供的标准视图解析器应该就足够了。

12.2 Spring MVC 框架中的数据格式转换

在Spring MVC框架中,数据格式转换是一个常见且重要的功能,它允许你自动地在请求参数、模型属性和响应体之间转换数据格式。Spring MVC通过一系列机制来实现这一功能,包括但不限于类型转换(ConversionService)、格式化(Formatter)、编辑器(PropertyEditor)以及@RequestBody和@ResponseBody注解的使用。

下面我将通过几个示例来说明如何在Spring MVC中实现数据格式转换。

1. 使用@RequestBody和@ResponseBody进行JSON转换
这是最常见的数据格式转换场景之一,通常用于RESTful API的开发。Spring MVC通过配置HttpMessageConverters来支持JSON的自动序列化和反序列化。

Controller示例:

import org.springframework.web.bind.annotation.PostMapping;  
import org.springframework.web.bind.annotation.RequestBody;  
import org.springframework.web.bind.annotation.ResponseBody;  
import org.springframework.web.bind.annotation.RestController;  @RestController  
public class UserController {  @PostMapping("/user")  public @ResponseBody User createUser(@RequestBody User user) {  // 处理用户数据...  return user; // 直接返回User对象,Spring MVC会将其转换为JSON  }  
}  // 假设有一个User类  
public class User {  private String name;  private int age;  // getters and setters  
}

在这个例子中,Spring MVC自动将传入的JSON数据转换为User对象,并将返回的User对象序列化为JSON。这通常是通过配置Jackson或Gson作为HttpMessageConverter来实现的。

2. 自定义类型转换器(ConversionService)
当你需要在Spring MVC的绑定过程中自定义类型转换逻辑时,可以实现并注册Converter或ConverterFactory,并通过ConversionService进行管理。

自定义转换器示例:

import org.springframework.core.convert.converter.Converter;  
import org.springframework.stereotype.Component;  @Component  
public class StringToUserConverter implements Converter<String, User> {  @Override  public User convert(String source) {  // 这里是自定义的转换逻辑,例如从某种格式的字符串解析User对象  // ...  return new User(); // 示例返回  }  
}

然后,你需要在Spring MVC的配置中注册这个转换器。如果你使用的是Java配置,可以通过WebMvcConfigurer接口来实现。

3. 使用Formatter进行字段格式化
Formatter接口用于在Spring MVC的绑定过程中格式化字段。与Converter不同,Formatter是针对特定字段和类型的,并且它考虑了语言环境。

自定义Formatter示例:

import org.springframework.format.Formatter;  
import java.text.ParseException;  
import java.text.SimpleDateFormat;  
import java.util.Date;  
import java.util.Locale;  public class CustomDateFormatter implements Formatter<Date> {  private final String dateFormat;  public CustomDateFormatter(String dateFormat) {  this.dateFormat = dateFormat;  }  @Override  public String print(Date object, Locale locale) {  SimpleDateFormat sdf = new SimpleDateFormat(dateFormat, locale);  return sdf.format(object);  }  @Override  public Date parse(String text, Locale locale) throws ParseException {  SimpleDateFormat sdf = new SimpleDateFormat(dateFormat, locale);  return sdf.parse(text);  }  
}

然后,你需要在Spring MVC的配置中注册这个Formatter。

结论
Spring MVC提供了多种机制来实现数据格式转换,从简单的JSON序列化和反序列化,到复杂的自定义类型转换和字段格式化。你可以根据具体需求选择合适的机制来实现数据格式转换。

12.2.1 Spring MVC 框架数据转换流程

在Spring MVC框架中,数据转换流程是一个复杂但高度集成的过程,它涉及到多个组件和接口。这里,我将概述Spring MVC中数据转换的基本流程,并提供一些关键的Java代码片段来说明这一过程。

数据转换流程概述

  1. 请求接收: 客户端(如浏览器或另一个服务)发送HTTP请求到服务器。
  2. 请求分发: Spring MVC的DispatcherServlet接收请求,并根据请求URL和配置的映射找到对应的Controller和HandlerMethod。
  3. 参数解析: DispatcherServlet使用HandlerMethodArgumentResolver接口的实现来解析请求中的参数。这包括从请求体(@RequestBody)、路径变量、查询参数等中解析数据。
  4. 数据转换:
    类型转换器(ConversionService): 用于在简单类型之间转换,如String到Integer。
    格式化器(Formatter): 用于特定类型的格式化,如日期或货币,考虑语言环境。
    HTTP消息转换器(HttpMessageConverter): 用于在请求体和响应体中读写数据,如JSON、XML等。
  5. 方法调用: 解析并转换后的参数被传递给Controller中的方法。
  6. 结果处理: Controller方法执行后,返回的结果(可能是视图名、模型数据或响应体)被处理。
  7. 响应发送: 处理后的结果通过DispatcherServlet和配置的视图解析器(如果需要的话)发送给客户端。

关键代码片段
1. 控制器方法示例

@RestController  
public class UserController {  @PostMapping("/user")  public User createUser(@RequestBody User user) {  // 处理用户数据...  return user; // 直接返回User对象,Spring MVC会将其转换为JSON  }  
}

2. 配置HttpMessageConverter(通常通过配置类自动完成)

@Configuration  
public class WebConfig implements WebMvcConfigurer {  @Override  public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {  converters.add(new MappingJackson2HttpMessageConverter()); // Jackson JSON转换器  // 可以添加其他转换器,如XML等  }  
}

注意:在Spring Boot应用中,MappingJackson2HttpMessageConverter通常会自动配置,无需手动添加。

3. 自定义Formatter注册

@Configuration  
public class FormatterConfig implements FormattingConversionServiceConfigurer {  @Override  public void configureFormattingConversionService(FormattingConversionService conversionService) {  conversionService.addFormatter(new CustomDateFormatter("yyyy-MM-dd"));  }  // CustomDateFormatter的实现(如上所示)  
}

4. 自定义Converter注册(如果需要)
自定义Converter的注册通常通过将其声明为Spring组件(使用@Component注解)来自动完成。但是,如果你需要更细粒度的控制,可以在配置类中通过ConversionServiceFactoryBean来注册它们。

5. 自定义HandlerMethodArgumentResolver(高级用法)
如果你需要处理特殊的参数解析逻辑,可以实现HandlerMethodArgumentResolver接口。这通常用于处理Spring MVC默认不支持的复杂场景。

@Component  
public class CustomArgumentResolver implements HandlerMethodArgumentResolver {  // 实现解析逻辑  
}  // 然后在配置类中注册它  
@Override  
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {  resolvers.add(new CustomArgumentResolver());  
}

注意:上面的addArgumentResolvers方法需要在实现了WebMvcConfigurer接口的类中重写。

结论
Spring MVC的数据转换流程是一个高度可配置和可扩展的过程,它允许开发者通过实现各种接口和注册组件来定制请求处理和响应生成的行为。上述代码片段提供了数据转换流程中一些关键步骤的示例。

12.2.2 编写自定义转换器

在Java中,特别是在使用Spring框架时,编写自定义转换器(Converter)通常涉及实现org.springframework.core.convert.converter.Converter接口或继承org.springframework.core.convert.converter.ConverterFactory(如果你需要更复杂的转换逻辑,能够处理多个源类型或目标类型)。下面是一个简单的自定义转换器示例,它将一个字符串转换为自定义的User对象。

首先,定义你的User类(假设它有两个属性:id和name):

public class User {  private Long id;  private String name;  // 构造函数、getter和setter省略  public User(Long id, String name) {  this.id = id;  this.name = name;  }  // getters and setters  public Long getId() {  return id;  }  public void setId(Long id) {  this.id = id;  }  public String getName() {  return name;  }  public void setName(String name) {  this.name = name;  }  // toString()方法可以帮助我们在转换后看到结果  @Override  public String toString() {  return "User{" +  "id=" + id +  ", name='" + name + '\'' +  '}';  }  
}

然后,编写你的自定义转换器,它实现了Converter接口:

import org.springframework.core.convert.converter.Converter;  
import org.springframework.stereotype.Component;  @Component  
public class StringToUserConverter implements Converter<String, User> {  @Override  public User convert(String source) {  // 这里是一个简单的字符串解析逻辑,假设字符串格式为"id,name"  String[] parts = source.split(",");  if (parts.length != 2) {  throw new IllegalArgumentException("String must be in the format 'id,name'");  }  try {  Long id = Long.parseLong(parts[0].trim());  String name = parts[1].trim();  return new User(id, name);  } catch (NumberFormatException e) {  throw new IllegalArgumentException("ID must be a valid number", e);  }  }  
}

注意,这里我使用了@Component注解来标记这个转换器,这样Spring就能够自动检测到它并注册到Spring的上下文中。但是,对于自定义转换器,你还需要确保Spring知道如何使用它。这通常是通过在配置类中注册ConversionService来完成的,但如果你使用的是Spring Boot,并且你的转换器被标记为@Component,那么Spring Boot会自动为你处理这一切。

现在,当Spring MVC的控制器需要从一个请求参数或请求体中解析一个User对象时,并且如果请求中提供了符合"id,name"格式的字符串,Spring就会使用你的StringToUserConverter来执行转换。

请注意,上面的示例是一个非常简单的字符串到对象的转换。在实际应用中,你可能需要处理更复杂的情况,比如从JSON字符串到对象的转换,这通常是通过配置HttpMessageConverter(如Jackson或Gson的转换器)来完成的,而不是通过自定义的Converter。然而,对于那些不能通过标准HTTP消息转换器直接处理的情况,自定义转换器就非常有用了。

12.2.3 使用@InitBinder装配自定义编辑器

在Spring MVC中,@InitBinder注解用于在控制器中声明一个初始化数据绑定的方法,这个方法可以用来注册自定义的属性编辑器(PropertyEditor)或格式化器(Formatter)。但是,从Spring 3.0开始,推荐使用Formatter接口和FormattingConversionService来代替PropertyEditor,因为Formatter提供了更灵活的类型安全转换。不过,为了完整性,我将首先展示如何使用PropertyEditor,然后展示如何使用Formatter。

使用PropertyEditor
首先,你需要实现一个PropertyEditor来执行自定义的字符串到对象的转换。但是,请注意,直接在控制器中使用PropertyEditor并不是最佳实践,因为这会使得你的控制器与Spring的ConversionService机制解耦。不过,为了说明目的,我会展示一个简单的例子。

import org.springframework.beans.propertyeditors.CustomDateEditor;  
import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.WebDataBinder;  
import org.springframework.web.bind.annotation.InitBinder;  // 注意:这里我实际上不会展示自定义的PropertyEditor,而是使用CustomDateEditor作为示例  
@Controller  
public class MyController {  @InitBinder  public void initBinder(WebDataBinder binder) {  // 示例:注册一个自定义的日期编辑器  SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");  dateFormat.setLenient(false);  binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));  // 如果你要注册自定义的PropertyEditor,你需要实现PropertyEditorSupport并覆盖相应的方法  // binder.registerCustomEditor(YourClass.class, new YourCustomPropertyEditor());  }  
}

请注意,上面的例子实际上展示了如何注册一个CustomDateEditor,而不是一个完全自定义的PropertyEditor。对于自定义类型,你需要实现PropertyEditorSupport类并重写setAsText和getAsText方法。

使用Formatter
现在,让我们看一个使用Formatter的示例,这是更现代且推荐的方法。

首先,实现Formatter接口:

import org.springframework.format.Formatter;  
import java.text.ParseException;  
import java.text.SimpleDateFormat;  
import java.util.Date;  
import java.util.Locale;  public class CustomDateFormatter implements Formatter<Date> {  private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");  @Override  public String print(Date object, Locale locale) {  return dateFormat.format(object);  }  @Override  public Date parse(String text, Locale locale) throws ParseException {  return dateFormat.parse(text);  }  
}

然后,在你的配置中注册这个Formatter(如果你使用的是Java配置):

import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.format.FormatterRegistry;  
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;  @Configuration  
public class WebConfig implements WebMvcConfigurer {  @Override  public void addFormatters(FormatterRegistry registry) {  registry.addFormatter(customDateFormatter());  }  @Bean  public CustomDateFormatter customDateFormatter() {  return new CustomDateFormatter();  }  
}

或者,如果你使用的是XML配置,你可以通过mvc:annotation-driven标签的conversion-service属性来引用一个自定义的ConversionService,该服务注册了你的Formatter。

使用Formatter比PropertyEditor更灵活且类型安全,因为它允许你在方法签名中明确指定源类型和目标类型。此外,Formatter是Spring 3.0及更高版本中推荐的数据绑定和格式化机制。

12.3 SSM框架整合

SSM(Spring + Spring MVC + MyBatis)框架整合是Java Web开发中非常流行的一种架构方式。这里我将提供一个简单的示例来说明如何整合这三个框架。

1. 项目结构
首先,我们需要创建一个Maven项目,并设置其pom.xml文件以包含必要的依赖项。

<dependencies>  <!-- Spring -->  <dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-context</artifactId>  <version>5.3.10</version>  </dependency>  <dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-webmvc</artifactId>  <version>5.3.10</version>  </dependency>  <!-- MyBatis -->  <dependency>  <groupId>org.mybatis</groupId>  <artifactId>mybatis</artifactId>  <version>3.5.7</version>  </dependency>  <dependency>  <groupId>org.mybatis.spring.boot</groupId>  <artifactId>mybatis-spring-boot-starter</artifactId>  <version>2.1.4</version>  </dependency>  <!-- 数据库连接池 -->  <dependency>  <groupId>com.zaxxer</groupId>  <artifactId>HikariCP</artifactId>  <version>4.0.3</version>  </dependency>  <!-- 数据库驱动 -->  <dependency>  <groupId>mysql</groupId>  <artifactId>mysql-connector-java</artifactId>  <version>8.0.25</version>  </dependency>  <!-- Servlet API -->  <dependency>  <groupId>javax.servlet</groupId>  <artifactId>javax.servlet-api</artifactId>  <version>4.0.1</version>  <scope>provided</scope>  </dependency>  <!-- JSP API -->  <dependency>  <groupId>javax.servlet.jsp</groupId>  <artifactId>javax.servlet.jsp-api</artifactId>  <version>2.3.3</version>  <scope>provided</scope>  </dependency>  <!-- JSTL -->  <dependency>  <groupId>javax.servlet.jsp.jstl</groupId>  <artifactId>jstl-api</artifactId>  <version>1.2</version>  </dependency>  <dependency>  <groupId>taglibs</groupId>  <artifactId>standard</artifactId>  <version>1.1.2</version>  </dependency>  
</dependencies>

2. 配置Spring
在src/main/resources目录下创建applicationContext.xml文件来配置Spring的Bean。

<beans xmlns="http://www.springframework.org/schema/beans"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd">  <!-- 配置数据源 -->  <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"  destroy-method="close">  <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>  <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/yourdb?serverTimezone=UTC"/>  <property name="username" value="root"/>  <property name="password" value="password"/>  </bean>  <!-- 配置SqlSessionFactory -->  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  <property name="dataSource" ref="dataSource"/>  <!-- 引入MyBatis配置文件 -->  <property name="configLocation" value="classpath:mybatis-config.xml"/>  </bean>  <!-- Mapper扫描 -->  <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  <property name="basePackage" value="com.example.mapper"/>  </bean>  <!-- 其他Bean配置 -->  
</beans>

3. 配置Spring MVC
在web.xml中配置Spring MVC的前端控制器(DispatcherServlet)和Spring的监听器

12.3.1 SSM 框架简介

SSM(Spring + Spring MVC + MyBatis)框架是一个流行的Java Web开发框架组合,它结合了Spring的依赖注入和面向切面编程(AOP)能力、Spring MVC的Web层处理能力和MyBatis的持久层处理能力。下面我将简要介绍这三个框架的作用,并提供一些基本的Java代码示例来展示它们是如何协同工作的。

1. Spring
Spring是一个全面的、控制反转(IoC)和面向切面编程(AOP)的容器框架。它主要用于管理Java应用中的对象(称为beans),并促进松耦合设计。

Spring Bean 示例

@Component  
public class UserService {  @Autowired  private UserMapper userMapper;  public User getUserById(int id) {  return userMapper.selectByPrimaryKey(id);  }  
}

2. Spring MVC
Spring MVC是一个基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架。它主要用于Web层的开发,将Web层进行职责解耦,使得开发者更容易进行开发。

Spring MVC Controller 示例

@Controller  
@RequestMapping("/user")  
public class UserController {  @Autowired  private UserService userService;  @GetMapping("/{id}")  public String getUser(@PathVariable("id") int id, Model model) {  User user = userService.getUserById(id);  model.addAttribute("user", user);  return "userView"; // 假设有一个名为userView的JSP页面来展示用户信息  }  
}

3. MyBatis
MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,简单的Java对象)映射成数据库中的记录。

MyBatis Mapper XML 示例

<mapper namespace="com.example.mapper.UserMapper">  <select id="selectByPrimaryKey" resultType="com.example.domain.User">  SELECT * FROM user WHERE id = #{id}  </select>  
</mapper>

MyBatis Mapper 接口

public interface UserMapper {  User selectByPrimaryKey(int id);  
}

12.3.2 SSM框架搭建

SSM(Spring + Spring MVC + MyBatis)框架的搭建涉及多个步骤,包括项目结构的设置、依赖的引入、配置文件的编写以及各层代码的编写等。下面是一个简化的SSM框架搭建过程及关键Java代码示例。

  1. 项目结构设置
    首先,你需要创建一个Java Web项目,并设置好项目的结构。一般来说,SSM项目的结构会包括以下几个部分:
    – src/main/java:存放Java源代码。
    – src/main/resources:存放配置文件(如Spring配置文件、MyBatis映射文件等)和静态资源(如图片、CSS、JS等)。
    – src/main/webapp:存放Web资源,如JSP页面、HTML文件等。
    – pom.xml(如果使用Maven):项目的依赖管理文件。

2. 依赖引入
如果你使用Maven作为项目管理和构建工具,你需要在pom.xml文件中引入SSM框架所需的依赖。这通常包括Spring框架、Spring MVC、MyBatis、数据库连接池(如HikariCP或DBCP)、Servlet API等。

例如,引入Spring和MyBatis的依赖可能如下所示:

<!-- Spring核心依赖 -->  
<dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-context</artifactId>  <version>你的Spring版本</version>  
</dependency>  
<!-- Spring MVC依赖 -->  
<dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-webmvc</artifactId>  <version>你的Spring版本</version>  
</dependency>  
<!-- MyBatis依赖 -->  
<dependency>  <groupId>org.mybatis</groupId>  <artifactId>mybatis</artifactId>  <version>你的MyBatis版本</version>  
</dependency>  
<!-- MyBatis与Spring整合依赖 -->  
<dependency>  <groupId>org.mybatis.spring.boot</groupId>  <artifactId>mybatis-spring-boot-starter</artifactId>  <version>你的版本</version>  
</dependency>  
<!-- 数据库连接池依赖(示例为HikariCP) -->  
<dependency>  <groupId>com.zaxxer</groupId>  <artifactId>HikariCP</artifactId>  <version>你的HikariCP版本</version>  
</dependency>  
<!-- 数据库驱动依赖(以MySQL为例) -->  
<dependency>  <groupId>mysql</groupId>  <artifactId>mysql-connector-java</artifactId>  <version>你的MySQL驱动版本</version>  
</dependency>

注意:上面的版本号需要替换为你项目中实际使用的版本号。

3. 配置文件编写
SSM框架通常需要编写Spring配置文件(如applicationContext.xml)、Spring MVC配置文件(如dispatcherServlet-servlet.xml)以及MyBatis配置文件(如mybatis-config.xml)等。但是,随着Spring Boot的普及,很多配置可以通过注解和application.properties/application.yml文件来完成,从而简化配置过程。

4. Java代码编写
实体类(Entity)

public class User {  private Integer id;  private String name;  private String email;  // 省略getter和setter方法  
}

Mapper接口

@Mapper  
public interface UserMapper {  User selectByPrimaryKey(Integer id);  // 其他数据库操作方法  
}

Mapper XML
MyBatis Mapper XML文件用于定义SQL语句和映射规则。

<mapper namespace="com.example.mapper.UserMapper">  <select id="selectByPrimaryKey" resultType="com.example.domain.User">  SELECT * FROM user WHERE id = #{id}  </select>  <!-- 其他SQL映射 -->  
</mapper>

Service层

@Service  
public class UserService {  @Autowired  private UserMapper userMapper;  public User getUserById(Integer id) {  return userMapper.selectByPrimaryKey(id);  }  // 其他业务逻辑方法  
}

Controller层

package com.example.controller;  import com.example.service.UserService;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.PostMapping;  
import org.springframework.web.bind.annotation.RequestBody;  
import org.springframework.web.bind.annotation.ResponseBody;  @Controller  
public class UserController {  @Autowired  private UserService userService;  @PostMapping("/login")  @ResponseBody  public Map<String, Object> login(@RequestBody UserLoginDTO userLoginDTO) {  Map<String, Object> result = new HashMap<>();  User user = userService.login(userLoginDTO.getUsername(), userLoginDTO.getPassword());  if (user != null) {  result.put("code", 200);  result.put("message", "登录成功");  result.put("user", user);  } else {  result.put("code", 401);  result.put("message", "用户名或密码错误");  }  return result;  }  // 其他请求处理方法...  
}

相关文章:

第十二章 Spring MVC 框架扩展和SSM框架整合(2023版本IDEA)

学习目标 12.1 Spring MVC 框架处理JSON数据12.1.1 JSON数据的传递处理12.1.2 JSON数据传递过程中的中文乱码和日期问题12.1.3 多视图解析器 12.2 Spring MVC 框架中的数据格式转换12.2.1 Spring MVC 框架数据转换流程12.2.2 编写自定义转换器12.2.3 使用InitBinder装配自定义编…...

js中的全局函数有这些

js中的全局函数有这些,记忆规则 6个编译 escape、‌‌unescape、decodeURI、decodeURIComponent、encodeURI、encodeURIComponent 2个数据处理 Number()、String() 4个数字处理 ‌isFinite、isNaN、‌parseFloat、parseInt 1个特殊情况 eval()...

Android SurfaceFlinger——重绘闪烁处理(四十六)

在帧数据准备完成后,下一步是调用 devOptRepaintFlash() 函数处理显示输出设备的可选重绘闪烁问题,这里我们就来看一下重绘闪屏问题的处理方案。 1.更新输出设备的色彩配置文件2.更新与合成相关的状态3.计划合成帧图层4.写入合成状态5.设置颜色矩阵6.开始帧7.准备帧数据以进行…...

罗马数字转整数 C++

罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如&#x…...

Day20_2--介绍同步加载和异步加载

同步加载和异步加载是处理程序或数据的两种不同方式&#xff0c;它们在处理任务的方式、效率和用户体验上有显著差异。下面是对这两种加载机制的详细介绍。 1. 同步加载&#xff08;Synchronous Loading&#xff09; 定义&#xff1a; 同步加载是一种加载数据或资源的方式&am…...

sftp做成一个池子

前言&#xff1a;开发中的需求要去对方的 ftp 服务器下载文件&#xff0c;这里下载文件采用 ftp 方式&#xff0c;下载之后程序再去解析文件的内容&#xff0c;然后再存数据库。下载过来的文件默认是 zip 格式&#xff0c;需要解压 unzip 一下&#xff0c;然后里面有一个 csv 文…...

全网最全-Netty从入门到精通

XiaoYongCai/2024/8/6 一&#xff1a;Netty入门 1.Netty概述 A.Netty的定义 Netty是一个提供异步事件驱动的网络应用程序框架和工具&#xff0c;用以快速开发高性能、高可靠性的网络服务器和客户端程序。在Java领域&#xff0c;Netty被认为是除了Java原生NIO之外的最佳网络…...

C#知识|文件与目录操作:对象的创建、保存、读取

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 面向对象编程的特点就是一切皆对象&#xff0c;操作的也是对象&#xff0c;本节学习文件与目录操作中&#xff0c;对象的保存&#xff1b; 以下为学习笔记。 01 对象的特点 ①&#xff1a;对象运行在内存中&#xff…...

自定义 SwiftUI 中符号图像的外观

文章目录 前言大小颜色渲染模式单色分层调色板多色 可变值设计变体示例代码结论 前言 符号图像是来自 Apple的SF Symbols 库的矢量图标&#xff0c;设计用于在 Apple 平台上使用。这些可缩放的图像适应不同的大小和重量&#xff0c;确保在我们的应用程序中具有一致的高质量图标…...

循环神经网络和自然语言处理一

目录 一.分词 1.分词工具 2.分词的方法 3.N-gram表示方法 二.向量化 1.one-hot编码 2.word embedding 3.word embedding API 4.数据形状改变 既然是自然语言&#xff0c;那么就有字&#xff0c;词&#xff0c;句了 一.分词 1.分词工具 tokenization&#xff0c;jie…...

CSS技巧专栏:一日一例 20-纯CSS实现点击会凹陷的按钮

本例图片 案例分析 其实这个按钮非常的简单啊,主要就是利用了box-shadow的inset。 布局代码 <button class="base">凹下的按钮</button> 基础样式 :root{--main-bg-color: #dcdcdc; /* 将页面背景色调整为浅灰色 */--color:#000;--hover-color:#99…...

20240807 每日AI必读资讯

&#x1f468;‍&#x1f4bc;马斯克再发难、OpenAI 高层巨变&#xff1a;两大核心人物离职&#xff0c;总裁休长假到年底 - OpenAI 联合创始人 John Schulman 官宣离职&#xff0c;加入原是竞品公司的 Anthropic - 陪伴 OpenAI 共同成长 9 年的总裁兼联合创始人 Greg Brockm…...

海外社媒账号如何让防关联?账号隔离的5大要点

在跨境电商迅速发展和全球化营销的背景下&#xff0c;海外社交媒体平台成为外贸人拓展市场的关键阵地。因此&#xff0c;为了保障账号安全&#xff0c;实现高效推广&#xff0c;账号隔离以及安全防关联对外贸人来说至关重要。本文将盘点引起海外社媒账号关联的原因及其五大解决…...

下一代 AI 搜索引擎 MindSearch:多智能体 + 系统2,模拟人类认知过程的 AI 搜索引擎

下一代 AI 搜索引擎 MindSearch&#xff1a;多智能体 系统2&#xff0c;模拟人类认知过程的 AI 搜索引擎 提出背景解法拆解实验评估开放集封闭集问答 论文大纲怎么进一步改进 MindSearch&#xff1f;1. 组合&#xff08;Combination&#xff09;2. 拆开&#xff08;Disassembl…...

一键生成专业PPT:2024年AI技术在PPT软件中的应用

不知道你毕业答辩的时候有没有做过PPT&#xff0c;是不是也被这个工具折磨过。没想到现在都有AI生成PPT的工具了吧&#xff1f;这次我就介绍几款可以轻松生成PPT的AI工具吧。 1.笔灵AIPPT 连接直达&#xff1a;​​​​​​​https://ibiling.cn/ppt-zone 这个工具我最早是…...

Godot学习笔记8——PONG游戏制作

目录 一、小球 二、地图 三、积分系统 四、玩家场景 五、导出与发布 PONG是1972年由雅达利公司推出的游戏&#xff0c;主要玩法为玩家控制两个可以上下移动的板子击打屏幕中不断运动的球 一、小球 我们首先创建一个“Area2D”场景&#xff0c;在它下方创建“Collisi…...

软件RAID配置实战(2个案例场景)

文章目录 3、软件RAID管理-mdadm工具安装mdadm组件格式示例选项说明mdadm命令其它常用选项 4、相关查询命令查看创建RAID的进度查看RAID磁盘详细信息查看文件系统的磁盘空间使用情况 5、RAID配置示例场景1&#xff1a;RAID5步骤 场景2&#xff1a;RAID10步骤 6、移除RAID阵列 接…...

# 基于MongoDB实现商品管理系统(2)

基于MongoDB实现商品管理系统&#xff08;2&#xff09; 基于 mongodb 实现商品管理系统之准备工作 1、案例需求 这里使用的不是前端页面&#xff0c;而是控制台来完成的。 具体的需求如下所示&#xff1a; 运行 查询所有 通过id查询详情 添加 - 通过id删除 2、案例分析 程…...

国标GB28181视频平台LntonCVS视频融合共享平台视频汇聚应用方案

近年来&#xff0c;国内视频监控应用迅猛发展&#xff0c;系统接入规模不断扩大&#xff0c;导致了大量平台提供商的涌现。然而&#xff0c;不同平台的接入协议千差万别&#xff0c;使得终端制造商不得不为每款设备维护多个不同平台的软件版本&#xff0c;造成了资源的严重浪费…...

java基础I/O

1,I/O流的概念&#xff1a; IO流代表的是一个数据输入的源或者输出的目标地址&#xff0c;可以是硬盘&#xff0c;内存&#xff0c;网络或者什么其他的电子设备&#xff0c;而IO流的类型也很多比如最简单的字节或者字符&#xff0c;或者其他更高级的对象。 不管它有多少特性&am…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...