การโพสต์ไฟล์และข้อมูลที่เกี่ยวข้องไปยัง RESTful WebService ควรเป็น JSON


757

นี่อาจจะเป็นคำถามที่โง่ แต่ฉันมีหนึ่งในคืนนั้น ในแอปพลิเคชันฉันกำลังพัฒนา RESTful API และเราต้องการให้ลูกค้าส่งข้อมูลเป็น JSON ส่วนหนึ่งของแอปพลิเคชันนี้ต้องการให้ลูกค้าอัปโหลดไฟล์ (โดยทั่วไปคือรูปภาพ) รวมถึงข้อมูลเกี่ยวกับรูปภาพ

ฉันมีปัญหาในการติดตามว่าเกิดอะไรขึ้นในคำขอเดียว เป็นไปได้หรือไม่ที่ Base64 ข้อมูลไฟล์ลงในสตริง JSON? ฉันจะต้องทำการโพสต์ 2 ครั้งไปยังเซิร์ฟเวอร์หรือไม่ ฉันไม่ควรใช้ JSON สำหรับสิ่งนี้?

ในฐานะที่เป็นบันทึกด้านข้างเรากำลังใช้ Grails บนแบ็กเอนด์และบริการเหล่านี้เข้าถึงได้โดยลูกค้ามือถือดั้งเดิม (iPhone, Android, ฯลฯ ) หากมีสิ่งใดที่สร้างความแตกต่าง


1
ดังนั้นวิธีที่ดีที่สุดในการทำเช่นนี้คืออะไร?
James111

3
ส่งข้อมูลเมตาในสตริงการสืบค้น URL แทนที่จะเป็น JSON
jrc

คำตอบ:


632

ฉันถามคำถามที่คล้ายกันที่นี่:

ฉันจะอัพโหลดไฟล์ที่มีเมทาดาทาได้อย่างไรโดยใช้บริการเว็บ REST

คุณมีสามตัวเลือกโดยทั่วไป:

  1. Base64 เข้ารหัสไฟล์โดยมีค่าใช้จ่ายในการเพิ่มขนาดข้อมูลประมาณ 33% และเพิ่มค่าใช้จ่ายในการประมวลผลทั้งเซิร์ฟเวอร์และไคลเอนต์สำหรับการเข้ารหัส / ถอดรหัส
  2. ส่งไฟล์เป็นอันดับแรกในmultipart/form-dataPOST และส่งคืน ID ไปยังลูกค้า จากนั้นไคลเอ็นต์จะส่งข้อมูลเมตาที่มี ID และเซิร์ฟเวอร์จะเชื่อมโยงไฟล์และข้อมูลเมตาอีกครั้ง
  3. ส่งข้อมูลเมตาก่อนและส่งคืนรหัสไปยังลูกค้า จากนั้นไคลเอ็นต์จะส่งไฟล์ที่มี ID และเซิร์ฟเวอร์จะเชื่อมโยงไฟล์และข้อมูลเมตาอีกครั้ง

29
หากฉันเลือกตัวเลือก 1 ฉันจะรวมเนื้อหา Base64 ไว้ในสตริง JSON หรือไม่ {file: '234JKFDS # $ @ # $ MFDDMS .... ', ชื่อ: 'somename' ... } หรือมีอะไรมากกว่านี้
Gregg

15
Gregg อย่างที่คุณบอกคุณจะรวมมันเป็นคุณสมบัติและค่านั้นจะเป็นสตริงที่เข้ารหัสแบบ 64 นี่อาจเป็นวิธีที่ง่ายที่สุดในการใช้ แต่อาจไม่สามารถใช้ได้จริงขึ้นอยู่กับขนาดไฟล์ ตัวอย่างเช่นสำหรับแอปพลิเคชันของเราเราต้องส่งภาพ iPhone ที่มีขนาด 2-3 MB ไม่ยอมรับการเพิ่มขึ้น 33% หากคุณส่งภาพขนาดเล็กเพียง 20KB ค่าใช้จ่ายนั้นอาจยอมรับได้มากกว่า
Daniel T.

19
ฉันควรพูดถึงว่าการเข้ารหัส / ถอดรหัส base64 จะใช้เวลาประมวลผลด้วย มันอาจเป็นสิ่งที่ง่ายที่สุดที่จะทำ แต่ก็ไม่ได้ดีที่สุดอย่างแน่นอน
Daniel T.

8
JSON กับ base64? อืม .. ฉันกำลังคิดที่จะติดกับหลายส่วน / แบบฟอร์ม
ทุกหนทุกแห่ง

12
เหตุใดจึงปฏิเสธที่จะใช้ข้อมูลหลายส่วน / แบบฟอร์มในคำขอเดียว
1nstinct

107

คุณสามารถส่งไฟล์และข้อมูลในคำขอเดียวโดยใช้ ประเภทเนื้อหาแบบหลายส่วน / แบบฟอร์มข้อมูล :

ในหลายแอปพลิเคชันผู้ใช้สามารถนำเสนอแบบฟอร์มได้ ผู้ใช้จะกรอกแบบฟอร์มรวมถึงข้อมูลที่พิมพ์สร้างขึ้นโดยการป้อนข้อมูลของผู้ใช้หรือรวมจากไฟล์ที่ผู้ใช้เลือก เมื่อกรอกแบบฟอร์มข้อมูลจากแบบฟอร์มจะถูกส่งจากผู้ใช้ไปยังแอปพลิเคชันที่รับ

คำจำกัดความของ MultiPart / Form-Data มาจากหนึ่งในแอปพลิเคชันเหล่านั้น ...

จากhttp://www.faqs.org/rfcs/rfc2388.html :

"multipart / form-data" มีชุดของส่วนต่าง ๆ แต่ละส่วนคาดว่าจะมีส่วนหัว content-disposition [RFC 2183] โดยที่ประเภทการจัดการคือ "form-data" และที่ซึ่งการจัดการประกอบด้วยพารามิเตอร์ (เพิ่มเติม) ของ "ชื่อ" โดยที่ค่าของพารามิเตอร์นั้นเป็นต้นฉบับ ชื่อฟิลด์ในแบบฟอร์ม ตัวอย่างเช่นส่วนหนึ่งอาจมีส่วนหัว:

การจัดการเนื้อหา: แบบฟอร์มข้อมูล; name = "ผู้ใช้"

ด้วยค่าที่สอดคล้องกับรายการของฟิลด์ "ผู้ใช้"

คุณสามารถรวมข้อมูลไฟล์หรือข้อมูลฟิลด์ภายในแต่ละส่วนระหว่างขอบเขต ฉันได้ใช้บริการ RESTful เรียบร้อยแล้วซึ่งต้องการให้ผู้ใช้ส่งทั้งข้อมูลและฟอร์มและ multipart / form-data ทำงานได้อย่างสมบูรณ์ บริการนี้สร้างขึ้นโดยใช้ Java / Spring และลูกค้าใช้ C # ดังนั้นน่าเสียดายที่ฉันไม่มีตัวอย่าง Grails ใด ๆ ที่จะให้คุณเกี่ยวกับวิธีการตั้งค่าบริการ คุณไม่จำเป็นต้องใช้ JSON ในกรณีนี้เนื่องจากแต่ละส่วน "form-data" ให้สถานที่เพื่อระบุชื่อของพารามิเตอร์และค่าของมัน

ข้อดีของการใช้ multipart / form-data คือคุณกำลังใช้ส่วนหัวที่กำหนดโดย HTTP ดังนั้นคุณจึงยึดติดกับปรัชญา REST ในการใช้เครื่องมือ HTTP ที่มีอยู่เพื่อสร้างบริการของคุณ


1
ขอบคุณ แต่คำถามของฉันมุ่งเน้นไปที่ต้องการใช้ JSON สำหรับคำขอและหากเป็นไปได้ ฉันรู้แล้วว่าฉันสามารถส่งตามที่คุณแนะนำ
Gregg

15
ใช่นั่นเป็นคำตอบของฉันสำหรับ "ฉันไม่ควรใช้ JSON สำหรับสิ่งนี้หรือ มีเหตุผลเฉพาะที่ทำให้คุณต้องการให้ลูกค้าใช้ JSON หรือไม่?
McStretch

3
น่าจะเป็นความต้องการทางธุรกิจหรือการรักษาอย่างสม่ำเสมอ แน่นอนสิ่งที่ต้องทำคือยอมรับทั้ง (แบบฟอร์มข้อมูลและการตอบสนอง JSON) โดยยึดตามส่วนหัว HTTP ของ Content-Type HTTP
Daniel T.

2
การเลือก JSON จะทำให้ได้รหัสที่สวยงามยิ่งขึ้นทั้งในฝั่งไคลเอ็นต์และฝั่งเซิร์ฟเวอร์ซึ่งทำให้เกิดข้อบกพร่องที่อาจเกิดขึ้นได้น้อยลง ข้อมูลในฟอร์มเมื่อวานนี้
superarts.org

5
ฉันขอโทษสำหรับสิ่งที่ฉันพูดถ้ามันทำร้ายความรู้สึกของนักพัฒนา. Net ถึงแม้ว่าภาษาอังกฤษจะไม่ใช่ภาษาแม่ของฉัน แต่ก็ไม่ใช่ข้อแก้ตัวที่ถูกต้องสำหรับฉันที่จะพูดเรื่องหยาบคายเกี่ยวกับเทคโนโลยี การใช้ข้อมูลในแบบฟอร์มนั้นยอดเยี่ยมและหากคุณยังคงใช้มันต่อไปคุณจะยิ่งยอดเยี่ยมขึ้นเช่นกัน!
superarts.org

53

ฉันรู้ว่ากระทู้นี้ค่อนข้างเก่า แต่ฉันหายไปที่นี่ตัวเลือกเดียว หากคุณมีข้อมูลเมตา (ในรูปแบบใด ๆ ) ที่คุณต้องการส่งพร้อมกับข้อมูลที่จะอัปโหลดคุณสามารถmultipart/relatedส่งคำขอเดียว

Multipart / ประเภทสื่อที่เกี่ยวข้องนั้นมีไว้สำหรับวัตถุผสมซึ่งประกอบด้วยส่วนต่าง ๆ ของร่างกายที่เกี่ยวข้องกันหลายส่วน

คุณสามารถตรวจสอบข้อกำหนดRFC 2387สำหรับรายละเอียดเชิงลึกเพิ่มเติม

โดยทั่วไปแต่ละส่วนของคำขอดังกล่าวสามารถมีเนื้อหาที่มีประเภทแตกต่างกันและทุกส่วนมีความสัมพันธ์กัน (เช่นภาพและข้อมูลเมตา) ชิ้นส่วนจะถูกระบุด้วยสตริงขอบเขตและสตริงขอบเขตสุดท้ายตามด้วยเครื่องหมายขีดคั่นสองตัว

ตัวอย่าง:

POST /upload HTTP/1.1
Host: www.hostname.com
Content-Type: multipart/related; boundary=xyz
Content-Length: [actual-content-length]

--xyz
Content-Type: application/json; charset=UTF-8

{
    "name": "Sample image",
    "desc": "...",
    ...
}

--xyz
Content-Type: image/jpeg

[image data]
[image data]
[image data]
...
--foo_bar_baz--

ฉันชอบทางออกที่ดีที่สุดของคุณ น่าเสียดายที่ดูเหมือนว่าจะไม่มีวิธีสร้าง mutlipart / คำขอที่เกี่ยวข้องในเบราว์เซอร์
Petr Baudis

คุณมีประสบการณ์ในการรับลูกค้าที่จะ (โดยเฉพาะอย่างยิ่งคนที่ JS) ในการสื่อสารกับ API ในลักษณะนี้
pvgoddijn

น่าเสียดายที่ปัจจุบันไม่มีผู้อ่านสำหรับข้อมูลประเภทนี้ใน php (7.2.1) และคุณจะต้องสร้างโปรแกรมแยกวิเคราะห์ของคุณเอง
dewd

เป็นเรื่องน่าเศร้าที่เซิร์ฟเวอร์และลูกค้าไม่มีการสนับสนุนที่ดีสำหรับเรื่องนี้
Nader Ghanbari

14

ฉันรู้ว่าคำถามนี้เก่า แต่ในวันสุดท้ายฉันค้นหาทั้งเว็บเพื่อแก้ปัญหาเดียวกันนี้ ฉันมีเว็บเซิร์ฟเวอร์ REST และไคลเอนต์ iPhone ที่ส่งรูปภาพชื่อและคำอธิบาย

ฉันไม่รู้ว่าวิธีการของฉันดีที่สุดหรือไม่ แต่ง่ายและเรียบง่าย

ฉันถ่ายภาพโดยใช้ UIImagePickerController และส่งไปยังเซิร์ฟเวอร์ NSData โดยใช้แท็กส่วนหัวของคำขอเพื่อส่งข้อมูลของรูปภาพ

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"myServerAddress"]];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:UIImageJPEGRepresentation(picture, 0.5)];
[request setValue:@"image/jpeg" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"myPhotoTitle" forHTTPHeaderField:@"Photo-Title"];
[request setValue:@"myPhotoDescription" forHTTPHeaderField:@"Photo-Description"];

NSURLResponse *response;

NSError *error;

[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

ที่ฝั่งเซิร์ฟเวอร์ฉันได้รับรูปโดยใช้รหัส:

InputStream is = request.inputStream

def receivedPhotoFile = (IOUtils.toByteArray(is))

def photo = new Photo()
photo.photoFile = receivedPhotoFile //photoFile is a transient attribute
photo.title = request.getHeader("Photo-Title")
photo.description = request.getHeader("Photo-Description")
photo.imageURL = "temp"    

if (photo.save()) {    

    File saveLocation = grailsAttributes.getApplicationContext().getResource(File.separator + "images").getFile()
    saveLocation.mkdirs()

    File tempFile = File.createTempFile("photo", ".jpg", saveLocation)

    photo.imageURL = saveLocation.getName() + "/" + tempFile.getName()

    tempFile.append(photo.photoFile);

} else {

    println("Error")

}

ฉันไม่รู้ว่าฉันมีปัญหาในอนาคต แต่ตอนนี้ทำงานได้ดีในสภาพแวดล้อมการผลิต


1
ฉันชอบตัวเลือกนี้ในการใช้ส่วนหัว http วิธีนี้ใช้งานได้ดีโดยเฉพาะเมื่อมีความสมมาตรระหว่างส่วนหัวของเมตาดาต้าและส่วนหัว http มาตรฐาน แต่คุณสามารถประดิษฐ์เองได้อย่างชัดเจน
EJ Campbell

14

นี่คือ API แนวทางของฉัน (ฉันใช้ตัวอย่าง) - อย่างที่คุณเห็นคุณไม่ใช้file_id(ตัวระบุไฟล์ที่อัปโหลดไปยังเซิร์ฟเวอร์) ใน API:

  1. สร้างphotoวัตถุบนเซิร์ฟเวอร์:

    POST: /projects/{project_id}/photos   
    body: { name: "some_schema.jpg", comment: "blah"}
    response: photo_id
  2. อัปโหลดไฟล์ (โปรดทราบว่าfileอยู่ในรูปแบบเอกพจน์เพราะมันมีเพียงหนึ่งภาพต่อรูปภาพ):

    POST: /projects/{project_id}/photos/{photo_id}/file
    body: file to upload
    response: -

ตัวอย่างเช่น:

  1. อ่านรายการภาพถ่าย

    GET: /projects/{project_id}/photos
    response: [ photo, photo, photo, ... ] (array of objects)
  2. อ่านรายละเอียดภาพถ่าย

    GET: /projects/{project_id}/photos/{photo_id}
    response: { id: 666, name: 'some_schema.jpg', comment:'blah'} (photo object)
  3. อ่านไฟล์รูปภาพ

    GET: /projects/{project_id}/photos/{photo_id}/file
    response: file content

ดังนั้นข้อสรุปคือก่อนอื่นคุณสร้างวัตถุ (ภาพถ่าย) โดย POST จากนั้นคุณส่งคำขอที่สองพร้อมไฟล์ (อีกครั้ง POST)


3
ดูเหมือนว่าวิธี 'พักฟื้น' ที่มากขึ้นเพื่อให้บรรลุเป้าหมายนี้
James Webster

การดำเนินการ POST สำหรับทรัพยากรที่สร้างขึ้นใหม่จะต้องส่งคืนรหัสสถานที่โดยมีรายละเอียดของวัตถุอย่างง่าย
Ivan Proskuryakov

@ivanproskuryakov ทำไม "ต้อง" ในตัวอย่างด้านบน (POST ในจุดที่ 2) id ของไฟล์ไม่มีประโยชน์ อาร์กิวเมนต์ที่สอง (สำหรับ POST ในจุดที่ 2) ฉันใช้รูปแบบเอกฐาน '/ file' (ไม่ใช่ '/ files') ดังนั้น ID ไม่จำเป็นเนื่องจาก path: / projects / 2 / photos / 3 / file ให้ข้อมูลแบบเต็มกับไฟล์ภาพตัวตน
Kamil Kiełczewski

จากข้อกำหนดคุณสมบัติโปรโตคอล HTTP w3.org/Protocols/rfc2616/rfc2616-sec10.html 10.2.2 201 สร้าง "ทรัพยากรที่สร้างขึ้นใหม่สามารถอ้างอิงได้โดย URI ที่ส่งคืนในเอนทิตีของการตอบกลับโดยมี URI เฉพาะที่สุดสำหรับทรัพยากรที่กำหนดโดย ฟิลด์ส่วนหัวสถานที่ตั้ง " @ KamilKiełczewski (หนึ่ง) และ (สอง) สามารถรวมกันเป็นหนึ่งการดำเนินการ POST POST: / projects / {project_id} / photos จะคืนค่าส่วนหัวของตำแหน่งคุณซึ่งสามารถใช้สำหรับ GET single photo (resource *) GET: เพื่อรับ ภาพเดี่ยวพร้อมรายละเอียดทั้งหมด CGET: เพื่อรับภาพถ่ายทั้งหมด
Ivan Proskuryakov

1
หากข้อมูลเมตาและการอัปโหลดเป็นการดำเนินการแยกกันจุดสิ้นสุดมีปัญหาเหล่านี้: สำหรับการอัปโหลดไฟล์ที่ใช้การดำเนินการ POST - POST ไม่ใช่ idempotent ต้องใช้ PUT (idempotent) เนื่องจากคุณเปลี่ยนทรัพยากรโดยไม่ต้องสร้างใหม่ ทำงานร่วมกับส่วนที่เหลือเรียกว่าวัตถุทรัพยากร POST:“ ../photos/“ PUT:“ ../photos/{photo_id}” GET:“ ../photos/“ GET:“ ../photos/{photo_id}” PS การแยกการอัปโหลดออกเป็นจุดปลายแยกอาจทำให้เกิดพฤติกรรมที่ไม่คาดคิด restapitutorial.com/lessons/idempotency.html restful-api-design.readthedocs.io/en/latest/resources.html
Ivan Proskuryakov

6

วัตถุ FormData: อัปโหลดไฟล์โดยใช้ Ajax

XMLHttpRequest ระดับ 2 เพิ่มการสนับสนุนสำหรับอินเทอร์เฟซ FormData ใหม่ วัตถุ FormData ให้วิธีการสร้างชุดของคู่คีย์ / ค่าที่แสดงถึงเขตข้อมูลฟอร์มและค่าอย่างง่ายดายซึ่งสามารถส่งได้อย่างง่ายดายโดยใช้เมธอด XMLHttpRequest send ()

function AjaxFileUpload() {
    var file = document.getElementById("files");
    //var file = fileInput;
    var fd = new FormData();
    fd.append("imageFileData", file);
    var xhr = new XMLHttpRequest();
    xhr.open("POST", '/ws/fileUpload.do');
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
             alert('success');
        }
        else if (uploadResult == 'success')
             alert('error');
    };
    xhr.send(fd);
}

https://developer.mozilla.org/en-US/docs/Web/API/FormData


6

เนื่องจากตัวอย่างเดียวที่ขาดหายไปคือตัวอย่าง ANDROIDฉันจะเพิ่ม เทคนิคนี้ใช้ AsyncTask ที่กำหนดเองที่ควรประกาศไว้ในคลาสกิจกรรมของคุณ

private class UploadFile extends AsyncTask<Void, Integer, String> {
    @Override
    protected void onPreExecute() {
        // set a status bar or show a dialog to the user here
        super.onPreExecute();
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        // progress[0] is the current status (e.g. 10%)
        // here you can update the user interface with the current status
    }

    @Override
    protected String doInBackground(Void... params) {
        return uploadFile();
    }

    private String uploadFile() {

        String responseString = null;
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost("http://example.com/upload-file");

        try {
            AndroidMultiPartEntity ampEntity = new AndroidMultiPartEntity(
                new ProgressListener() {
                    @Override
                        public void transferred(long num) {
                            // this trigger the progressUpdate event
                            publishProgress((int) ((num / (float) totalSize) * 100));
                        }
            });

            File myFile = new File("/my/image/path/example.jpg");

            ampEntity.addPart("fileFieldName", new FileBody(myFile));

            totalSize = ampEntity.getContentLength();
            httpPost.setEntity(ampEntity);

            // Making server call
            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();

            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode == 200) {
                responseString = EntityUtils.toString(httpEntity);
            } else {
                responseString = "Error, http status: "
                        + statusCode;
            }

        } catch (Exception e) {
            responseString = e.getMessage();
        }
        return responseString;
    }

    @Override
    protected void onPostExecute(String result) {
        // if you want update the user interface with upload result
        super.onPostExecute(result);
    }

}

ดังนั้นเมื่อคุณต้องการอัปโหลดไฟล์ของคุณเพียงแค่โทร:

new UploadFile().execute();

สวัสดี AndroidMultiPartEntity คืออะไรโปรดอธิบาย ... และถ้าฉันต้องการอัปโหลดไฟล์ PDF, ไฟล์ word หรือ xls สิ่งที่ฉันต้องทำโปรดให้คำแนะนำ ... ฉันเป็นคนใหม่
amit pandya

1
@amitpandya ฉันได้เปลี่ยนรหัสเป็นการอัปโหลดไฟล์ทั่วไปดังนั้นจึงเป็นเรื่องที่ชัดเจนสำหรับทุกคนที่อ่านมัน
lifeisfoo

2

ฉันต้องการส่งสตริงไปยังเซิร์ฟเวอร์เบื้องหลัง ฉันไม่ได้ใช้ json กับ multipart ฉันได้ใช้พารามิเตอร์ขอ

@RequestMapping(value = "/upload", method = RequestMethod.POST)
public void uploadFile(HttpServletRequest request,
        HttpServletResponse response, @RequestParam("uuid") String uuid,
        @RequestParam("type") DocType type,
        @RequestParam("file") MultipartFile uploadfile)

Url จะเป็นอย่างไร

http://localhost:8080/file/upload?uuid=46f073d0&type=PASSPORT

ฉันผ่านสอง params (uuid และ type) พร้อมกับอัพโหลดไฟล์ หวังว่าสิ่งนี้จะช่วยให้ผู้ที่ไม่มีข้อมูล json ที่ซับซ้อนในการส่ง


1

คุณสามารถลองใช้https://square.github.io/okhttp/ไลบรารี่ คุณสามารถตั้งค่าคำขอร่างกายเป็นหลายส่วนแล้วเพิ่มไฟล์และวัตถุ json แยกจากกันดังนี้:

MultipartBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("uploadFile", uploadFile.getName(), okhttp3.RequestBody.create(uploadFile, MediaType.parse("image/png")))
                .addFormDataPart("file metadata", json)
                .build();

        Request request = new Request.Builder()
                .url("https://uploadurl.com/uploadFile")
                .post(requestBody)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

            logger.info(response.body().string());

0
@RequestMapping(value = "/uploadImageJson", method = RequestMethod.POST)
    public @ResponseBody Object jsongStrImage(@RequestParam(value="image") MultipartFile image, @RequestParam String jsonStr) {
-- use  com.fasterxml.jackson.databind.ObjectMapper convert Json String to Object
}

-5

โปรดตรวจสอบให้แน่ใจว่าคุณมีการนำเข้าต่อไปนี้ Ofcourse นำเข้ามาตรฐานอื่น ๆ

import org.springframework.core.io.FileSystemResource


    void uploadzipFiles(String token) {

        RestBuilder rest = new RestBuilder(connectTimeout:10000, readTimeout:20000)

        def zipFile = new File("testdata.zip")
        def Id = "001G00000"
        MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>()
        form.add("id", id)
        form.add('file',new FileSystemResource(zipFile))
        def urld ='''http://URL''';
        def resp = rest.post(urld) {
            header('X-Auth-Token', clientSecret)
            contentType "multipart/form-data"
            body(form)
        }
        println "resp::"+resp
        println "resp::"+resp.text
        println "resp::"+resp.headers
        println "resp::"+resp.body
        println "resp::"+resp.status
    }

1
สิ่งนี้รับjava.lang.ClassCastException: org.springframework.core.io.FileSystemResource cannot be cast to java.lang.String
Mariano Ruiz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.