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