3

I need write server side part to post a forum reply. I receive a post request with reply text, and attachment which is a base64 encoded string. Is there a way to restore filename and extension from this base64 string, or I need to have them as additional params in request? Is it a right way to post attachment as as base64 string?

EDIT

It's a spring web service, I'm expecting Post request. For now I'm using x-www-form-urlencoded encoding and expect message and encoded file to be a part of form body. But encoding type can be changed if needed. On server side I just retrieve it as requestParams map, and extract encoded String from this map.

user2281439
  • 673
  • 2
  • 11
  • 19
  • I think we need more information. Is this an HTML form POST with `multipart/form-data` encoding you are talking about? If so, what technology are you using on server side to read that? Please edit question to clarify. – Andreas May 17 '16 at 07:52
  • I've edited question. – user2281439 May 17 '16 at 08:01
  • If you want to be able to receive files, i so not think you can use x-www-form-urlencoded. multipart/form-data is commonly used for this – Stian Skjelstad May 17 '16 at 08:15
  • And if I can receive messages from mobile devices? Will it be ok to post this multipart/form-data from device? Is there any advantages with multipart/form-data ? – user2281439 May 17 '16 at 09:05
  • If it is a Spring *Web Service*, why are you using HTML Form Post encoding (`application/x-www-form-urlencoded` or `multipart/form-data`)? A web service would usually receive a SOAP, XML or JSON payload. – Andreas May 17 '16 at 16:12

3 Answers3

5

If the filename/extension are not included within the base64 encoded string (for example in the message) I don't think there is a way to restore it, (can be context depending). Using another encoding type won't change that; e.g. the client has to specify the filename/extension and include it in the request (either as parameter or within the encoded content) before the server can use it.

uniknow
  • 938
  • 6
  • 5
2

Using Apache Tika you can get the file mime-type for most common files, and from that you can extract the file extension.

This will work great if know that you only expect or wish to allow certain types. View almost all common mime-types here.

Note that Apache Tika might have some issue with thread safety.

This is an example with a few popular mime-types and their correlating file extension:

import org.apache.tika.Tika;

import javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class FileTypeResolver {

    private static final Map<String, String> mimeTypeMap;
    static {
        Map<String, String> map = new HashMap<>();
        map.put("application/pdf", "pdf");
        map.put("application/msword", "doc");
        map.put("application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx");
        map.put("application/vnd.ms-excel", "xls");
        mimeTypeMap = Collections.unmodifiableMap(map);
    }

    private static String getFileExtension(String base64) throws IOException {

        byte[] base64Bytes = DatatypeConverter.parseBase64Binary(base64);
        Tika tika = new Tika();
        String fileMimeType = tika.detect(base64Bytes);
        return mimeTypeMap.get(fileMimeType);
    }
}
Stempler
  • 1,309
  • 13
  • 25
-1

In the HTTP request being POST'ed, you need to transfer the filename separate from the message body using the content-disposition header field. Like this:

response.setHeader("Content-Disposition", "attachment;filename=" + filename );

If the POST'ing side does not transmit this header field, there no way to determine the filename. Unless you have agreed some format of the base64 encoded payload which contains it.

tbsalling
  • 4,477
  • 4
  • 30
  • 51
  • `response.setHeader()` is for a response from the server, so a file download. The question is about a file *upload*. – Andreas May 17 '16 at 16:09