Загрузите файл через службу REST JHipster, используя HTTPie или Curl
Я сделал приложение JHipster (v5.3.1), которое имеет сущность Attachment
который содержит Blob
поле называется fileAttachment
, Используя сгенерированный веб-интерфейс Angular 6, я могу загружать файлы в приложение. Я хотел бы сделать то же самое с помощью командной строки (либо HTTPie
или же curl
).
Определение jdl вложения:
/**
* An entity to store attachments
*/
entity Attachment {
/** The name of the attachment */
fileName String required,
/** the attachment */
attachedFile Blob required
}
Генератор JHipster создает Attachment.java
а также AttachmentService.java
и AttachmentResource.java
который я не изменил вообще.
Используя веб-интерфейс, при загрузке файла регистрируются следующие операторы:
2018-09-18 09:18:11.501 DEBUG 14151 --- [ XNIO-2 task-7] c.k.kapture.aop.logging.LoggingAspect : Enter: com.kaleido.kapture.web.rest.AttachmentResource.createAttachment() with argument[s] = [Attachment{id=null, fileName='test', attachedFile='[B@396897d6', attachedFileContentType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}]
2018-09-18 09:18:11.502 DEBUG 14151 --- [ XNIO-2 task-7] c.k.kapture.web.rest.AttachmentResource : REST request to save Attachment : Attachment{id=null, fileName='test', attachedFile='[B@396897d6', attachedFileContentType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}
2018-09-18 09:18:11.504 DEBUG 14151 --- [ XNIO-2 task-7] c.k.kapture.aop.logging.LoggingAspect : Enter: com.kaleido.kapture.service.AttachmentService.save() with argument[s] = [Attachment{id=null, fileName='test', attachedFile='[B@396897d6', attachedFileContentType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}]
2018-09-18 09:18:11.518 DEBUG 14151 --- [ XNIO-2 task-7] c.k.kapture.service.AttachmentService : Request to save Attachment : Attachment{id=null, fileName='test', attachedFile='[B@396897d6', attachedFileContentType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}
Hibernate: call next value for hibernate_sequence
2018-09-18 09:18:11.562 DEBUG 14151 --- [ XNIO-2 task-7] o.j.core.metamodel.type.TypeFactory : javersType of class com.kaleido.kapture.domain.Attachment inferred as EntityType
2018-09-18 09:18:11.564 DEBUG 14151 --- [ XNIO-2 task-7] o.j.core.metamodel.type.TypeFactory : javersType of class java.lang.Long inferred as ValueType, it's used as id-property type
2018-09-18 09:18:11.597 DEBUG 14151 --- [ XNIO-2 task-7] o.j.core.metamodel.type.TypeFactory : javersType of class [B spawned as ArrayType from prototype ArrayType{baseType:'class [Ljava.lang.Object;'}
2018-09-18 09:18:11.599 DEBUG 14151 --- [ XNIO-2 task-7] o.javers.core.graph.ObjectGraphBuilder : live graph assembled, object nodes: 1, entities: 1, valueObjects: 0
2018-09-18 09:18:11.695 INFO 14151 --- [ XNIO-2 task-7] org.javers.core.Javers : Commit(id:1.0, snapshots:1, author:admin, changes - NewObject:1), done in 144 millis (diff:71, persist:73)
2018-09-18 09:18:12.096 DEBUG 14151 --- [ XNIO-2 task-7] c.k.kapture.aop.logging.LoggingAspect : Exit: com.kaleido.kapture.service.AttachmentService.save() with result = Attachment{id=1001, fileName='test', attachedFile='[B@396897d6', attachedFileContentType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}
Hibernate: insert into attachment (attached_file, attached_file_content_type, file_name, id) values (?, ?, ?, ?)
2018-09-18 09:18:12.104 DEBUG 14151 --- [ XNIO-2 task-7] c.k.kapture.aop.logging.LoggingAspect : Exit: com.kaleido.kapture.web.rest.AttachmentResource.createAttachment() with result = <201 Created,Attachment{id=1001, fileName='test', attachedFile='[B@396897d6', attachedFileContentType='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'},{Location=[/api/attachments/1001], X-kaptureApp-alert=[A new attachment is created with identifier 1001], X-kaptureApp-params=[1001]}>
Используя HTTPie, я могу аутентифицироваться и получить токен JWT.
http POST :8080/api/authenticate password=**** username=admin
Однако не очевидно, как POST
файл:
http -v --form POST :8080/api/attachments/ \
'Authorization:Bearer ***.***.***' \
fileName=test.txt \
attachedFile@test.txt \
attachedFileContentType=text/plain
результаты в:
POST /api/attachments/ HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Authorization: Bearer ****.****.****
Connection: keep-alive
Content-Length: 404
Content-Type: multipart/form-data;
boundary=087aa239fc6f4eb197fa883424e2bdc3
Host: localhost:8080
User-Agent: HTTPie/0.9.9
--087aa239fc6f4eb197fa883424e2bdc3
Content-Disposition: form-data; name="fileName"
test.txt
--087aa239fc6f4eb197fa883424e2bdc3
Content-Disposition: form-data; name="attachedFileContentType"
text/plain
--087aa239fc6f4eb197fa883424e2bdc3
Content-Disposition: form-data; name="attachedFile";
filename="test.txt"
Content-Type: text/plain
test test test
--087aa239fc6f4eb197fa883424e2bdc3--
HTTP/1.1 415 Unsupported Media Type
Accept: application/octet-stream, text/plain, application/xml, text/xml, application/x-www-form-urlencoded, application/x-jackson-smile, application/*+xml, multipart/form-data, application/json, application/cbor, application/*+json, */*
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Type: application/problem+json
Date: Tue, 18 Sep 2018 14:27:08 GMT
Expires: 0
Pragma: no-cache
Transfer-Encoding: chunked
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
{
"detail": "Content type 'multipart/form-data;boundary=087aa239fc6f4eb197fa883424e2bdc3;charset=UTF-8' not supported",
"message": "error.http.415",
"path": "/api/attachments/",
"status": 415,
"title": "Unsupported Media Type",
"type": "https://www.jhipster.tech/problem/problem-with-message"
}
Как я должен построить POST
?
Обновить
Когда я смотрю, что происходит в Chrome, я вижу, что полезная нагрузка запроса
{"fileName":"test.txt","attachedFileContentType":"text/plain","attachedFile":"dGVzdCB0ZXN0IHRlc3QK"}
Не понятно где attachedFile
значение исходит от?
Заголовки запроса, сгенерированные веб-интерфейсом:
POST /api/attachments HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 100
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json, text/plain, */*
Origin: http://localhost:8080
X-XSRF-TOKEN: *****************
Authorization: Bearer ****.****.****.****
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36
Content-Type: application/json
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie:
access_token=****.****.****; session_token=****; XSRF-TOKEN=*****; Idea-1c443776=2050c190-4f64-4a09-a50c-a0ef97b6a9da; io=p4GYHllrvXuakjfbAAAA
1 ответ
Решение состоит в том, чтобы Base64 кодировал файл и предоставлял эту строку в качестве значения attachedFile
(Спасибо Джону Радделлу за подсказку).
Следующий вызов создаст запись с вложением test.txt
с закодированным в base64 контентомtest test test
" и с text/plain
в качестве типа контента.
http POST :8080/api/attachments/ \
'Authorization:Bearer ****.****.****' \
fileName=test.txt \
attachedFile=dGVzdCB0ZXN0IHRlc3QK \
attachedFileContentType=text/plain
Для любого реального файла нереально включить в командную строку кодировку Base64 этого файла. Поэтому вы должны Base64 кодировать содержимое в файл, а затем ссылаться на файл с http
тем самым делая его частью тела JSON.
Кодировать файл (schema.png
) и запишите кодировку в другой файл (schema.png.base64
):
openssl base64 -in schema.png > schema.png.base64
POST
файл с именем schema2.png
и тип носителя image/png
http POST :8080/api/attachments/ \
'Authorization:Bearer ****.****.***' \
fileName=schema2.png \
attachedFile=@schema.png.base64 \
attachedFileContentType=image/png