```
src/
├── main/
│ ├── java/
│ │ ├── com/example/
│ │ │ ├── controller/ProductController.java
│ │ │ ├── entity/Product.java
│ ├── resources/
│ │ ├── springmvc-config.xml
│ │ ├── applicationContext.xml
│ ├── webapp/
│ │ ├── WEB-INF/
│ │ │ ├── views/
│ │ │ │ ├── product.jsp
│ │ │ │ ├── productList.jsp
│ │ │ ├── web.xml
│ │ ├── js/
│ │ │ ├── jquery-3.6.0.min.js
│ │ ├── css/
│ │ │ ├── style.css
```
## 二、代码实现
### 1. 添加依赖 (pom.xml)
```xml
<dependencies>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.18</version>
</dependency>
<!-- Jackson for JSON processing -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- JSTL for JSP -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
```
### 2. Product 实体类 (Product.java)
```java
package com.example.entity;
public class Product {
private Integer id;
private String name;
private Double price;
private String description;
// 省略构造方法
// Getter 和 Setter 方法
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "Product{" +
"id=" + id +
", name='" + name + '\'' +
", price=" + price +
", description='" + description + '\'' +
'}';
}
}
```
### 3. ProductController 控制器 (ProductController.java)
```java
package com.example.controller;
import com.example.entity.Product;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.ArrayList;
import java.util.List;
@Controller
@RequestMapping("/product")
public class ProductController {
// 处理单个商品 JSON 数据绑定
@PostMapping("/getProduct")
@ResponseBody
public Product getProduct(@RequestBody Product product) {
System.out.println("接收到单个商品信息: " + product);
// 模拟处理逻辑,返回处理后的商品信息
product.setId(1001); // 设置模拟 ID
return product;
}
// 处理多个商品 JSON 数据绑定
@PostMapping("/getProductList")
@ResponseBody
public List<Product> getProductList(@RequestBody List<Product> products) {
System.out.println("接收到多个商品信息: " + products);
// 模拟处理逻辑,返回处理后的商品列表
for (int i = 0; i < products.size(); i++) {
products.get(i).setId(2000 + i); // 设置模拟 ID
}
return products;
}
// 返回 ModelAndView 类型的页面跳转
@GetMapping("/showProducts")
public ModelAndView showProducts() {
ModelAndView mav = new ModelAndView();
// 模拟数据
List<Product> productList = new ArrayList<>();
productList.add(new Product(1, "iPhone 13", 5999.0, "Apple 旗舰手机"));
productList.add(new Product(2, "MacBook Pro", 12999.0, "Apple 笔记本电脑"));
productList.add(new Product(3, "AirPods Pro", 1999.0, "Apple 无线耳机"));
// 添加模型数据
mav.addObject("products", productList);
mav.addObject("title", "商品列表");
// 设置视图名称
mav.setViewName("productList");
return mav;
}
// 跳转到商品信息录入页面
@GetMapping("/input")
public String input() {
return "product";
}
}
```
### 4. Spring MVC 配置文件 (springmvc-config.xml)
```xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 组件扫描 -->
<context:component-scan base-package="com.example.controller"/>
<!-- 注解驱动 -->
<mvc:annotation-driven/>
<!-- 静态资源处理 -->
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
```
### 5. web.xml 配置
```xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 配置 DispatcherServlet -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 字符编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
```
### 6. JSP 页面 (product.jsp)
```jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>商品信息录入</title>
<script src="/js/jquery-3.6.0.min.js"></script>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
form { max-width: 500px; margin: 0 auto; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; }
input, textarea { width: 100%; padding: 8px; }
button { padding: 10px 15px; background: #4CAF50; color: white; border: none; cursor:
pointer; }
button:hover { background: #45a049; }
#result { margin-top: 20px; padding: 10px; border: 1px solid #ddd; }
</style>
</head>
<body>
<h2>商品信息录入</h2>
<form id="productForm">
<div class="form-group">
<label for="name">商品名称:</label>
<input type="text" id="name" name="name" required>
</div>
<div class="form-group">
<label for="price">商品价格:</label>
<input type="number" id="price" name="price" step="0.01" required>
</div>
<div class="form-group">
<label for="description">商品描述:</label>
<textarea id="description" name="description" rows="3"></textarea>
</div>
<button type="button" onclick="submitProduct()">提交单个商品</button>
<button type="button" onclick="submitProductList()">提交多个商品</button>
</form>
<div id="result"></div>
<script>
function submitProduct() {
const product = {
name: $('#name').val(),
price: parseFloat($('#price').val()),
description: $('#description').val()
};
$.ajax({
url: '/product/getProduct',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(product),
success: function(response) {
$('#result').html('<h3>返回的单个商品信息:</h3>' +
'<p>ID: ' + response.id + '</p>' +
'<p>名称: ' + response.name + '</p>' +
'<p>价格: ' + response.price + '</p>' +
'<p>描述: ' + response.description + '</p>');
}
});
}
function submitProductList() {
const product1 = {
name: $('#name').val(),
price: parseFloat($('#price').val()),
description: $('#description').val()
};
const product2 = {
name: "示例商品 2",
price: 99.99,
description: "这是第二个示例商品"
};
const products = [product1, product2];
$.ajax({
url: '/product/getProductList',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(products),
success: function(response) {
let html = '<h3>返回的多个商品信息:</h3>';
response.forEach(function(product) {
html += '<div style="margin-bottom: 15px; padding: 10px; border: 1px solid #eee;">'
+
'<p>ID: ' + product.id + '</p>' +
'<p>名称: ' + product.name + '</p>' +
'<p>价格: ' + product.price + '</p>' +
'<p>描述: ' + product.description + '</p>' +
'</div>';
});
$('#result').html(html);
}
});
}
</script>
<p><a href="/product/showProducts">查看商品列表(ModelAndView 示例)</a></p>
</body>
</html>
```
### 7. JSP 页面 (productList.jsp)
```jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>${title}</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
h1 { color: #333; }
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
tr:nth-child(even) { background-color: #f9f9f9; }
</style>
</head>
<body>
<h1>${title}</h1>
<table>
<tr>
<th>ID</th>
<th>商品名称</th>
<th>价格</th>
<th>描述</th>
</tr>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.id}</td>
<td>${product.name}</td>
<td>${product.price}</td>
<td>${product.description}</td>
</tr>
</c:forEach>
</table>
<p><a href="/product/input">返回商品录入页面</a></p>
</body>
</html>
```