Convert string to blob and save to bank

Asked

Viewed 1,657 times

4

I’m developing a mobile application that has a form where the user can attach an image, the image is being sent as string via Rest to the server and will be saved in the blob database, however, I’m having trouble converting from string to blob next to my api.

Capturing application image via camera:

public void tirarFoto(View view){
    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
    startActivityForResult(intent, 0);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
    if(data != null){
        Bundle bundle = data.getExtras();
        if(bundle != null){
            Bitmap img = (Bitmap) bundle.get("data");
            Toast toast = Toast.makeText(getApplicationContext(), "Foto anexada", Toast.LENGTH_LONG);
            toast.show();
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            img.compress(Bitmap.CompressFormat.JPEG, 100, stream);
            foto = Base64.encodeToString(stream.toByteArray(), Base64.DEFAULT);

        }
    }
}

Sending to my API:

public void registerForms() {

    final String address = frua.getText().toString().trim();
    final String district = fbairro.getText().toString().trim();
    final String city = fcidade.getText().toString().trim();
    final String email = femail.getText().toString().trim();
    final String complement = fcompl.getText().toString().trim();
    final String state = festado.getText().toString().trim();
    final String note = fobs.getText().toString().trim();
    final String countries = fpais.getText().toString().trim();
    progressDialog = ProgressDialog.show(DenunciaActivity.this, "Aguarde um momento", "Enviando...", true, false);

    StringRequest stringRequest = new StringRequest( Request.Method.POST, REGISTER_URL, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {

            if (response.contains("Erro")) {
                progressDialog.dismiss();
                Toast.makeText( DenunciaActivity.this, "Erro ao enviar", Toast.LENGTH_LONG ).show();

            } else {
                progressDialog.dismiss();
                Intent intent = new Intent(DenunciaActivity.this, MainActivity.class);
                Toast.makeText( DenunciaActivity.this, "Enviado com sucesso!", Toast.LENGTH_LONG ).show();
                startActivity(intent);
            }

        }
    },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    progressDialog.dismiss();
                    Toast.makeText( DenunciaActivity.this, error.toString(), Toast.LENGTH_LONG ).show();
                    Log.i( TAG, "Lat: " + error );
                }
            } ) {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> map = new HashMap<String, String>();
            map.put( KEY_USERNAME, name );
            map.put( KEY_DATE, dataFormatada );
            map.put( KEY_STATE, state );
            map.put( KEY_CITY, city );
            map.put( KEY_DISTRICT, district );
            map.put( KEY_ADDRESS, address );
            map.put( KEY_EMAIL, email );
            map.put( KEY_COMPLEMENT, complement );
            map.put( KEY_COUNTRIE, countries );
            map.put( KEY_LAT, String.valueOf( latitude ) );
            map.put( KEY_LONG, String.valueOf( longitude ) );
            map.put( KEY_NOTE, note );
            map.put( KEY_STATUS, "ATIVO" );
            map.put( KEY_IMAGE, foto );
            Log.i( TAG, "Lat: " + longitude +" "+latitude);
            return map;
        }

    };

    RequestQueue requestQueue = Volley.newRequestQueue( this );
    requestQueue.add( stringRequest );
}

My API:

public class Services extends Controller {

public static void denuncia(@Valid String nome, String data, String rua, String bairro, String complemento,
        String cidade, String estado, String pais, String observacao, String email, String latitude,
        String longitude, Status status, String foto) {
    if (validation.hasErrors()) {
        String mensagem = "Erro ao cadastrar";
        JsonObject j = new JsonObject();
        j.addProperty("Erro", 404);
        j.addProperty("msg", mensagem);
        renderJSON(j);
    } else {
        byte[] decodedBytes = Base64.decodeBase64(foto);
        String msgsucess = "Cadastrado com sucesso!";
        Denuncia denuncia = new Denuncia();
        denuncia.nome = nome;
        denuncia.data = data;
        denuncia.rua = rua;
        denuncia.bairro = bairro;
        denuncia.complemento = complemento;
        denuncia.cidade = cidade;
        denuncia.estado = estado;
        denuncia.pais = pais;
        denuncia.observacao = observacao;
        denuncia.email = email;
        denuncia.latitude = latitude;
        denuncia.longitude = longitude;
        denuncia.status = status;
        if(foto == null) {
            denuncia.foto = null;
        }else {
            denuncia.foto = decodedBytes;
        }
        denuncia.save();
        JsonObject j = new JsonObject();
        j.addProperty("Success", 200);
        j.addProperty("msg", msgsucess);
        renderJSON(j);
    }
}
}

my model:

public Blob foto;

3 answers

1


A blob actually for the database is a byte[], so as the information traffic was done in Base64, you just read this Base64 and convert to byte[] making the Decode of the same.

First of all, add apache-Commons-codec to your project and then, upon receiving your JSON template, you take down Base64:

byte[] decodedBytes = Base64.decodeBase64(base64String);

If you are using Java8 on the server, use the native java conversion:

byte[] decodedString = Base64.getDecoder().decode(encodedString.getBytes(StandardCharsets.UTF_8));
  • Infomatica CDS gives the following error: Type Mismatch: cannot Convert from byte[] to Blob

  • And if you change the Blob field type to byte[], and save?

  • changing to byte[] it returns error: Value Too long for column "PHOTO BINARY(255)": "X'ffd8ffe000104a46494600010100000100010000ff0043000101010101010101010101010101010101010101010101010101010101010101010101010101010101... (50366)"; SQL statement:

  • Binary n may have size, so the error. In your database do not have a blob type, or image? Use them but leave no size.

  • As described in the question, my bank already this public Blob photo;

  • Which bank are you using? Could be a ORM problem then.

  • Local database H2, because it’s only for testing. But I have another model with Blob that can save attached images to html, and saves normally. Pro eh only with images coming from the application.

Show 2 more comments

0

Handling Base64 vc need to pay attention to small details, in the web vc define page break among other things, depending on use, on android is not necessary to do this, so you can indicate in the field 'flags' the type of encoding, remembering that for each type of encoding you must use the same type to decode: source here

String text = "somenews";
byte[] dataParaEncode = text.getBytes(StandardCharsets.UTF_8);
//Usar UTF-8 se vc estiver usando o charset da sua requisição como UTF-8
String base64 = Base64.encodeToString(dataParaEncode, Base64.NO_WRAP);
//User NO_WRAP para não haver quebra de paginas, mais indicado para uso quando tratar imagens em base64

Decoding

byte[] data = Base64.decode(base64, Base64.NO_WRAP);
String textDecoded = new String(data, StandardCharsets.UTF_8);

In your case the variable data will be yours "Blob"

-1

Blob blob = new SerialBlob(foto.getBytes());
denuncia.foto = blob;

an option!

    byte[] byteData = foto.getBytes("UTF-8");
    Blob blobData = conexao.createBlob();
    blobData.setBytes(1, byteData);
  • from the following error: Type Mismatch: cannot Convert from Serialblob to Blob

  • see if the yes works!

  • Doing so you’re only getting the byte representation of the string, not Base64 content.

  • Have some other simpler way to save image coming from apk?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.