版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
前言
springboot版本1.5.x,使用MultipartHttpServletRequest上传图片,
权限是token + SpringSecurity 控制api访问;
出现的问题是图片可以正常上传,但是无法显示。
pom文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>2.1.5.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- lombok插件 实体注解省略get set -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.5.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
</dependencies>
servcie层代码
package com.example.student.service;
import com.example.student.util.DateUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @Desc 图片上传实现
*/
@Service
public class ImageServiceImpl {
private final static List<String> fileTypes = new ArrayList<String>() {{
add("jpg");
add("jpeg");
add("png");
add("gif");
add("bmp");
}};
@Value("${file.save-path}")
private String baseFilePath;
/**
* 上传图片
*
* @param request
* @return
*/
public Object upload(MultipartHttpServletRequest request) throws Exception {
//按月来保存一个目录
String uploadPath = DateUtil.dateToString(new Date(), "yyyyMM");
//文件路径不存在,则新建
String checkPath = baseFilePath + "/" + uploadPath;
File fileStream = new File(checkPath);
if (!fileStream.exists()) {
fileStream.mkdirs();
}
MultipartFile file = request.getFile("file");
BufferedOutputStream stream;
if (file.isEmpty()) {
throw new Exception("上传文件不能为空");
}
String fileName = file.getOriginalFilename();
String realPath;
try {
String relatedPath = "/" + (new SimpleDateFormat("yyyyMMddHHmmssSSS")).format(new Date()) + "_" + fileName;
realPath = uploadPath + relatedPath;
int len = fileName.lastIndexOf(".");
if (len <= 0) {
throw new Exception("文件类型有误,请确认!");
}
String fileType = fileName.substring(len + 1).toLowerCase();
if (!fileTypes.contains(fileType)) {
throw new Exception("只允许上传图片!");
}
byte[] bytes = file.getBytes();
stream = new BufferedOutputStream(new FileOutputStream(new File(baseFilePath + "/" + realPath)));//设置文件路径及名字
stream.write(bytes);// 写入
stream.close();
} catch (Exception e) {
stream = null;
e.printStackTrace();
throw new Exception(fileName + "上传失败 => " + e.getMessage());
}
return realPath;
}
}
Controller层
package com.example.student.controller;
import com.example.student.response.BaseEntity;
import com.example.student.service.ImageServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartHttpServletRequest;
/**
* @Desc 上传图片
*/
@RestController
@RequestMapping("/api/image")
public class ImageController extends BaseController {
@Autowired
private ImageServiceImpl imageService;
@PostMapping("/upload")
public Object upload(MultipartHttpServletRequest request) {
try {
return imageService.upload(request);
} catch (Exception ex) {
return BaseEntity.failed(ex);
}
}
}
BaseEntity类返回值封装类
yml配置文件
spring:
datasource:
# mysql
driver-class-name: com.mysql.jdbc.Driver #jdbc驱动类
url: jdbc:mysql://localhost:3306/exe?useUnicode=true&allowMultiQueries=true&characterEncoding=utf8
username: root
password: 123456
jpa:
database: mysql
database-platform: com.example.student.MySQLDialect # mysql
hibernate:
ddl-auto: update # 反向生成
show-sql: false # 显示sql(false)
# Server HTTP port.
server:
port: 9004
tomcat:
uri-encoding: utf-8
http:
multipart:
max-file-size: 10Mb # 单个文件不超过10M
max-request-size: 100Mb # 请求文件总大小不超过100M
# 文件存储位置
fileProps:
filePath: /user/student/files #相对路径(windows版本)
SpringSecurity的配置文件(重点)
package com.example.student.config;
import com.example.student.config.jwt.JwtTokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* SpringSecurity的配置
* 通过SpringSecurity的配置,JwtTokenFilter配置进去
*/
@Configuration
@EnableWebSecurity//(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final RedisTemplate redisTemplate;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired
public WebSecurityConfig(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
// 设置 HTTP 验证规则
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/public/**", "/html/**", "/static/**", "/vendor/**", "/**/*.js", "/fonts/**", "/**/*.css", "/index.html", "/*.js", "/api/static/files/**").permitAll()
.antMatchers(HttpMethod.POST, "/api/auth/**").denyAll()
.antMatchers("/api/qyt/report/**").permitAll()
.antMatchers("/api/qyt/notice/**").permitAll()
.antMatchers("/api/qyt/attach/**").permitAll()
.antMatchers("/api/qyt/job-test/**").permitAll()
.anyRequest().authenticated() // 所有请求需要身份认证
.and().headers().frameOptions().disable()// 禁用x-frame 、
.and()
.addFilter(new JwtTokenFilter(authenticationManager(), jwtTokenUtil)); //自定义拦截器
}
}
重点讲一下:
图片无法显示的问题,主要是图片是静态资源,在拦截中放行 “/api/static/files/**”
下面是图片路径的相关设置:
package com.example.student.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 AppConfig extends WebMvcConfigurerAdapter {
@Value("${file.save-path}")
private String baseFilePath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/api/static/files/**").addResourceLocations("file:" + baseFilePath + "/");
}
}
这样问题就解决了!图片可以正常显示了,token控制权限在这里就不多讲了!
postman测试结果
postman测试路径:== localhost:9001/api/static/files/201909/20190923145332663_20190906154447929_20190829134459148_u=258217418,1801486311&fm=26&gp=0.jpg==