您好,登录后才能下订单哦!
在现代Web开发中,图片上传是一个常见的需求。无论是用户头像、商品图片还是文章插图,图片上传功能都是不可或缺的。本文将详细介绍如何在SSM(Spring + Spring MVC + MyBatis)框架中实现图片上传功能。我们将从环境搭建、前端页面设计、后端接口实现、图片存储与访问等方面进行详细讲解,帮助读者全面掌握SSM框架下的图片上传技术。
首先,我们需要创建一个基本的SSM项目结构。项目结构如下:
ssm-image-upload/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ ├── controller/
│ │ │ ├── service/
│ │ │ ├── dao/
│ │ │ └── entity/
│ │ ├── resources/
│ │ │ ├── mybatis/
│ │ │ ├── spring/
│ │ │ └── application.properties
│ │ └── webapp/
│ │ ├── WEB-INF/
│ │ │ └── views/
│ │ └── static/
│ │ ├── css/
│ │ ├── js/
│ │ └── images/
│ └── test/
│ └── java/
└── pom.xml
在pom.xml
中添加必要的依赖:
<dependencies>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.21</version>
</dependency>
<!-- Spring JDBC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.21</version>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!-- MyBatis Spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<!-- Commons FileUpload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!-- Jackson for JSON -->
<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 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
在src/main/resources/spring/
目录下创建spring-mvc.xml
和spring-mybatis.xml
配置文件。
spring-mvc.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解驱动 -->
<mvc:annotation-driven/>
<!-- 配置静态资源处理 -->
<mvc:resources mapping="/static/**" location="/static/"/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/> <!-- 10MB -->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<!-- 扫描Controller -->
<context:component-scan base-package="com.example.controller"/>
</beans>
spring-mybatis.xml
<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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 数据源配置 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm_image_upload?useSSL=false&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</bean>
<!-- MyBatis SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mybatis/*.xml"/>
</bean>
<!-- MyBatis Mapper扫描 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.dao"/>
</bean>
<!-- 事务管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 开启注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 扫描Service -->
<context:component-scan base-package="com.example.service"/>
</beans>
在src/main/webapp/WEB-INF/
目录下创建web.xml
文件:
<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_3_1.xsd"
version="3.1">
<!-- 配置Spring上下文监听器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-mybatis.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置Spring MVC DispatcherServlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</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>
在src/main/resources/application.properties
中配置数据库连接信息:
spring.datasource.url=jdbc:mysql://localhost:3306/ssm_image_upload?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
创建一个简单的图片表image
:
CREATE TABLE `image` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`path` varchar(255) NOT NULL,
`upload_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
在src/main/webapp/WEB-INF/views/
目录下创建upload.jsp
文件:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>图片上传</title>
<link rel="stylesheet" type="text/css" href="/static/css/style.css">
</head>
<body>
<h1>图片上传</h1>
<form action="/upload" method="post" enctype="multipart/form-data">
<label for="image">选择图片:</label>
<input type="file" id="image" name="image" accept="image/*" required>
<br><br>
<input type="submit" value="上传">
</form>
</body>
</html>
在src/main/webapp/WEB-INF/views/
目录下创建images.jsp
文件:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<title>图片展示</title>
<link rel="stylesheet" type="text/css" href="/static/css/style.css">
</head>
<body>
<h1>图片展示</h1>
<c:forEach var="image" items="${images}">
<div>
<img src="/static/images/${image.path}" alt="${image.name}" width="200">
<p>${image.name}</p>
</div>
</c:forEach>
</body>
</html>
在src/main/java/com/example/entity/
目录下创建Image.java
实体类:
package com.example.entity;
import java.util.Date;
public class Image {
private Integer id;
private String name;
private String path;
private Date uploadTime;
// Getters and Setters
}
在src/main/java/com/example/dao/
目录下创建ImageDao.java
接口:
package com.example.dao;
import com.example.entity.Image;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface ImageDao {
@Insert("INSERT INTO image(name, path, upload_time) VALUES(#{name}, #{path}, #{uploadTime})")
void insert(Image image);
@Select("SELECT * FROM image")
List<Image> findAll();
}
在src/main/java/com/example/service/
目录下创建ImageService.java
接口及其实现类ImageServiceImpl.java
:
package com.example.service;
import com.example.entity.Image;
import java.util.List;
public interface ImageService {
void saveImage(Image image);
List<Image> getAllImages();
}
package com.example.service;
import com.example.dao.ImageDao;
import com.example.entity.Image;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ImageServiceImpl implements ImageService {
@Autowired
private ImageDao imageDao;
@Override
public void saveImage(Image image) {
imageDao.insert(image);
}
@Override
public List<Image> getAllImages() {
return imageDao.findAll();
}
}
在src/main/java/com/example/controller/
目录下创建ImageController.java
:
package com.example.controller;
import com.example.entity.Image;
import com.example.service.ImageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
@Controller
public class ImageController {
@Autowired
private ImageService imageService;
@GetMapping("/upload")
public String uploadPage() {
return "upload";
}
@PostMapping("/upload")
public String uploadImage(@RequestParam("image") MultipartFile file, Model model) {
if (file.isEmpty()) {
model.addAttribute("message", "请选择一张图片");
return "upload";
}
try {
// 保存图片到服务器
String fileName = file.getOriginalFilename();
String filePath = "src/main/webapp/static/images/" + fileName;
File dest = new File(filePath);
file.transferTo(dest);
// 保存图片信息到数据库
Image image = new Image();
image.setName(fileName);
image.setPath(fileName);
image.setUploadTime(new Date());
imageService.saveImage(image);
model.addAttribute("message", "图片上传成功");
} catch (IOException e) {
e.printStackTrace();
model.addAttribute("message", "图片上传失败");
}
return "upload";
}
@GetMapping("/images")
public String getAllImages(Model model) {
List<Image> images = imageService.getAllImages();
model.addAttribute("images", images);
return "images";
}
}
在src/main/webapp/static/images/
目录下存储上传的图片。确保该目录存在,并且具有写权限。
上传的图片可以通过/static/images/
路径访问。例如,上传的图片example.jpg
可以通过http://localhost:8080/static/images/example.jpg
访问。
为了减少图片的存储空间和加载时间,可以在上传时对图片进行压缩。可以使用Java的ImageIO
类或第三方库如Thumbnailator
来实现图片压缩。
可以将上传的图片转换为WebP格式,以减少图片大小并提高加载速度。可以使用ImageIO
类或第三方库如TwelveMonkeys
来实现格式转换。
可以在上传的图片上添加水印,以防止图片被盗用。可以使用Java的Graphics2D
类来实现水印功能。
对于大文件上传,可以将图片分片上传,以提高上传的稳定性和速度。可以使用HTML5
的File API
和FormData
对象来实现分片上传。
为了提升用户体验,可以在前端实现图片上传的进度条。可以使用XMLHttpRequest
对象的upload
事件来监听上传进度。
Spring MVC默认的文件上传大小限制为1MB。可以通过配置CommonsMultipartResolver
的maxUploadSize
属性来调整上传大小限制。
确保上传路径存在并且具有写权限。可以使用File
类的mkdirs()
方法创建目录。
为了避免文件名冲突,可以在保存文件时生成唯一的文件名。可以使用UUID
类生成唯一的文件名。
为了防止恶意文件上传,可以在上传时检查文件的MIME类型和扩展名。可以使用MultipartFile
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。