0

I have an ajax post that posts some values from url

var sendUrl = url + ',' + testId + ',' +questionId + ',' + questionRevision + ',' + result;   
 var ajaxData = {
                type: "POST",
                contentType : 'application/json; charset=utf-8',
                dataType : 'json',
                data: requestData,
                url: sendUrl,
                headers: headersData,
        };

and bind them with @PathVariable like this:

@RequestMapping(value="/answer,{testId},{qid},{qrev},{qres}", method = RequestMethod.POST)
    public @ResponseBody String answer(HttpServletRequest request, 
                            @RequestBody List<NokDataDTO> nokInfoDtos ,
                            @PathVariable("testId") Long testId,
                            @PathVariable("qid") Long qid,
                            @PathVariable("qrev") Integer qrev,
                            @PathVariable("qres") Integer qres) 

With this scenario, is there a way to pass an image file with @PathVariable? I can get the uploaded file from the javascript like this:

var fileVal=document.getElementById("fileLoader").files[0];

but can not find a way to bind it from the RequestMapping.

Doga Ozdemir
  • 89
  • 1
  • 12
  • 2
    You could convert the image to a base64 string and POST that just like the other values. See: https://stackoverflow.com/questions/6150289/how-to-convert-image-into-base64-string-using-javascript – Luke Stoward Dec 18 '17 at 16:16

2 Answers2

0

When you're ready to send the data to the server you could get the file from the element using the element.files[0] property and then convert that to a base64 string which could be sent to the server just like your other values.

const file = document.getElementById("fileLoader").files[0];

const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function() {
  // Post to server
  const base64Img = reader.result;
};
reader.onerror = function(error) {
  console.log('Error: ', error);
};
Luke Stoward
  • 1,480
  • 14
  • 24
  • hi @luke , there is a problem that when I try to send reader.result as a url parameter, it says URI is too large >8192 . On the server side I was planing to bind it like: @PathVariable("photo") String photo – Doga Ozdemir Dec 19 '17 at 09:02
  • Then you would need to POST the data in the body instead of adding it to the URL. Otherwise as you've encountered, you will exceed the URL character limit. – Luke Stoward Dec 19 '17 at 10:34
  • With using FormData maybe? how should I pass it with this POST? var fd = new FormData(); fd.append('photo', file); var ajaxData = { type: "POST", contentType : 'application/json; charset=utf-8', dataType : 'json', data: requestData, url: sendUrl, headers: headersData, }; And then I need to use both @PathVariable and @RequestParam(value="photo") that looks tricky. – Doga Ozdemir Dec 19 '17 at 10:58
  • Using the `@RequestBody` tag, you would need to change the model you are binding to, to include the base64 string. In the JS side, you would add the base64 string to the `requestData` object before POSTing. – Luke Stoward Dec 19 '17 at 11:01
  • I am getting Uncaught TypeError: Illegal invocation error. I will be so glad that if you can write sample code, please? – Doga Ozdemir Dec 19 '17 at 11:40
  • Solved with formData way and bind them with @RequestParam . Thanks anyway – Doga Ozdemir Dec 20 '17 at 06:26
  • @DogaOzdemir Nice! So did you use the above solution to convert an image to base64? – Luke Stoward Dec 20 '17 at 08:53
  • nope, just appened it as a file just like this: const file=document.getElementById("fileLoader").files[0]; var fd = new FormData(); fd.append('photo', file); and bind it with MultipartFile type. – Doga Ozdemir Dec 20 '17 at 10:21
  • Probably worth adding your solution to this question then, to help others who come across it. – Luke Stoward Dec 20 '17 at 10:25
0

I found the solution with using javascript FormData(). Get the file and append all of your values to FormData and post it as formData object like this:

   const file=document.getElementById("fileLoader").files[0];
        var fd = new FormData();
        fd.append('photo', file);
        fd.append('testId', testId);
         var ajaxData = {
            type: "POST",
            data: fd,
            processData : false,
            contentType : false,
            url: sendUrl,
            headers: headersData,
    };

and on the backend side, bind them with param names:

@RequestMapping(value="/answer", method = RequestMethod.POST)
    public @ResponseBody String answer(HttpServletRequest request, 
            @RequestParam(value = "photo") MultipartFile photo,
            @RequestParam(value = "testId") String testId

It worked for me.

Doga Ozdemir
  • 89
  • 1
  • 12