背景:之前一直想做上传图片如何将图片保存到服务器路径下面并将URL地址保存到数据库中,在网上找了很多大多都是五五开,有幸找到一篇简单的上传图片教程,并对其加以改正,得到了自己想要的效果。
参考博主链接:https://blog.csdn.net/Coding13/article/details/54577076
废话不多说,先将我自己项目的整体结构展示一下
- 使用环境 idea + Maven + JDK1.8
- pom.xml配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.library</groupId> <artifactId>nbt</artifactId> <version>0.0.1-SNAPSHOT</version> <name>nbt</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <!--<dependency>--> <!--<groupId>mysql</groupId>--> <!--<artifactId>mysql-connector-java</artifactId>--> <!--<version>5.1.25</version>--> <!--</dependency> --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.15</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.9</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.44</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>4.1.14</version> </dependency> </dependencies> <build> <!--放置在dao下的话要在这里配置,让springboot启动时去扫描--> <resources> <resource> <directory>${basedir}/src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.yml</include> <include>**/*.properties</include> <include>**/log/**/logback.xml</include> </includes> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- mybatis generator 自动生成代码插件 --> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile> <overwrite>true</overwrite> <verbose>true</verbose> </configuration> </plugin> </plugins> </build> </project>
- 控制层核心代码
package com.library.nbt.controller; import com.library.nbt.utils.VerifyUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.awt.image.BufferedImage; import java.io.OutputStream; @RestController @RequestMapping(value = "/api") @Api(value = "验证码接口", tags = "验证码接口", description = "") public class CodeController { @ApiOperation(value = "生成验证码", notes = "生成验证码") @ApiResponses(value = { @ApiResponse(code = 200, message = "successful request"), @ApiResponse(code = 500, message = "internal server error")}) @RequestMapping(value = "/v1/getcode", method = RequestMethod.GET) public void getCode(HttpServletResponse response, HttpServletRequest request) throws Exception { HttpSession session = request.getSession(); //利用图片工具生成图片 //第一个参数是生成的验证码,第二个参数是生成的图片 Object[] objs = VerifyUtil.createImage(); //将验证码存入Session session.setAttribute("imageCode", objs[0]); //将图片输出给浏览器 BufferedImage image = (BufferedImage) objs[1]; response.setContentType("image/png"); OutputStream os = response.getOutputStream(); ImageIO.write(image, "png", os); } }
- application.yml配置
server.port=12000 ##jdbc配置 mysql 8.1以上版本 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/btn-dev spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.username=root spring.datasource.password=123456 ##jdbc配置 mysql 8.1以下版本 #spring.datasource.driver-class-name=com.mysql.jdbc.Driver #spring.datasource.url=jdbc:mysql://localhost:3306/btn #spring.datasource.type=com.alibaba.druid.pool.DruidDataSource #spring.datasource.username=root #spring.datasource.password=123456 ## 该配置节点为独立的节点,有容易将这个配置放在spring的节点下,导致配置无法被识别 #注意:一定要对应mapper映射xml文件的所在路径 mybatis.mapper-locations=classpath:com/library/nbt/dao/**/mapper/*.xml mybatis.type-aliases-package=com.library.nbt.model.entity #配置generatorConfig.xml 运行时:mybatis-generator:generate -e db.driverLocation=D:\\Interest\\mybatis-generator-core-1.3.2\\lib\\mysql-connector-java-8.0.12.jar #本地浏览器地址 spring.web.googleexcute=explorer #要打开的网址 spring.web.loginurl=http://localhost:${server.port}/swagger-ui.html #是否要启动时打开浏览器 spring.web.isopenurl=true logging.config=classpath:log/dev/logback.xml file.rootPath=E: file.sonPath=/img/
- 配置类
package com.library.nbt.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter { //图片存放根路径 @Value("${file.rootPath}") private String ROOT_PATH; //图片存放根目录下的子目录 @Value("${file.sonPath}") private String SON_PATH; @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ String filePath = "file:" + ROOT_PATH + SON_PATH; //指向外部目录 registry.addResourceHandler("img//**").addResourceLocations(filePath); super.addResourceHandlers(registry); } }
- service层及实现类
package com.library.nbt.service; import org.springframework.web.multipart.MultipartFile; public interface UploadFileService { String getUploadFilePath(MultipartFile file); }
package com.library.nbt.service.impl; import com.library.nbt.dao.UplocalFileEntityMapper; import com.library.nbt.model.entity.UplocalFileEntity; import com.library.nbt.service.UploadFileService; import com.library.nbt.utils.DateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Random; @Service public class UploadFileServiceImpl implements UploadFileService { private static final Logger LOG = LoggerFactory.getLogger(UploadFileServiceImpl.class); //图片存放根路径 @Value("${file.rootPath}") private String ROOT_PATH; //图片存放根目录下的子目录 @Value("${file.sonPath}") private String SON_PATH; @Value("${server.port}") //获取主机端口 private String POST; @Autowired private UplocalFileEntityMapper uplocalFileEntityMapper; @Override public String getUploadFilePath(MultipartFile file) { //返回上传的文件是否为空,即没有选择任何文件,或者所选文件没有内容。 //防止上传空文件导致奔溃 if (file.isEmpty()) { throw new NullPointerException("文件为空"); } // 设置文件上传后的路径 String filePath = ROOT_PATH + SON_PATH; // 获取文件名后缀名 String suffix = file.getOriginalFilename(); String prefix = suffix.substring(suffix.lastIndexOf(".")+1); //为防止文件重名被覆盖,文件名取名为:当前日期 + 1-1000内随机数 Random random = new Random(); Integer randomFileName = random.nextInt(1000); String fileName = DateUtils.timeStamp2Date(String.valueOf(System.currentTimeMillis() /100),"yyyyMMddHHmmss") + randomFileName +"." + prefix; //创建文件路径 File dest = new File(filePath + fileName); // 解决中文问题,liunx下中文路径,图片显示问题 // fileName = UUID.randomUUID() + suffixName; // 检测是否存在目录 if (!dest.getParentFile().exists()) { //假如文件不存在即重新创建新的文件已防止异常发生 dest.getParentFile().mkdirs(); } try { //transferTo(dest)方法将上传文件写到服务器上指定的文件 file.transferTo(dest); //保存t_upload_file表中 String filePathNew = SON_PATH + fileName; String profilePhoto = saveUploadFile(filePathNew); System.out.println(profilePhoto); return profilePhoto; } catch (Exception e) { return dest.toString(); } } private String saveUploadFile(String filePathNew) { //获取本机IP String host = null; try { host = InetAddress.getLocalHost().getHostAddress(); } catch (UnknownHostException e) { LOG.error("get server host Exception e:", e); } UplocalFileEntity uplocalFileEntity = new UplocalFileEntity(); uplocalFileEntity.setCreateTime(System.currentTimeMillis()); uplocalFileEntity.setUpdateTime(System.currentTimeMillis()); uplocalFileEntity.setEnabled(1); uplocalFileEntity.setProfilePhoto(host + ":" + POST + filePathNew); Integer result = uplocalFileEntityMapper.insertSelective(uplocalFileEntity); System.out.println("插入了" + result + "数据"); System.out.println("uplocalFileEntity.getProfilePhoto():" + uplocalFileEntity.getProfilePhoto()); return uplocalFileEntity.getProfilePhoto(); } }
- mapper层及实现
package com.library.nbt.dao; import com.library.nbt.model.entity.UplocalFileEntity; import org.apache.ibatis.annotations.Mapper; @Mapper public interface UplocalFileEntityMapper { /** * This method was generated by MyBatis Generator. * This method corresponds to the database table t_uplocal_file * * @mbggenerated */ int insert(UplocalFileEntity record); /** * This method was generated by MyBatis Generator. * This method corresponds to the database table t_uplocal_file * * @mbggenerated */ int insertSelective(UplocalFileEntity record); }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.library.nbt.dao.UplocalFileEntityMapper" > <resultMap id="BaseResultMap" type="com.library.nbt.model.entity.UplocalFileEntity" > <!-- WARNING - @mbggenerated This element is automatically generated by MyBatis Generator, do not modify. --> <result column="id" property="id" jdbcType="INTEGER" /> <result column="create_time" property="createTime" jdbcType="BIGINT" /> <result column="update_time" property="updateTime" jdbcType="BIGINT" /> <result column="enabled" property="enabled" jdbcType="INTEGER" /> <result column="profile_photo" property="profilePhoto" jdbcType="VARCHAR" /> </resultMap> <insert id="insert" parameterType="com.library.nbt.model.entity.UplocalFileEntity" > <!-- WARNING - @mbggenerated This element is automatically generated by MyBatis Generator, do not modify. --> <selectKey resultType="java.lang.Integer" keyProperty="id" order="AFTER" > SELECT LAST_INSERT_ID() </selectKey> insert into t_uplocal_file (create_time, update_time, enabled, profile_photo) values (#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{enabled,jdbcType=INTEGER}, #{profilePhoto,jdbcType=VARCHAR}) </insert> <insert id="insertSelective" parameterType="com.library.nbt.model.entity.UplocalFileEntity" > <!-- WARNING - @mbggenerated This element is automatically generated by MyBatis Generator, do not modify. --> <selectKey resultType="java.lang.Integer" keyProperty="id" order="AFTER" > SELECT LAST_INSERT_ID() </selectKey> insert into t_uplocal_file <trim prefix="(" suffix=")" suffixOverrides="," > <if test="createTime != null" > create_time, </if> <if test="updateTime != null" > update_time, </if> <if test="enabled != null" > enabled, </if> <if test="profilePhoto != null" > profile_photo, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides="," > <if test="createTime != null" > #{createTime,jdbcType=BIGINT}, </if> <if test="updateTime != null" > #{updateTime,jdbcType=BIGINT}, </if> <if test="enabled != null" > #{enabled,jdbcType=INTEGER}, </if> <if test="profilePhoto != null" > #{profilePhoto,jdbcType=VARCHAR}, </if> </trim> </insert> </mapper>
- 进行测试,我用的是SwaggerUI,如果没有安装的话可以下载Postman进行接口测试
url也保存到数据库中了,复制URL地址在网页打开即可访问