I have a BLOB type image in mysql database and I want to show the image on the jsp. I am using Hibernate and Spring MVC. This is my Model class:
#Repository
#Entity
#Table(name = "foto")
public class Image {
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "fk_id_users", nullable = false)
private Users user;
#Id
#Column(name = "id_foto")
#GeneratedValue(strategy = GenerationType.AUTO)
private int id_foto;
#Column(name = "tipo")
private String tipo;
#Column(name = "size")
private String size;
#Column(name = "nome")
private String nome;
#Column(name = "image")
private byte[] image;
//Getters and Setters
this is my controller:
#Controller
#SessionAttributes("UserSession")
public class LoginController {
#Autowired
private UsersService usersService;
#RequestMapping(value = "loginUsers", method = RequestMethod.POST)
public ModelAndView loginUsers(HttpServletRequest request,#RequestParam("username") String username,
#RequestParam("password") String password) {
Users user = usersService.loginUsers(username, password);
if( user == null ) {
ModelAndView MV = new ModelAndView("login");
MV.addObject("erroreLogin", "username e/o password errati");
return MV;
} else if ( user.getAmministratore() == false ){
request.getSession().setAttribute("UserSession",user);
ModelAndView mav = new ModelAndView("homeUtente");
mav.addObject("galleria", usersService.getAllFoto());
return mav;
} else {
request.getSession().setAttribute("UserSession",user);
ModelAndView mav = new ModelAndView("utenti");
mav.addObject("lista", usersService.getAllUtenti());
return mav;
}
}
#RequestMapping(value = "logout", method = RequestMethod.GET)
public ModelAndView logout(HttpServletRequest request) {
request.getSession().invalidate(); //invalido i dati presenti in sessione
return new ModelAndView("login");
}
}
and in my jsp I use this for show my image from Image List because each user have a gallery to display:
<img alt="Kangoo_image" src="data:image/jpeg;base64,${galleria.image}" />
when i'm trying to display it in my jsp.It is showing something binary like [B#59e73b47. how can i display the image here in jsp?
To show the image on JSP without storing to filesystem and linking to it, you'll have to do a Base64 encoding of the byte array. Easily done by following lines
byte[] encodeBase64 = Base64.encodeBase64(usersService.getAllFoto());
String base64Encoded = new String(encodeBase64, "UTF-8");
mav.addObject("galleria", usersService.getAllFoto());
Both IOUtils and Base64 are from org.apache.commonsEndFragment
this appends beacause galleria.image returns a byte[] type, and on the resulting html of the jsp appear the byte[].toString() value. exactly [B#59e73b47.
you should use something like:
<img alt="Kangoo_image" src="data:image/jpeg;base64,new String(${galleria.image})" />
or
<img alt="Kangoo_image" src="/getImage/${galleria.id_foto}" />
and in in the getImage controller somthing like this
#Autowired
private HttpServletRequest request;
#RequestMapping("/getImage/*")
public void getImage(ModelMap model, HttpServletResponse response)
throws IOException {
requestUri = requestUri.substring((request.getContextPath() + "/getImage/")
.length());
Image image = DAO.findById(requestUri);
String requestUri = request.getRequestURI();
InputStream is = new ByteArrayInputStream(image.getImage());
response.setContentType("image/jpeg");
String name = image.getName() + ".jpeg";
String attachment = "inline; filename=" + name;
response.setHeader("content-Disposition", attachment);
response.setContentLength((int) baos.toByteArray().length);
IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
is.close();
}
#Controller
#SessionAttributes("UserSession")
public class LoginController {
#Autowired
private UsersService usersService;
#RequestMapping(value = "loginUsers", method = RequestMethod.POST)
public ModelAndView loginUsers(HttpServletRequest request,#RequestParam("username") String username,
#RequestParam("password") String password) {
Users user = usersService.loginUsers(username, password);
if( user == null ) {
ModelAndView MV = new ModelAndView("login");
MV.addObject("erroreLogin", "username e/o password errati");
return MV;
} else if ( user.getAmministratore() == false ){
request.getSession().setAttribute("UserSession",user);
ModelAndView mav = new ModelAndView("homeUtente");
byte[] encodeBase64 = Base64.encode(usersService.getAllFoto());
String base64Encoded = new String(encodeBase64, "UTF-8");
mav.addObject("userImage", base64Encoded )
return mav;
} else {
request.getSession().setAttribute("UserSession",user);
ModelAndView mav = new ModelAndView("utenti");
mav.addObject("lista", usersService.getAllUtenti());
return mav;
}
}
#RequestMapping(value = "logout", method = RequestMethod.GET)
public ModelAndView logout(HttpServletRequest request) {
request.getSession().invalidate(); //invalido i dati presenti in sessione
return new ModelAndView("login");
}
}
and in jsp code use this code to display image
<img src="data:image/jpeg;base64,${userImage}" />
Related
I uploaded a file using multipart successfully and appended the entity class id to it. Sending a get request returns a null value.
This is my post endpoint:
#PostMapping("/{id}/upload_multiple")
public ResponseEntity<ResponseMessage> createDocument(#PathVariable Long id,
#RequestParam("applicationLetter") MultipartFile appLetter,
#RequestParam("certificateOfInc") MultipartFile cInc, #RequestParam("paymentReceipt") MultipartFile payment,
#RequestParam("taxClearance") MultipartFile tax, #RequestParam("staffsResume") MultipartFile staffs,
#RequestParam("letterOfCredibility") MultipartFile credibility,
#RequestParam("workCertificate") MultipartFile workCert,
#RequestParam("consentAffidavit") MultipartFile affidavit,
#RequestParam("collaborationCert") MultipartFile colabo, #RequestParam("directorsId") MultipartFile idcard,
#RequestParam("membership") MultipartFile member) throws IOException {
documentService.create(id, appLetter, cInc, payment, tax, staffs, credibility, workCert, affidavit, colabo,
idcard, member);
String message = "Upload successful";
return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message));
}
uploaded files are saved in a another folder 10001 which is the ID of the document entity. My challenge now is to get those files from 10001 folder.
This is what I tried but is returning null value for all the documents:
#GetMapping( "/files/{filename:.+}/{id}")
public ResponseEntity<Resource> getFile(#PathVariable String filename) {
Resource file = documentService.load(filename);
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType("application/octet-stream"))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"")
.body(file);
}
My service class:
private final Path root = Paths.get("documents");
#Override
public Resource load(String filename) {
try {
Path file = root.resolve(filename);
Resource resource = new UrlResource(file.toUri());
if (resource.exists() || resource.isReadable()) {
return resource;
} else {
throw new RuntimeException("Could not read the file!");
}
} catch (MalformedURLException e) {
throw new RuntimeException("Error: " + e.getMessage());
}
}
My Entity class:
#Entity
#Getter
#Setter
public class Documents {
#Id
#Column(nullable = false, updatable = false)
#SequenceGenerator(
name = "primary_sequence",
sequenceName = "primary_sequence",
allocationSize = 1,
initialValue = 10000
)
#GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "primary_sequence"
)
private Long id;
#Column(nullable = false)
private String applicationLetter;
#Column(nullable = false)
private String certOfIncorporation;
#Column(nullable = false)
private String paymentReceipt;
#Column(nullable = false)
private String taxClearance;
#Column(nullable = false)
private String staffsResume;
}
refer this example :
#GetMapping("/files")
public ResponseEntity<List<ResponseFile>> getListFiles() {
List<ResponseFile> files = storageService.getAllFiles().map(dbFile -> {
String fileDownloadUri = ServletUriComponentsBuilder
.fromCurrentContextPath()
.path("/files/")
.path(dbFile.getId())
.toUriString();
return new ResponseFile(
dbFile.getName(),
fileDownloadUri,
dbFile.getType(),
dbFile.getData().length);
}).collect(Collectors.toList());
return ResponseEntity.status(HttpStatus.OK).body(files);
}
#GetMapping("/files/{id}")
public ResponseEntity<byte[]> getFile(#PathVariable String id) {
FileDB fileDB = storageService.getFile(id);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileDB.getName() + "\"")
.body(fileDB.getData());
}
Try this method for loading resource. to see if it works
Resource file = fileStorageService.loadFileAsResource(fileName);
Try this code
#GetMapping( "/files/{filename:.+}/{id}")
public void getFile(#PathVariable String filename, HttpServletRequest request, final HttpServletResponse response) {
BufferedInputStream bufferedInputStream = null;
try {
File file = ...;
response.setHeader("Cache-Control", "must-revalidate");
response.setHeader("Pragma", "public");
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Content-disposition", "attachment; ");
bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
FileCopyUtils.copy(bufferedInputStream, response.getOutputStream());
} catch (Exception e) {
logger.error(e.getMesssage(), e);
} finally {
try {
response.getOutputStream().flush();
response.getOutputStream().close();
} catch (Exception ex) {
logger.error(ex);
}
try {
if (bufferedInputStream != null)
bufferedInputStream.close();
} catch (Exception ex) {
logger.error(ex);
}
}
}
I'm not sure it will work with your system, but for me I still use this method to download files normally.
I want to write unit test cases for the following spring MVC controller.
#Controller
#Configuration
#PropertySource("classpath:project/web/properties/RealTimeAPI.properties")
#RequestMapping("/learnon")
public class ClassManagerController {
private final Logger logger = Logger.getLogger(ClassManagerController.class);
#Autowired
private ClassManagerService classManagerService;
#Autowired
private GroupUserService groupUserService;
#RequestMapping(value = "/teacher", method = RequestMethod.GET)
public ModelAndView showClassDetail(HttpServletRequest request, HttpSession httpSession,
#RequestParam(value = "isbn", required = false) String isbn13,
#RequestParam(value = "classId", required = false) Long classId) {
String redirectUrl = "https://example.com/jsp/Login.jsp?reason=failedLogin&redirectUri=https://example.com/secure/Bookshelf";
String accessDeniedUri = "https://example.com/jsp/AccessDenied.jsp";
if (httpSession.getAttribute("USERID") == null) {
return new ModelAndView("redirect:" + redirectUrl);
}
try {
long userId = Long.parseLong(httpSession.getAttribute("USERID").toString());
UserBean user = classManagerService.getUser(userId);
if (httpSession.getAttribute("SCHOOLID") == null) {
httpSession.setAttribute("SCHOOLID", user.getSchoolId());
}
if (httpSession.getAttribute("FULLFILLMENT_YEAR") == null) {
httpSession.setAttribute("FULLFILLMENT_YEAR", user.getFulfillmentYear());
}
String isbn10 = ISBNUtil.convertIsbn13ToIsbn10(isbn13);
String title = "";
ModelAndView mav = null;
ClassManagerBean classBean = null;
if(classId == null && httpSession.getAttribute("classId") != null){
classId = (Long)httpSession.getAttribute("classId");
}
if(classId != null && classId > 0) {
List<UserBean> userBeanList = classManagerService.getUserList(user.getSchoolId(), classId, isbn10);
classBean = classManagerService.getClassById(classId);
classBean.setUserNumber(userBeanList.size());
title = classBean.getTitle();
//Set the view to ClassManager.jsp
mav = new ModelAndView("ClassManager");
mav.addObject("userList", userBeanList);
boolean authorized = userBeanList.stream().anyMatch(u->u.getUserId() == userId);
if(!authorized){
ModelAndView modelAndView = new ModelAndView("redirect:" + accessDeniedUri);
modelAndView.addObject("accessDenied", "true");
return modelAndView;
}
}else{
title = classManagerService.getTitle(isbn10);
//Set the view to createNewClass.jsp
mav = new ModelAndView("CreateNewClass");
classBean = new ClassManagerBean();
classBean.setLo2Flag(true);
classBean.setIsbn(isbn10);
classBean.setTitle(title);
}
httpSession.setAttribute("searchTitle", title);
httpSession.setAttribute("selectedIsbn", isbn10);
httpSession.setAttribute("classId", classId);
mav.addObject("user", user);
mav.addObject("classBean", classBean);
return mav;
} catch (Exception ex) {
ModelAndView mav2 = new ModelAndView("redirect:" + accessDeniedUri);
mav2.addObject("accessDenied", "true");
logger.error("Exception Occurred, Redirecting to Access Denied...", ex);
return mav2;
}
}
}
I have written the following unit test cases for the above class.
#RunWith(PowerMockRunner.class)
public class ClassManagerControllerTest {
public ClassManagerService classManagerService;
public GroupUserService groupUserService;
private MockMvc mockMvc;
#InjectMocks
private ClassManagerController classManagerController;
#Before
public void setUp() {
classManagerService = Mockito.mock(ClassManagerService.class);
groupUserService = Mockito.mock(GroupUserService.class);
mockMvc = MockMvcBuilders.standaloneSetup(classManagerController).build();
}
#Test
public void testShowClassDetail() throws Exception {
HttpServletRequest httpRequest = mock(HttpServletRequest.class);
HttpSession httpSession = mock(HttpSession.class);
Mockito.when(httpSession.getAttribute("USERID")).thenReturn(null);
RequestBuilder request = MockMvcRequestBuilders
.get("/learnon/teacher")
.param("isbn", "1234567890123")
.param("classId", "1")
.accept(MediaType.APPLICATION_JSON);
String modalView = "redirect:" + "https://example.com/jsp/Login.jsp?reason=failedLogin&redirectUri=https://www.example.com/secure/Bookshelf";
ResultActions result = mockMvc.perform(request)
.andExpect(status().is3xxRedirection())
.andExpect(view().name(modalView));
}
#Test
public void testShowClassDetail1() throws Exception {
HttpServletRequest httpRequest = mock(HttpServletRequest.class);
HttpSession httpSession = mock(HttpSession.class);
Mockito.when(httpSession.getAttribute("USERID")).thenReturn(Mockito.anyString());
//Line 87
List<UserBean> spyList = Mockito.mock(List.class);
Mockito.when(classManagerService.getUserList(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyString())).thenReturn(spyList);
Mockito.when(spyList.stream().anyMatch(u->u.getUserId() == Mockito.anyLong())).thenReturn(true);
RequestBuilder request = MockMvcRequestBuilders
.get("/learnon/teacher")
.param("isbn", "1234567890123")
.param("classId", "1")
.accept(MediaType.APPLICATION_JSON);
String modalView = "redirect:" + "https://example.com/jsp/AccessDenied.jsp";
ResultActions result = mockMvc.perform(request)
.andExpect(status().is3xxRedirection())
.andExpect(view().name(modalView));
}
first unit test case is passed successfully.
second test failed with following error.
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced argument matcher detected here:
-> at learnonclassmanager.spring.web.controller.ClassManagerControllerTest.testShowClassDetail1(ClassManagerControllerTest.java:87)
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
verify(mock).someMethod(contains("foo"))
Also, this error might show up because you use argument matchers with
methods that cannot be mocked. Following methods cannot be
stubbed/verified: final/private/equals()/hashCode(). Mocking methods
declared on non-public parent classes is not supported.
at
learnonclassmanager.spring.web.controller.ClassManagerControllerTest.testShowClassDetail1(ClassManagerControllerTest.java:90)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
The problem is with the code :
Mockito.when(httpSession.getAttribute("USERID")).thenReturn(Mockito.anyString());
httpSession.getAttribute("USERID") actually returns "Object", while you are returning a String.
If you try,
Mockito.when(httpSession.getAttribute("USERID")).thenReturn(new String("anyString"));,
then I works just fine.
Hope if it works for you.
I have created a controller:
#RequestMapping(value = "/photo/" , method = RequestMethod.POST)
public #ResponseBody
void addPhotoData(#RequestBody Photo photo, #RequestParam("data")
MultipartFile photoData) {
InputStream in = null;
try {
in = photoData.getInputStream();
photoService.save(photo, in);
} catch (IOException e) {
e.printStackTrace();
}
}
and I send the request with Postman:
I cannot understand why I receive the error 415 not supported.
Help!
Try wrapping the request body into an object.
public class Payload {
private String name;
private String url;
private MultipartFile data;
...
}
Add consumes = { "multipart/form-data" } and
#RequestMapping(value = "/photo/" , method = RequestMethod.POST, consumes = { "multipart/form-data" })
public #ResponseBody void addPhotoData(#ModelAttribute Payload payload) {
...
}
There is also MediaType.MULTIPART_FORM_DATA_VALUE constant instead of using that string
This is called multipart mixed type. Try changing your signature like this
#RequestMapping(value = "/photo/" , method = RequestMethod.POST, consumes = {"multipart/mixed"})
public #ResponseBody void addPhotoData(#RequestPart Photo photo, #RequestPart("data")
MultipartFile photoData) {
#Controller
#RequestMapping(value = "/admin/room")
public class Roomcontroller {
#Autowired
private RoomService roomService;
#RequestMapping(method = RequestMethod.GET)
public String index(ModelMap map) throws SQLException {
map.addAttribute("Room", roomService.getAll());
return "admin/room/index";
}
#RequestMapping(value = "/addroom", method = RequestMethod.GET)
public String addRoom() throws SQLException {
return "admin/room/addroom";
}
#RequestMapping(value = "/editroom/{ro_id}", method = RequestMethod.GET)
public ModelAndView edit(#PathVariable("ro_id") int ro_id) throws SQLException {
ModelAndView mv = new ModelAndView("admin/room/editroom");
mv.addObject("Room", roomService.getById(ro_id));
return mv;
}
#RequestMapping(value = "/deleteroom/{ro_id}", method = RequestMethod.GET)
public String delete(#PathVariable("ro_id") int ro_id) throws SQLException {
roomService.delete(ro_id);
return "redirect:/admin/room";
}
this portion of the code is used for saving image and other entities but I am not able to see the image stored in desired folder
#RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(#RequestParam("roomType") String roomType,
#RequestParam("roomDescription") String roomDescription, #RequestParam("roomNumber") int roomNumber,
#RequestParam("file") MultipartFile multipartFile, HttpServletRequest req) throws SQLException, IOException {
Room room = new Room();
room.setRoom_type(roomType);
room.setRoom_description(roomDescription);
room.setRoom_number(roomNumber);
// TO DO : Save room, fetch the id of saved room and set it through
// setter in above object.
if(room.getRo_id()==0){
String serverRootPath = req.getServletContext().getRealPath("");
System.out.println(serverRootPath);
// You can change the directory.
File roomImageDirectory = new File(serverRootPath + "D:\\Hotels\\ploadedImages");
if (!roomImageDirectory.exists()) {
roomImageDirectory.mkdirs();
}
String[] fileNameToken = multipartFile.getOriginalFilename().split("\\.");
// You can change file name to be saved.
String newFileName = "room-" + room.getRo_id() + "." + fileNameToken[fileNameToken.length - 1];
File roomImage = new File(roomImageDirectory, "/" + newFileName);
roomImage.createNewFile();
multipartFile.transferTo(roomImage);
room.setImage(newFileName);
roomService.insert(room);
}
else{
roomService.update(room);
}
return "redirect:/admin/room";
}
}
According to your code, you want to save your file under D:\\Hotels\\ploadedImages. So you don't need to use req.getServletContext().getRealPath(""). Just change your code like this
File roomImageDirectory = new File("D:\\Hotels\\ploadedImages");
...
File roomImage = new File(roomImageDirectory, "/" + newFileName);
I prefer File.separator instead of using / or \\
probably you are constructing a wrong path
try,
String pathToUpload = req.getServletContext().getRealPath("/fileuploads");
File f = new File(pathToUpload);
if(f.exists() && !f.isDirectory()) {
f.mkdir();
}
String orgName = multipartFile.getOriginalFilename();
String filePath = pathToUpload + orgName;
File dest = new File(pathToUpload);
file.transferTo(dest);
you should see file created inside root folder of your application context.
I am working in spring mvc project.
I am able to run my project in my local without any issues. I did a page for file upload using controller.
While I used this with production, I am not able to get the results and getting the error
"org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'userId' is not present
my code : (I am getting this user Id in upload screen)
#Resource
private UserService userService;
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
Long userId = userService.getLoggedInUser(request).getId();
ModelAndView modelAndView = new ModelAndView(UploadDocView.uploadmain);
modelAndView.addObject("userId", userId);
return modelAndView;
}
upload jsp
<form method="POST" enctype="multipart/form-data" action="upload.htm">
File to upload:
<input type="file" name="file"><br />
<input type="hidden" name="userId" value="${userId}"><br /> <br />
<input type="submit" value="Upload">
</form>
FileUploadController
#Controller
public class FileUploadController {
#Resource
private CollectionsRepository collectionsRepository;
#RequestMapping(value="/upload", method=RequestMethod.GET)
public #ResponseBody String provideUploadInfo() {
return "You can upload a file by posting to this same URL.";
}
#RequestMapping(value="/upload.htm", method=RequestMethod.POST)
public ModelAndView handleFileUpload(#RequestParam("userId") String userId, #RequestParam("file") MultipartFile file){
if (!file.isEmpty()) {
try {
String filePath = "/home/ubuntu/analyzer/LOS/";
byte[] bytes = file.getBytes();
File newFile = new File(filePath+""+file.getOriginalFilename());
BufferedOutputStream stream =
new BufferedOutputStream(new FileOutputStream(newFile));
stream.write(bytes);
stream.close();
List<BankStatementError> errorList = new ArrayList<BankStatementError>();
Excelsheetreader esr = new Excelsheetreader();
List<String> listaddSN = esr.GetCalculation(Long.parseLong(userId), filePath+""+file.getOriginalFilename());
newFile.delete();
for (int i = 0; i < listaddSN.size(); i++) {
String bank = listaddSN.get(i);
BankStatementError error = collectionsRepository.getErrorByBank(bank);
errorList.add(error);
}
ModelAndView modelAndView = new ModelAndView(UploadDocView.uploadsuccess);
modelAndView.addObject("errorList", errorList);
return modelAndView;
} catch (Exception e) {
ModelAndView modelAndView = new ModelAndView(UploadDocView.uploadexecption);
return modelAndView;
}
} else {
ModelAndView modelAndView = new ModelAndView(UploadDocView.uploadempty);
return modelAndView;
}
}
}
The problem is userId comes as null, which is getting for upload screen, I think. But not sure. Can anyone point me a right way in this?