SSM后台如何高效传递JSON数据:从配置到实践
在Java Web开发中,SSM(Spring + Spring MVC + MyBatis)框架组合曾因灵活性和可扩展性被广泛使用,虽然如今前后端分离架构已成为主流,但许多传统项目仍基于SSM构建,而JSON作为前后端数据交互的“通用语言”,在SSM中的正确传递至关重要,本文将从环境配置、Controller层接收、Service层处理、MyBatis交互到响应返回,系统讲解SSM后台如何高效传递JSON数据。
核心环境配置:开启JSON支持
要让SSM框架支持JSON数据传递,首先需要配置Spring MVC的消息转换器,使其能自动解析请求体中的JSON数据,并将响应对象序列化为JSON格式,核心配置如下:
添加依赖
在pom.xml中引入Jackson库(Spring MVC默认集成,无需额外配置其他JSON库):
<!-- Jackson核心依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
</dependency>
<!-- Spring MVC Web依赖(已包含Jackson相关配置) -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.15</version>
</dependency>
配置Spring MVC
在spring-mvc.xml中开启注解驱动和JSON消息转换支持:
<!-- 开启Spring MVC注解驱动,自动注册HandlerMapping和HandlerAdapter -->
<mvc:annotation-driven/>
<!-- 若需自定义JSON配置(如日期格式、忽略null值等),可配置MessageConverter -->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<!-- 配置日期格式 -->
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg value="yyyy-MM-dd HH:mm:ss"/>
</bean>
</property>
<!-- 忽略null字段,减少响应数据量 -->
<property name="serializationInclusion" value="NON_NULL"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
配置web.xml
确保DispatcherServlet已加载Spring MVC配置:
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Controller层:接收与返回JSON数据
Controller层是前后端数据交互的入口,需处理两类场景:接收前端POST的JSON数据、向响应体返回JSON数据。
接收JSON数据:使用@RequestBody注解
前端通过POST请求发送JSON数据(如{"username":"zhangsan","age":18}),Controller层需用@RequestBody将请求体绑定到Java对象。
示例:接收用户信息
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 {
/**
* 接收JSON格式的用户数据
* @param user 前端JSON数据自动绑定到User对象
* @return 响应结果(返回JSON格式)
*/
@PostMapping("/user/save")
@ResponseBody // 标识该方法返回JSON(而非视图名)
public Result saveUser(@RequestBody User user) {
System.out.println("接收到的用户数据:" + user);
// 业务处理(如调用Service层保存数据)
// ...
return Result.success("用户保存成功");
}
}
// 实体类
class User {
private String username;
private Integer age;
// 省略getter/setter/构造方法
}
// 统一响应结果类(避免直接返回字符串或对象)
class Result {
private Integer code; // 200成功,500失败
private String message;
private Object data;
public static Result success(Object data) {
Result result = new Result();
result.setCode(200);
result.setMessage("操作成功");
result.setData(data);
return result;
}
// 省略getter/setter
}
关键说明:
@RequestBody:将HTTP请求体中的JSON数据反序列化为Java对象,要求请求头Content-Type为application/json(前端需设置headers: {'Content-Type': 'application/json'})。@ResponseBody:将Controller方法的返回对象序列化为JSON,并写入响应体(若类上标注@RestController,则无需在每个方法上加@ResponseBody)。
返回JSON数据:直接返回对象或Result
通过@ResponseBody,Spring MVC会自动将返回对象转换为JSON,推荐使用统一响应结果类(如Result),避免直接返回业务对象导致前端解析困难。
Service层与MyBatis:处理JSON数据
Service层主要负责业务逻辑处理,若涉及JSON数据的存储或查询(如将对象存储为JSON字符串到数据库字段),可通过MyBatis的类型处理器实现。
场景:将对象存储为JSON(如MySQL的JSON字段)
假设数据库user表中有一个info字段(类型为JSON),需将Java对象UserDetail存储为JSON字符串。
(1)添加MySQL驱动和MyBatis依赖
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!-- MyBatis分页插件(可选) -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.0</version>
</dependency>
(2)自定义类型处理器
创建UserDetail类型处理器,实现Java对象与JSON字符串的互转:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@MappedTypes(UserDetail.class) // 指定处理的Java类型
public class UserDetailTypeHandler extends BaseTypeHandler<UserDetail> {
private static final ObjectMapper objectMapper = new ObjectMapper();
// Java对象转JSON字符串(设置到PreparedStatement)
@Override
public void setNonNullParameter(PreparedStatement ps, int i, UserDetail parameter, JdbcType jdbcType) throws SQLException {
try {
String json = objectMapper.writeValueAsString(parameter);
ps.setString(i, json);
} catch (JsonProcessingException e) {
throw new SQLException("对象转JSON失败", e);
}
}
// JSON字符串转Java对象(从ResultSet中获取)
@Override
public UserDetail getNullableResult(ResultSet rs, String columnName) throws SQLException {
String json = rs.getString(columnName);
return parseJson(json);
}
// JSON字符串转Java对象(从CallableStatement中获取)
@Override
public UserDetail getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String json = cs.getString(columnIndex);
return parseJson(json);
}
private UserDetail parseJson(String json) {
if (json == null || json.isEmpty()) {
return null;
}
try {
return objectMapper.readValue(json, UserDetail.class);
} catch (JsonProcessingException e) {
throw new SQLException("JSON转对象失败", e);
}
}
}
(3)MyBatis映射文件配置
在UserMapper.xml中指定字段使用自定义类型处理器:
<resultMap id="BaseResultMap" type="com.example.entity.User">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="info" property="detail" typeHandler="com.example.handler.UserDetailTypeHandler"/>
</resultMap>
<insert id="insertUser" parameterType="com.example.entity.User">
INSERT INTO user (username, info) VALUES (#{username}, #{detail, typeHandler=com.example.handler.UserDetailType


还没有评论,来说两句吧...