How to show image from H2 database to Thymeleaf? - spring-mvc

I'm doing spring boot, using H2 database, thymeleaf view.
I have a form to upload image to save into H2 database(byte[] image),
In thymeleaf, how to show image? anyone tell me the solution?
controller:
#RequestMapping(value = "user/new", method = RequestMethod.GET)
public String newBeans(Model model) {
model.addAttribute("usersss", new Beans());
return "userform";
}
#RequestMapping(value = "user", method = RequestMethod.POST)
public String saveUser(Beans beans) {
RepositoryUser.save(beans);
return "redirect:/users";
}
form:
<form>
<label>Avatar:</label>
<input type="file" th:field="${usersss.Avatar}"/>
<button type="submit">Submit</button>
</form>
shows:
<form>
<label>Avatar:</label>
<p>
?????????
</p>
</form>

Although there are many different ways to do this,here is some sample code which you can use for the same :
#RequestMapping(value = "/user/avatar/{userId}", method = RequestMethod.GET)
#ResponseBody
public ResponseEntity<InputStreamResource> downloadUserAvatarImage(#PathVariable Long userId) {
UserObject userAvatar = RepositoryUser.findUserAccountAvatarById(userId);//Could be a handle to a file stream as well,which could be incorporated accordingly
return ResponseEntity.ok()
.headers("Content-Disposition", "inline;filename=\""
+ userAvatar.getUserName() + "\"")
.contentLength(userAvatar.getImageBlob().getLength())
.contentType(MediaType.parseMediaType(userAvatar.getImageBlob().getContentType()))
.body(new InputStreamResource(userAvatar.getImageBlob().getBinaryStream()));
}
And then in your thymeleaf :
<form>
<label >Avatar :</label>
<p>
<img class="picture" th:src="#{'/user/avatar/'+${userId}}" />
</p>
</form>
Hope this helps.

Related

asp.net core - form values return null

Passing department and title models for use data in selectbox and passing employee model for save data from user. tring to pass values from partial view but in controller values return null.
partial view:
#model (List<Department> Departments, List<Title> Titles, Employee e)
<form class="g-3" asp-action="CreateEmployee" asp-controller="Employees" method="post">
<div class="row">
<div class="col-lg-6">
<div class="mb-3">
<label for="Name" class="form-label">İsim</label>
<input asp-for="e.Name" type="text" class="form-control" id="Name">
<div class="invalid-feedback">
İsim alanı boş bırakılamaz.
</div>
</div>
</div>
</div>
<button type="submit">Tek Form</button>
</form>
controller:
public IActionResult CreateEmployee()
{
HR_ManagementContext context = new HR_ManagementContext();
var departments = context.Departments.ToList();
var titles = context.Titles.ToList();
var models = (departments, titles, new Employee());
return View(models);
}
[HttpPost]
public IActionResult CreateEmployee(Employee employee)
{
return RedirectToAction("CreateEmployee");
}
Set the name attribute in the input tag:
<input asp-for="e.Name" type="text" class="form-control" id="Name", name="employee.Name">
The second solution is to use model name item3 generated by the MVC:
[HttpPost]
public IActionResult CreateEmployee(Employee item3)
{
return RedirectToAction("CreateEmployee");
}
Thx #Jackdaw his answer also working too.
I found an alternative
in Controller you can bind model:
public IActionResult CreateEmployee([Bind(Prefix = "Item3")]Employee employee)
{
return RedirectToAction("CreateEmployee");
}
Item3 is the prefix of tuple model.
#model (List<Department> Departments, List<Title> Titles, Employee e)
Department = Item1
Titles = Item2
Employee = Item3

Asp net core 2.2, updating usename not working

I want my user to be able to change his username so i made this:
<form asp-action="UpdateUserProfile" asp-controller="Account" method="post">
<div class="account-details-item">
<h2 class="center-text text-left account-details-item-title">UserName:</h2>
<input name="username" id="username-text" readonly="readonly" class="center-text account-details-item-value" asp-for="User.UserName" value=#Model.User.UserName>
<a id="btn-username" class="account-details-item-btn" >Edit</a>
</div>
<div class="account-details-item">
<h2 class="center-text text-left account-details-item-title">Email:</h2>
<input name="email" readonly="readonly" id="email-text" class="center-text account-details-item-value email" asp-for="User.Email" value=#Model.User.Email />
<a id="btn-email" class="account-details-item-btn" >Edit</a>
</div>
<div class="account-details-item">
<h2 class="center-text text-left account-details-item-title">Phone number:</h2>
<input name="phonenumber" readonly="readonly" id="phone-text" class="center-text account-details-item-value" asp-for="User.PhoneNumber" value=#Model.User.PhoneNumber>
<a id="btn-phone" class="account-details-item-btn" >Edit</a>
</div>
<div class="btns-container">
<div class="btn-item"><a asp-action="Index" asp-controller="Cart" asp-route-id=#Model.User.CartId>Go To Cart</a></div>
<div id="save-btn" class="btn-item"><button type="submit">Save Changes</button></div>
</div>
</form>
And in AccountController:
[HttpPost]
public IActionResult UpdateUserProfile()
{
var username = Request.Form["username"];
var phonenumber = Request.Form["phonenumber"];
var email = Request.Form["email"];
var user = _userService.GetUser(User);
if(`enter code here`IsUsernameDiffrent(username))
{
_userService.UpdateUsername(User, username);
_userManager.UpdateAsync(user.Result);
}
else if(IsEmailDiffrent(email))
{
_userService.UpdateEmail(User, email);
_userManager.UpdateAsync(user.Result);
}
else if (IsPhoneNumberDiffrent(phonenumber))
{
_userService.UpdatePhoneNumber(User, phonenumber);
_userManager.UpdateAsync(user.Result);
}
return RedirectToAction("Index");
}
And in Service Class:
public async void UpdateUsername(ClaimsPrincipal user, string newUsername)
{
var currentUser = await GetUser(user);
currentUser.UserName = newUsername;
_dbContext.SaveChanges();
}
The issue is that if user change his username he still have to login with the old one,
changes are made in database but whenever i try to login with new username it says "Invalid login attempt"
I have an Update User Action in my project and it does work in mine, and its little different from yours, but you can try to change it like that:
[HttpPost]
public async Task<IActionResult> UpdateUserProfile()
{
var user = _userService.GetUser(User);
if (user == null)
{
return StatusCode(404);
}
var username = Request.Form["username"];
if(IsUsernameDifferent(username))
{
user.UserName = username;
var result = await _userManager.UpdateAsync(user);
if (result.Succeeded)
{
return RedirectToAction("Action", "Controller");
}
return View();
}
return View();
}
I feel that more code must be seen to analyze the issue. But, make sure you are using transaction scope in your services when you are making changes to the data in the database like update or delete.
Using this technique will ensure that the code is consistent. Changes to the database will not happen unless everything inside the scope is successful. For example, if you are updating and then deleting, what if while deleting an error occurs. Then your data will be updated in the database but not deleted. This is to make sure that both happens successfully or nothing happens at all.
Refer this link.
https://learn.microsoft.com/en-us/ef/core/saving/transactions

Display uploaded image asp.net mvc

I'm trying to upload image to my folder and the display it in view.
My controller:
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
if (file != null)
{
string pic = System.IO.Path.GetFileName(file.FileName);
string path = System.IO.Path.Combine(Server.MapPath("~/images"), pic);
file.SaveAs(path);
ViewBag.Path = path;
}
return View();
}
My view:
#{
ViewBag.Title = "Upload";
}
#using (Html.BeginForm("Upload", "Home", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<label for="file">Upload Image:</label>
<input type="file" name="file" id="file" style="width: 100%;" />
<input type="submit" value="Upload" class="submit" />
}
<h2>Upload</h2>
<img src="#ViewBag.path" alt="Image"/>
By doing this, image is not in my view, only alt text. HTML source generated:
<img src="C:\Users\D Stag\Documents\Visual Studio 2012\Projects\Data\Web\images\1232743916lituviai23afp.jpg"/>
Image is saved correctly, it exist in that folder.
Instead of -
ViewBag.Path = path;
try that this way -
ViewBag.Path = String.Format("/images/{0}", pic); //output should be "~/images/image1.jpg"
UPDATE: There is no need for "~" in the path. Then image displays.
Example Try like this:
<img src="#string.Format("/Image/{0}",pictue._id.ToString())" alt="#pictue.FileName" />

How to upload file with web-api

Client side code:
<form action="api/MyAPI" method="post" enctype="multipart/form-data">
<label for="somefile">File</label> <input name="somefile" type="file" />
<input type="submit" value="Submit" />
</form>
And how to process upload file with mvc web-api,have some sample code?
HTML Code:
<form action="api/MyAPI" method="post" enctype="multipart/form-data">
<label for="somefile">File</label>
<input name="somefile" type="file" />
<input type="submit" value="Submit" />
</form>
Controller
// POST api/MyAPI
public HttpResponseMessage Post()
{
HttpResponseMessage result = null;
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Files.AllKeys[0] == "image")
{
if (httpRequest.Files.Count > 0)
{
var docfiles = new List<string>();
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
var filePath = HttpContext.Current.Server.MapPath("~/Images/" + postedFile.FileName);
postedFile.SaveAs(filePath);
docfiles.Add(filePath);
}
result = Request.CreateResponse(HttpStatusCode.Created, docfiles);
}
}
else
{
result = Request.CreateResponse(HttpStatusCode.BadRequest);
}
return result;
}
try below link
this link use for me hopefully it will work you
http://www.asp.net/web-api/overview/advanced/sending-html-form-data,-part-2
You can use ApiMultipartFormFormmatter to upload file to web api 2.
By using this library, you can define a view model to get parameters submitted from client-side. Such as:
public class UploadFileViewModel
{
public HttpFile Somefile{get;set;}
}
And use it in your Api controller like this:
public IHttpActionResult Upload(UploadFileViewModel info)
{
if (info == null)
{
info = new UploadFileViewModel();
Validate(info);
}
if (!ModelState.IsValid)
return BadRequest(ModelState);
return Ok();
}
Nested objects can be parsed by this library.

spring 3 upload many files

yeah,our customer want to upload more than one file.
we use spring 3 mvc.
the official example like this:
markup:
<form method="post" action="/form" enctype="multipart/form-data">
<input type="text" name="name"/>
<input type="file" name="file"/>
<input type="submit"/>
</form>
code:
#RequestMapping(value = "/form", method = RequestMethod.POST)
public String handleFormUpload(#RequestParam("name") String name,
#RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
byte[] bytes = file.getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
} else {
return "redirect:uploadFailure";
}
}
there is only one file,so i can write the file input name in the method.
but what should i do if i want to upload many files.
i could not write all the file input names because if is generated by the js code.
i only know that its name like 'attach_'
then ,what should i write in the method ? if i write like this
#RequestParam() MultipartFile file
or
#RequestParam("attach_") MultipartFile file
i'll get a error.
A much simpler way - works for me
/*** Upload Images ***/
#RequestMapping(value = "/images/upload", method = RequestMethod.POST)
public void upload(#RequestParam("file") List<MultipartFile> files, #RequestParam("user") String user) {
files.forEach((file -> System.out.println(file.getOriginalFilename())));
}
I have it working with Spring 3.0.4 (there was an issue in previous versions of Spring, so be sure to use >= 3.0.4).
To test it, you can use the following steps:
public class MultiPartFileUploadBean {
private List<MultipartFile> files;
public void setFiles(List<MultipartFile> files) {
this.files = files;
}
public List<MultipartFile> getFiles() {
return files;
}
}
The controller:
#RequestMapping(value = "/uploadtest", method = RequestMethod.POST)
public String uploadtestProcess(MultiPartFileUploadBean file, BindingResult bindingResult,
Model model) throws IOException {
... // binding check
StringBuilder sb = new StringBuilder();
List<MultipartFile> files = file.getFiles();
for(MultipartFile f:files)
sb.append(String.format("File: %s, contains: %s<br/>\n",f.getOriginalFilename(),new String(f.getBytes())));
String content = sb.toString();
model.addAttribute("content", content);
return "uploadtest";
}
The jsp:
<form method="post" action="/uploadtest" enctype="multipart/form-data">
<p>Type: <input type="text" name="type" value="multiPartFileSingle" size="60" /></p>
<p>File 1: <input type="file" name="files[0]" size="60" /></p>
<p>File 2: <input type="file" name="files[1]" size="60" /></p>
<p><input type="submit" value="Upload" /></p>
</form>
<c:if test="${not empty content}">
<p>The content uploaded: <br/>${content}</p>
I found clearer to use the MultipartHttpServletRequest object as a parameter to the controller method:
#RequestMapping(value = "/save", method=RequestMethod.POST)
protected String save(Model model, MultipartHttpServletRequest multipartRequest) {
MultipartFile file = multipartRequest.getFile("field-name");
// Also multiple files with same name
List<MultipartFile> files = multipartRequest.getFiles("multifield-name");
// ...
}
Link to the docs: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-multipart-resolver-commons
You use model and form.
( Html / Jsp )
<form id="uploadForm" method="POST"enctype="multipart/form-data/charset=UTF-8">
//...multi file, add dynamic input
<input type="file" name="file"/>
<input type="file" name="file"/>
<input type="file" name="file"/>
<input type="file" name="file"/>
</form>
<input type="button" id="save_button" value="save" />
(Js)
var form = new FormData(document
.getElementById('uploadForm'));
$.ajax({
url : "/test/upload/file,
type : 'POST',
dataType : 'text',
data : form,
processData : false,
contentType : false,
success : function(response) {
if (response == "success") {
document.location.reload(true);
} else {
$("#editMsg").text("fail");
}
},
error : function(request, status, error) {
}
});
( Model )
public class fileModel {
private List<MultipartFile> file; // this name = input name
... setter, getter
}
( Controller )
#RequestMapping(value = "/upload/file", method = RequestMethod.POST)
public #ResponseBody String uploadFiles(fileModel model, HttpServletRequest req) {
return "success" // <-- debug. break point !! Your watch model.
}
You can find it here:
http://dhruba.name/2008/12/27/implementing-single-and-multiple-file-multipart-uploads-using-spring-25/

Resources