摘要:的官方文檔中將調(diào)用的入口稱作,而在的示例代碼中將其命名為,其實指的是同一個東西。其次是類至此,一個文件上傳的服務(wù)端接口已經(jīng)編寫完成。
前言
SpringBoot的官方文檔中關(guān)于Jersey的介紹并不是很全面: 27.3 JAX-RS and Jersey,SpringBoot-Sample項目里面也只有非常基礎(chǔ)的代碼,對于一些復(fù)雜的常用需求,這個文檔給不了任何幫助。
為了使用Jersey提供的Restful API完成文件上傳功能,今天我花了不少時間查閱文檔資料,遇到了一些問題,然后不斷地踩坑嘗試,其中一些坑還是參照Stack Overflow的解決方案,甚至是框架官方文檔的說明而碰到的。主要問題就是,SpringBoot和Jersey的官方文檔沒有給出更詳細的內(nèi)容,Stack Overflow針對的問題很片面,不能適用于所有的情況,所以我打算將搭建項目的過程從頭到尾寫下來,以便有一個方便參照的教程。
項目搭建我使用了Spring發(fā)布的Spring Tool Suit(STS)來創(chuàng)建項目,因為這個IDE使用SpringBoot十分方便,可以在創(chuàng)建項目時引入一些技術(shù)棧。
我使用的Java版本是JDK 8,后面會用到CURL這個命令行工具來測試相關(guān)的接口,大家可以先準(zhǔn)備好,以便學(xué)習(xí)過程連貫。
這個項目命名為demo-app,默認包為org.demo,我在創(chuàng)建時僅添加了Jersey的支持,SpringBoot版本是1.5.10。
如果沒有STS,也可以用Eclipse創(chuàng)建一個Maven項目,Pom文件配置如下:
4.0.0 org.demo demo-app 0.0.1-SNAPSHOT jar org.springframework.boot spring-boot-starter-parent 1.5.10.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-jersey org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin
項目創(chuàng)建完成后,需要添加一個jersey-media-multipart的依賴,在pom中dependencies標(biāo)簽中添加:
org.glassfish.jersey.media jersey-media-multipart
這個依賴不需要版本號,因為在spring-boot-starter-parent中已經(jīng)定義了版本,我們只需要添加一個dependency在具體項目中即可。
編寫代碼項目創(chuàng)建好時,已經(jīng)存在一個帶有main方法的入口類DemoAppApplication,我們不需要改動它。
Jersey的官方文檔中將Restful API調(diào)用的入口稱作Resources,而在SpringBoot的示例代碼中將其命名為Endpoint,其實指的是同一個東西。因為使用了SpringBoot,為了風(fēng)格統(tǒng)一我使用了Endpoint的命名規(guī)則,這不是強制的,大家也可以自定義命名規(guī)則。但建議從這兩者中選擇一種,以便大家方便理解。
首先增加一個HelloEndpoint類:
package org.demo; import java.io.IOException; import java.io.InputStream; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.core.MediaType; import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataParam; import org.springframework.stereotype.Component; @Component @Path("/file") public class FileUploadEndpoint { @POST @Consumes(MediaType.MULTIPART_FORM_DATA) public String upload(@FormDataParam("file") InputStream fis, @FormDataParam("file") FormDataContentDisposition fileDisposition) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { IOUtils.copy(fis, baos); String content = new String(baos.toByteArray()); return content; } catch (IOException e) { e.printStackTrace(); } return null; } }
它十分類似于SpringMVC的Controller,但是擁有更規(guī)范更嚴格的REST風(fēng)格,而且它不能像SpringMVC一樣通過返回一個視圖名稱指向某個視圖。
其次是JerseyConfig類:
package org.demo; import javax.ws.rs.ApplicationPath; import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.server.ResourceConfig; import org.springframework.stereotype.Component; @Component @ApplicationPath("/rest/demo") public class JerseyConfig extends ResourceConfig { public JerseyConfig() { register(MultiPartFeature.class); register(FileUploadEndpoint.class); } }
至此,一個文件上傳的服務(wù)端接口已經(jīng)編寫完成。關(guān)于表單頁面這里不多做說明,因為這個項目不是一個Web項目,而是Web Service的服務(wù)端,不能在項目中直接訪問靜態(tài)Web資源。也不建議使用特殊方法滿足這種需要,我們應(yīng)當(dāng)保持項目的純凈。
需要注意@ApplicationPath這個注解,它決定了所有Endpoint的基礎(chǔ)路徑。
運行測試下面我們來測試一下這個Restful API是否能正常工作,運行DemoAppApplication,等待項目部署。
接下來準(zhǔn)備使用CURL測試,CURL可以到官網(wǎng)下載操作系統(tǒng)對應(yīng)的版本。創(chuàng)建一個demo.txt文件保存到任意目錄,文件內(nèi)容寫入Test my restful api with curl.,使用英文是為了避免CMD命令行中的中文出現(xiàn)亂碼的情況,這里不用過多在意,我們只要關(guān)注結(jié)果。
進入demo.txt文件所在的目錄,按住Shift打開CMD或者PowerShell(Linux系統(tǒng)下打開終端定位到該目錄),執(zhí)行:curl -X POST -F "file=@demo.txt" http://localhost:8080/rest/demo/file
如果得到Test my restful api with curl.的回顯,說明Restful API部署成功,并且能夠接收上傳的文件。
注意問題在實現(xiàn)利用Jersey完成文件上傳的過程中,我遇到的一些問題需要大家特別關(guān)注:
SpringBoot沒有默認添加jersey-media-multipart依賴,僅預(yù)先定義了需要的版本,如果未引入這個包,將無法使用@FormDataParam注解和Multipart相關(guān)的類,無法對Multipart內(nèi)容進行解析;
JerseyConfig中需要注冊MultiPartFeature.class,否則會出現(xiàn)報錯,無法正確注入文件輸入流對象。報錯的時機根據(jù)是否延遲加載決定,如果application.properties定義了spring.jersey.servlet.load-on-startup=1,會在項目啟動時報錯;否則會在首次上傳文件,初始化FileUploadEndpoint時報錯。
關(guān)于FileUploadEndpoint.upload()方法,有些文檔和教程中,fileDisposition對象使用了ContentDisposition類來定義,盡管它是FormDataContentDisposition的父類,但仍然會報錯,原因未知。建議直接使用FormDataContentDisposition
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/68428.html
摘要:筆主很早就開始用阿里云存儲服務(wù)當(dāng)做自己的圖床了。阿里云對象存儲文檔,本篇文章會介紹到整合阿里云存儲服務(wù)實現(xiàn)文件上傳下載以及簡單的查看。 Github 地址:https://github.com/Snailclimb/springboot-integration-examples(SpringBoot和其他常用技術(shù)的整合,可能是你遇到的講解最詳細的學(xué)習(xí)案例,力爭新手也能看懂并且能夠在看完...
摘要:開公眾號差不多兩年了,有不少原創(chuàng)教程,當(dāng)原創(chuàng)越來越多時,大家搜索起來就很不方便,因此做了一個索引幫助大家快速找到需要的文章系列處理登錄請求前后端分離一使用完美處理權(quán)限問題前后端分離二使用完美處理權(quán)限問題前后端分離三中密碼加鹽與中異常統(tǒng)一處理 開公眾號差不多兩年了,有不少原創(chuàng)教程,當(dāng)原創(chuàng)越來越多時,大家搜索起來就很不方便,因此做了一個索引幫助大家快速找到需要的文章! Spring Boo...
摘要:整合到本文更加注重代碼實踐,對于配置相關(guān)的知識會一筆帶過,不做過多的詳解。筆者是上傳到私服,然后通過導(dǎo)入。接口是預(yù)留給開發(fā)者根據(jù)不同事件處理業(yè)務(wù)邏輯的接口。改造筆記二優(yōu)化邏輯 Moquette簡介 Mqtt作為物聯(lián)網(wǎng)比較流行的協(xié)議現(xiàn)在已經(jīng)被大范圍使用,其中也有很多開源的MQTT BROKEN。Moquette是用java基于netty實現(xiàn)的輕量級的MQTT BROKEN. Moquet...
摘要:前言由于寫的文章已經(jīng)是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導(dǎo)航。 前言 由于寫的文章已經(jīng)是有點多了,為了自己和大家的檢索方便,于是我就做了這么一個博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時間才會更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號:Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡單 注解就這么簡單 Druid數(shù)據(jù)庫連接池...
閱讀 2033·2021-11-16 11:45
閱讀 3778·2021-09-06 15:02
閱讀 2095·2019-08-30 15:44
閱讀 2352·2019-08-30 11:21
閱讀 1943·2019-08-29 16:31
閱讀 3486·2019-08-29 13:55
閱讀 1958·2019-08-29 12:15
閱讀 3302·2019-08-28 18:05