您好,登录后才能下订单哦!
在现代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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。