2

I have a mysql db and I have a table called User and contains a column called pct that is of Type Blob.

I am using hibernate to carry out a native select query as follows:

   public List<Map<String, Object>> queryExtraction(String sql, QWSInputParam[] qwsInputParams) {

        sql = "SELECT user.name,user.pct FROM user user  WHERE user.id = user.id and user.id in :PARAM0";
        Query query = getSession().createSQLQuery(sql);

        query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
        for (int i = 0; i < qwsInputParams.length; i++) {
            LOGGER.info("PARAM" + i + ": " + Arrays.toString(qwsInputParams[i].getValues()));
            query.setParameterList("PARAM" + i, qwsInputParams[i].getValues());
        }

        //LOGGER.info("Query extraction: " + query.toString());
        //query.setTimeout(QUERY_TIME_OUT);
        List<Map<String, Object>> list = query.list();

        Object value = null;

        for (Map<String, Object> map : list) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                value = entry.getValue();
                System.out.println("0 " + entry.getValue());

            }

        }
        return list;
    }

I cannot use entity because it is a generic method that should cater for any table and therefore not related to a specific table. Basically when the query is executed and for the column pct of type blob the following value is displayed:

[B@1a270232

Based on the post I understand this is a JNI type signature.

The pct value in the table is a picture as follows: enter image description here

Is it possible to convert the value [B@1a270232 to a base64 so that I can display it on my browser? Thanks in advance

user1999453
  • 1,297
  • 4
  • 29
  • 65
  • 1
    To directory answer your "Is it possible to convert ...?" question: No. The JNI type signature does not contain the data itself. But you're really asking the wrong question. What you want to do is not convert the JNI type signature to an image. You need to actually get the content of the blob, not the JNI type signature. You already have it, in the form of a `byte[]`. What you're doing wrong is that you are calling `toString()` on the `byte[]`, which gives you `[B@1a270232`. You just have to convert that `byte[]` to Base64 instead. – Jesper Dec 17 '21 at 08:03
  • @Jesper Hi thanks for your response, can you please guide me where I am calling toString() on the byte? – user1999453 Dec 17 '21 at 08:28
  • I don't know where exactly, it's not in the code that you posted. But `[B@1a270232` is what you get when you call `toString()` on a `byte[]`. The variable `list` at the end of your code contains the result of the query. In there you can find the `byte[]` somewhere. – Jesper Dec 17 '21 at 10:26
  • yes you are right when I debug the code (entry.getValue()) it is byte[] but when I display it System.out.println("1 " + entry.getValue()); it is [B@544797e7. But i am not sure why this is happening. I ve updated the code.Thnks – user1999453 Dec 17 '21 at 10:35
  • 1
    When you do `System.out.println("1 " + entry.getValue());` you are implicitly calling `toString()` on the `byte[]` that `entry.getValue()` returns. – Jesper Dec 17 '21 at 15:29

2 Answers2

1

How about:

// ... once get hold of a byte array:
  byte[] bytes = (byte[]) entry.getValue();

  System.out.println(Base64Utils.encodeToString(bytes));
// ...

Javadoc:

xerx593
  • 12,237
  • 5
  • 33
  • 64
0

An alternative solution using apache IOUtils which matches with your exact requirement.

This is from my Github repo. Where I have the the Entity having:

@Lob
private Byte[] userpicture;

The controller to get image to view:

@GetMapping("appUser/{id}/appUserimage")
    public void renderImageFromDB(@PathVariable String id, HttpServletResponse response) throws IOException {
        AppUserCommand appUserCommand = appUserService.findCommandById(Long.valueOf(id));

        if (appUserCommand.getUserpicture() != null) {
            byte[] byteArray = new byte[appUserCommand.getUserpicture().length];
            int i = 0;

            for (Byte wrappedByte : appUserCommand.getUserpicture()){
                byteArray[i++] = wrappedByte; //auto unboxing
            }

            response.setContentType("image/jpeg");
            InputStream is = new ByteArrayInputStream(byteArray);
            IOUtils.copy(is, response.getOutputStream());
        }
    }

And finally the view where the image is displayed:

<div th:if="${appUser.userpicture == null}">
<img th:src="@{/images/defaultuser.jpg}" width="40" height="40" /> 
<a href="#" th:href="@{'/appUser/' + ${appUser.id} + '/image'}" role="button">Upload</a> </div>
<div th:if="${appUser.userpicture != null}"><img th:src="@{'/appUser/' + ${appUser.id} + '/appUserimage'}" width="40" height="40" /> 
Ajay Kumar
  • 2,906
  • 3
  • 23
  • 46