Java實例講解文件上傳與跨域問題
Java文件上傳實例并解決跨域問題
目在Web應(yīng)用系統(tǒng)開發(fā)中,文件上傳和下載功能是非常常用的功能,今天來講一下JavaWeb中的文件上傳功能的實現(xiàn)。
了解MultipartFile接口
我們實現(xiàn)文件的上傳用到了Spring-web框架中的 MultipartFile接口,MultipartFile接口的源碼注釋中說“MultipartFile接口是 在大部分請求中接收的上載文件的表示形式?!?/p>
A representation of an uploaded file received in a multipart request.
The file contents are either stored in memory or temporarily on disk. In either case, the user is responsible for copying file contents to a session-level or persistent store as and if desired. The temporary storage will be cleared at the end of request processing.
常用方法如下表
Method Summary | ||
---|---|---|
byte[] |
獲取文件的字節(jié)數(shù)組 | getBytes() Return the contents of the file as an array of bytes. |
String |
獲取文件的類型 | getContentType() Return the content type of the file. |
InputStream |
獲取文件的輸入流 | getInputStream() Return an InputStream to read the contents of the file from. |
String |
獲取文件名 | getName() Return the name of the parameter in the multipart form. |
String |
獲取原始文件名(防止篡改文件類型) | getOriginalFilename() Return the original filename in the client's filesystem. |
long |
獲取文件的大小,以字節(jié)的形式) | getSize() Return the size of the file in bytes. |
boolean |
判斷文件是否為空 | isEmpty() Return whether the uploaded file is empty, that is, either no file has been chosen in the multipart form or the chosen file has no content. |
void |
將接收到的文件傳輸?shù)浇o定的目標(biāo)文件。 | transferTo(File dest) Transfer the received file to the given destination file. |
文件上傳業(yè)務(wù)代碼
Controller類
/** * @Author: 小小張自由 * @Date: 2021/7/6 - 20:56 * @Description: 文件上傳 * @version: 1.0 */ @Controller @RequestMapping("upload") public class UploadController { @Autowired private UploadService uploadService; @PostMapping("image") public ResponseEntity<String> uploadImage(@RequestParam("file") MultipartFile file){ String url= this.uploadService.uploadImage(file); if (StringUtils.isBlank(url)){ return ResponseEntity.badRequest().build(); } return ResponseEntity.status(HttpStatus.CREATED).body(url); } }
Service類
寫了具體的業(yè)務(wù)邏輯
/** * @Author: 小小張自由 * @Date: 2021/7/6 - 21:01 * @Description: 文件上傳 * @version: 1.0 */ @Service public class UploadService { //用于判斷文件的類型,暫時只判斷了“image/gif","image/jpeg” private static final List<String> CONTENT_TYPES= Arrays.asList("image/gif","image/jpeg"); private static final Logger LOGGER= LoggerFactory.getLogger(UploadService.class); /** * 業(yè)務(wù)邏輯代碼 * @param file 文件的存儲的url * @return */ public String uploadImage(MultipartFile file) { String originalFilename = file.getOriginalFilename(); //校驗文件類型 //方法一:截取字符串 String afterLast = StringUtils.substringAfterLast(".", originalFilename); //方法二:使用getContentType方法 String contentType = file.getContentType(); if (!CONTENT_TYPES.contains(contentType)){ LOGGER.info("文件類型不合法:"+originalFilename); return null; } //校驗文件內(nèi)容 try { //獲取文件流 BufferedImage bufferedImage = ImageIO.read(file.getInputStream()); if (bufferedImage==null){ LOGGER.info("文件內(nèi)容不合法:{}",originalFilename); return null; } //保存到服務(wù)器 E:\Leyou\image //將接收到的文件傳輸?shù)浇o定的目標(biāo)文件。 file.transferTo(new File("E:\\Leyou\\Image\\"+originalFilename)); //返回URL,進行回顯 //可以使用Nginx-圖片服務(wù)器 return "http://image.leyou.com/"+originalFilename; } catch (Exception e) { LOGGER.info("服務(wù)器內(nèi)部錯誤:"+originalFilename); e.printStackTrace(); } return null; } }
修改nginx配置
將文件存儲到文件服務(wù)器中
修改Nginx的配置文件nginx.conf,監(jiān)聽80端口,設(shè)置root的值為:E盤
- 圖片不能保存在服務(wù)器內(nèi)部,這樣會對服務(wù)器產(chǎn)生額外的加載負擔(dān)
一般靜態(tài)資源都應(yīng)該使用獨立域名,這樣訪問靜態(tài)資源時不會攜帶一些不必要的cookie,減小請求的數(shù)據(jù)量
server { listen 80; server_name image.leyou.com; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; location / { root E:\\Leyou\\image; } }
如何繞過網(wǎng)關(guān)
每次上傳文件都會經(jīng)過網(wǎng)關(guān),必然會給網(wǎng)關(guān)帶來很大的壓力,那我們?nèi)绾卫@過網(wǎng)關(guān)呢?
1.在網(wǎng)關(guān)中配置白名單
在網(wǎng)關(guān)中配置白名單,這樣也會走網(wǎng)關(guān),只是壓力少了一點點
@Slf4j public class AuthorizeFilter implements GlobalFilter, Ordered { //白名單:存放放行的URL private List<String> allowPaths; @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { //獲取請求的url路徑 String path = request.getURI().getPath(); boolean flag=isAllowPath(path); if (flag) { log.info("請求在白名單中,leyou.filter: {}",path); //放行 return chain.filter(exchange); } else { //寫其他的業(yè)務(wù)邏輯 ~~~~ } } private boolean isAllowPath(String path) { //判斷是否允許放行 if (allowPaths.contains(path)){ return true; } return false; }
2.在nginx做轉(zhuǎn)發(fā)
在nginx做轉(zhuǎn)發(fā),當(dāng)請求文件上傳時,直接轉(zhuǎn)到相應(yīng)的服務(wù)
本實例使用了方法二,需要增加配置
server { listen 80; server_name api.leyou.com; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 新增加的配置,用于文件上傳 location /api/upload { proxy_pass http://127.0.0.1:8082; proxy_connect_timeout 600; proxy_read_timeout 600; rewrite "^/api/(.*)$" /$1 break; } # 網(wǎng)關(guān)的配置 location / { proxy_pass http://127.0.0.1:10010; proxy_connect_timeout 600; proxy_read_timeout 600; } }
當(dāng)這樣配置之后,文件上傳就不會過網(wǎng)關(guān),減少了網(wǎng)關(guān)的壓力。但是有引來了一個新問題那就是跨域。
解決上傳文件出現(xiàn)跨域問題
由于Nginx將文件上傳的請求直接轉(zhuǎn)發(fā)到了具體服務(wù)中,不再走gateway,所以gateway中的跨域配置,不再生效了。 需要在文件上傳這個服務(wù)中單獨配置跨域。
寫配置類CorsFilter
/** * @Author: 小小張自由 * @Date: 2021/6/15 - 11:12 * @Description: 解決 跨域問題 * @version: 1.0 */ @Configuration public class LeyouCorsConfiguration { @Bean public CorsFilter corsFilter(){ //初始化配置對象 CorsConfiguration configuration = new CorsConfiguration(); //允許跨域訪問的域名 configuration.addAllowedOrigin("*"); // configuration.setAllowCredentials(true); //運行攜帶cookie configuration.addAllowedMethod("*"); //代表所有請求方法 configuration.addAllowedHeader("*"); //允許攜帶任何頭信息 //初始化cors配置源對象 UrlBasedCorsConfigurationSource configurationSource=new UrlBasedCorsConfigurationSource(); configurationSource.registerCorsConfiguration("/**",configuration); //返回CorSfilter實例,參數(shù) return new CorsFilter(configurationSource); } }
到此應(yīng)該就可以上傳了,但是還是報跨域,我已經(jīng)配置好了啊,為什么還是報跨域呢?
在nginx配置中配置請求實體大小
我就想是不是Nginx的問題,然后我就一行一行的讀配置,最后發(fā)現(xiàn)
nginx配置中沒有配置請求實體大小
加上這行配置就好了
client_max_body_size 1024m;
到此這篇關(guān)于Java實例講解文件上傳與跨域問題的文章就介紹到這了,更多相關(guān)Java文件上傳跨域內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中Collection和Collections的區(qū)別
Collection是一個集合接口,集合類的頂級接口,Collections是一個包裝類,本文主要介紹了Java中Collection和Collections的區(qū)別,具有一定的參考價值,感興趣的可以了解一下2024-04-04Spring定時任務(wù)@Scheduled注解(cron表達式fixedRate?fixedDelay)
這篇文章主要為大家介紹了Spring定時任務(wù)@Scheduled注解(cron表達式fixedRate?fixedDelay)使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11Java并發(fā)包工具類CountDownLatch的應(yīng)用詳解
CountDownLatch是Java并發(fā)包中非常實用的一個工具類,它可以幫助我們實現(xiàn)線程之間的同步和協(xié)作。本文主要介紹了CountDownLatch的應(yīng)用場景及最佳實踐,希望對大家有所幫助2023-04-04關(guān)于String轉(zhuǎn)Json的幾種方式
這篇文章主要介紹了關(guān)于String轉(zhuǎn)Json的幾種方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12java使用ffmpeg命令來實現(xiàn)視頻編碼轉(zhuǎn)換的示例
本文主要介紹了java使用ffmpeg命令來實現(xiàn)視頻編碼轉(zhuǎn)換的示例,可以通過調(diào)用系統(tǒng)命令來執(zhí)行FFmpeg命令,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07