How to properly show profile picutre for user - java

It seems that my Google-fu has failed me since I can't find similiar problems or solutions.
I want to show users image in the users profile page, but the image eather does not load or just consumes everything else.
The profile picture is save as such:
#Lob
#Basic(fetch = FetchType.EAGER)
private byte[] profilePicture;
This the controlle which should return the image. The HttpServeltResponse is something I found related to this, but I made the image consume the whole page.
#GetMapping("/profile")
public String showporfile(Model model, Principal principal, HttpServletResponse response) throws IOException {
acc = accountRepo.findByUsername(principal.getName());
model.addAttribute("accountName", acc.getName());
model.addAttribute("skills", acc.getSkills());
model.addAttribute("accounts", acc);
/*response.setContentType("image/jpg");
InputStream is = new ByteArrayInputStream(acc.getProfilePicture());
IOUtils.copy(is, response.getOutputStream());*/
return "profile";
}
And this is my HTML in which I have tried to get the picture to show. At the moment I get error stating: The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing). It seems that the image is now going as: http://localhost:8080/[B#1c535b01 and I don't know why that is.
<div th:each="account : ${accounts}">
<label th:text="${account.name}"></label>
<div class="header_image clearfix">
<img th:src="${account.profilePicture}"/>
</div>
</div>
Thank you for advance I have been stuck with this for 3 days now.
EDIT
the image is stored to h2 database and linked to user as seen up.

The first thing you have to understand is that src attribute of the img tag is the URL of the image, and not the image itself.
Given you've already decided to store the image in a database, you'll need to create a separate endpoint to get the image (e.g. "/profile/avatar") where you actually return the image body pretty much the same way you're trying in your commented-out code. And then you would refer to that endpoint in your img src.
BTW, Actually there is a way to embed an image into html using "data" protocol and base64 encoding (here's one example of it), but it's only suitable for tiny images, and I believe you would benefit from learning the usual way first.

Related

What is the proper way to send images from an API to HTML?

My current implementation is the following:
I store the image in binary data in the Database. Then I load it and send it as Base64 data in the Http Response.
API:
#Lob
#Column(length = 16777215)
private byte[] image;
Then load it in the UI <img ng-src="data:image/png;base64, {{product.image}}">
The HTTP Response is Huge for some images. It works well for a couple of images but let's say I want to display 100 images.
Is this the proper way to do it fast and well?
You could just try passing the URL to API in the image node. For example:
<img ng-src="https://api.myhost.com/product/5646/image" />
In most cases it should work just fine.
I don't believe there is a way around that, you're just transferring the size of the image to the HTML instead.
I would recommend against storing images in a database, the correct way to do it would be to store the images on the file system and store the URL within the database.
That should keep your HTTP response small and the HTML will load fast.

How to set URL anchor (hash) in servlets?

Simple question! Don't know why Google doesn't know the answer!
In a Java servlet, how can I set the URL anchor (hash) when returning to the user?
The URL anchor is handled by the browser only and never even reaches the server (it's not part of the request).
What this means is that server-side, either in a servlet as you propose or with any other server-side technology (e.g. PHP), you can redirect to an URL which has the URL anchor set, but you cannot check if an URL anchor was provided in the request you are currently processing.
This limitation prevents you from setting the URL anchor while keeping the rest of the URL unchanged, because the server has no way to differentiate between the address with and without the URL anchor.
So, this, you can do: the canonical address to this answer is this
http://stackoverflow.com/a/27988314/4402557
but the server redirects it to this
http://stackoverflow.com/questions/27987762/how-to-set-url-anchor-hash-in-servlets/27988314#27988314
Note that the part of the URL before the anchor is not the same.
In an HTTP servlet, you can achieve this by using the sendRedirect(String) method of the HTTPServletResponse object passed to your service method, for example
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
/* ... */
response.sendRedirect("http://example.com/your/url#hash");
}
However, this, you cannot do: redirect this
http://example.com/some/url
to this
http://example.com/some/url#there
As far as the server is concerned, both are the same address, it cannot distinguish between them. That makes it impossible to check if the address was the first (the one without the URL anchor) and redirect conditionally if it is. Redirecting without checking will, of course, create a redirect loop.
However, depending on what it is exactly you are trying to accomplish, even if you cannot do it in your servlet, you can probably achieve it with client-side scripting (i.e. JavaScript). Have a look at the window.location.hash property.
Once I encountered a similar need.
My problem was:
I had two different forms on the same jsp page (one for registrations and one for logging in). The forms were made visible by hashes in urls, i.e. http://myapp.com/auth#login made login form visible and http://myapp.com/auth#signup made signup form visible.
I needed to show the validation errors to the user by reloading the same page, but couldn't navigate to hashes from my servlet.
Here's how I showed validation errors (jsp):
<form method="post" action="authentication">
<c:forEach items="${errorSignupMessage}" var="message">
<div class="error-message">${message}</div>
</c:forEach>
..................................
</form>
and errorSignupMessage was the attribute I passed in through servlet
request.setAttribute("errorSignupMessage", array);
The solution:
Firstly, I created the hidden field in my form that had to contain the needed attributes:
<input type="text" name="ACTION" class="hidden important" value="signup" data-attr="${errorSignupMessage != null ? true : false}"/>
the important thing to look at is the attribute data-attr. As you can see, I set the boolean value on the attribute depending on actions from servlet, i.e. if the errorSignupMessage is null, than the user interacted with another form and if errorSignupMessage exists and is not null, then the current form is the one the user interacted with.
Then I went to javascript and using window.onload event did the data attribute detection and wrote some logic for changing the location.hash value.
var authForms = document.getElementsByClassName('important');
function changeHash() {
for(var i = 0; i < authForms.length; ++i) {
var form = authForms[i];
if (form.value === 'signup' && form.getAttribute('data-attr') === 'true') {
location.hash = '#signup';
} else {
location.hash = '#login';
}
}
}
window.onload = changeHash;
This is how I solved that. Of course, you'll need to adopt all this for your needs, but I think you still get the general idea.
Hope it was helpful!

HTML to servlet communication without form tag

Actually I am displaying name dynamically from my database. What I am not getting is that "after retrieving name from a database that is dynamic data. For this 'Name' I need to provide a link" that should display details regarding database table content of 'name' contained table.
Please help me.
Html to servlet Communication without form tag
Regardless the communication is being happen through a Form, it is essentially a GET or POST request. Look up for that to understand that better.
For this 'Name' I need to provide a link" that should display Details regarding Database Table content of 'name' Contained Table.
If I undertood you well, you should create a link that, when clicked, should open a new page with the Details, right?
You can generate a link similar to this:
<a href='http://www.yourwebsite.com/DetailsServlet?id=X'>Show details</a>
Where X is the ID that would be retrieved on your sevlet (or JSP file):
public class DetailsServlet implements HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) {
int id = Integer.parseInt(request.getParameter("id"));
// Get details based on ID and show the page
}
}
After that, you only have to get the Details using that ID and then show them in another page.
A fancier alternative would involve AJAX, but you should really stick to the basics in your state.
Keep that name in tag i.e the name should be between 'a' tag.
Suppose the name you are reading is in 'DbName' field in tag give like
<a href="somepage.jsp?Name=DbName>DbName</a>
And Read That in somepage.jsp file like
request.getParameter("Name");

display an image from server with an output stream

I am trying to show an image from the server in my browser.I am following this link
http://balusc.blogspot.in/2007/04/imageservlet.html. i must say this is pretty well written and documented. I tried this and everything is working fine.
The problem is there when i am using ajax to display this image.the whole image seems to break into some codes inside the div.
i understand that the outputstream used in the code is writing directly to the page.But is it really not possible to handle that outputstream to somehow display the image in image tag of a jsp without having to create a different servlet.
Thank you for reading
You don't need to request image data via AJAX and then manipulate it yourself, in order to display it. Just use an <img> tag!
If /my_url is the location of your image, then
<img src="/my-url" alt="Appropriate description"/>
would do it. NOTE: /my-url doesn't have to be an actual image. It can be any resource (including a servlet) that returns image data with the appropriate MIME type set.
If you want to create the tag dynamically, you can use your favourite library, or do it iwth native JS:
var oImg=document.createElement("img");
oImg.setAttribute('src', '/my-url');
oImg.setAttribute('alt', 'Appropriate description');
oImg.setAttribute('height', imgHeight);
oImg.setAttribute('width', imgWidth);
document.body.appendChild(oImg);
Edit
If you want to be doing this server-side (and if so, is this really AJAX?), then you might want to look at the data uri scheme.
With this scheme, you can data directly to an image tag, without needing to provide it with an HTTP resource. To use this, you convert your outputstream to base64 and use the following:
<img src="data:image/png;base64,converted-data-stream-goes-here..." alt="Who needs HTTP?"/>
The image/png would change depending on the MIME type of your source data.
Read the linked Wikipedia page to fully understand the trade-offs here.
Just adding how i achieved a solution for it.
I referred to a new page(from the page i am submitting the form) through ajax and in the new page i used an image and through its src attribute i called the servlet method which is writing the image through its outputstream.
This way the servlet is writing my image to the new file which i can position anywhere.

Strange behavior with the method getUploadedBlobs

I've a problem with the methode blobstoreService.getUploadedBlobs(). I've a JSP page in wich one I set an uploader like this :
<formname='form' action='<%= blobstoreService.createUploadUrl("/Edit_Engine") %>' method='POST' enctype='multipart/form-data' >
<input label='...' multiple='false' name='myFile' />
//...and multiple input for text
</form>
and I retrieve this code with my servlet :
java.util.Map<String,BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
BlobKey blobK = blobs.get("myFiles[]"); //I don't know why I need to add the characters 's[]' at the end...
But the behavior is strange. The first time I upload an image, everything works. However, the second time, I send my form without uploading somehting (only text data), and then my java code finds a BlobKey. But this BlobKey seems to be the previous sended data, or a corrupted data.
I mean that not normal, because when I deploy this version on my localhost, if the form uploads no file the method getUploadedBlobs returns an empty HashMap. However, when I deploy on google servers, if the form uploads no file, the method getUploadedBlobs seems to return a HashMap with wrong data.
Could you help me? Or tell me if this behaviro is normal...
Many thanks,
bat
If you're getting a valid BlobKey, then myFiles[] is most likely the name given to the file input field in the form. Is that the case? That seems like an odd name for an input field. Are you using a template library to help generate HTML from the JSP?

Categories

Resources