1

I have tried a rest api without any View with mongodb. My application is working fine with Spring boot embedded server with no error. With standalone tomcat application is running without error but cannot access @RestController mapped url. It shows 404 page not found. It is not creating that url but other url works fine.

Here is config

FileStorageProperties.java

@Component public class FileStorageProperties { private static String baseDir = "E://temp//FileManager//"; private String uploadDir = ""; public String getUploadDir() { return baseDir + uploadDir; } public void setUploadDir(String uploadDir) { this.uploadDir = baseDir + uploadDir; } } 

MediaTypeUtils.java

public class MediaTypeUtils { // abc.zip // abc.pdf,.. public static MediaType getMediaTypeForFileName(ServletContext servletContext, String fileName) { // application/pdf // application/xml // image/gif, ... String mineType = servletContext.getMimeType(fileName); try { MediaType mediaType = MediaType.parseMediaType(mineType); return mediaType; } catch (Exception e) { return MediaType.APPLICATION_OCTET_STREAM; } } } 

Here is model

Avatar.java:

@Document @Component public class Avatar { @Id // @Indexed(unique = true) private String id; private String originalName; @Indexed(unique = true) private String generatedName; private String size; @DBRef private User user; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getOriginalName() { return originalName; } public void setOriginalName(String originalName) { this.originalName = originalName; } public String getGeneratedName() { return generatedName; } public void setGeneratedName(String generatedName) { this.generatedName = generatedName; } public String getSize() { return size; } public void setSize(String size) { this.size = size; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String toString() { return "Avatar [id=" + id + ", originalName=" + originalName + ", generatedName=" + generatedName + ", size=" + size + ", user=" + user + "]"; } } 

UploadFileResponse.java

public class UploadFileResponse { private String fileName; private String fileType; private long size; public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public String getFileType() { return fileType; } public void setFileType(String fileType) { this.fileType = fileType; } public long getSize() { return size; } public void setSize(long size) { this.size = size; } public UploadFileResponse(String fileName, String fileType, long size) { this.fileName = fileName; this.fileType = fileType; this.size = size; } } 

FileStorageException.java

public class FileStorageException extends RuntimeException { /** * */ private static final long serialVersionUID = -2482390550398268830L; public FileStorageException(String message) { super(message); } public FileStorageException(String message, Throwable cause) { super(message, cause); } } 

MyFileNotFoundException.java

@ResponseStatus(HttpStatus.NOT_FOUND) public class MyFileNotFoundException extends RuntimeException { /** * */ private static final long serialVersionUID = -7680896574598153059L; public MyFileNotFoundException(String message) { super(message); } public MyFileNotFoundException(String message, Throwable cause) { super(message, cause); } } 

Now repository:

AvatarRepository.java

public interface AvatarRepository extends MongoRepository<Avatar, String>{ public Avatar findAvatarByGeneratedName(String generatedName); public Avatar findAvatarByUser(User user); } 

AvatarRepositopryImpl.java - There are some overrided MongoRepository methods which are ignored on the following code as those are not used at all.

@Repository public class AvatarRepositopryImpl implements AvatarRepository { @Autowired MongoTemplate mongoTemplate; private static final String COLLECTION_NAME = "avatar"; @Override public <S extends Avatar> List<S> saveAll(Iterable<S> entities) { // TODO Auto-generated method stub return null; } @Override public List<Avatar> findAll() { return mongoTemplate.findAll(Avatar.class, COLLECTION_NAME); } @Override public <S extends Avatar> S save(S entity) { return mongoTemplate.save(entity); } @Override public void deleteById(String id) { mongoTemplate.remove(id); } @Override public void delete(Avatar entity) { mongoTemplate.remove(entity); } @Override public Avatar findAvatarByGeneratedName(String generatedName) { Query query = new Query(); query.addCriteria(Criteria.where("generatedName").is(generatedName)); return (Avatar) mongoTemplate.findOne(query, Avatar.class); } @Override public Avatar findAvatarByUser(User user) { // System.out.println(user); Query query = new Query(); query.addCriteria(Criteria.where("user").is(user)); return (Avatar) mongoTemplate.find(query, Avatar.class); } } 

Here is my service:

AvatarService.java

@Service public class AvatarService { @Autowired private Avatar avatar; // // @Autowired // private FileStorageService fileStorageService; @Autowired AvatarRepository avatarRepository; /** * @param fileStorageService * @param avatarRepository */ public Avatar findAvatarByGeneratedName(String generatedName) { return avatarRepository.findAvatarByGeneratedName(generatedName); } public Avatar findAvatarByUser(User user) { System.out.println(user); return avatarRepository.findAvatarByUser(user); } public Avatar saveAvatar(User user,String fileOriginalName, String fileNameToSave, String fileSize) { avatar.setId(UUID.randomUUID().toString()); avatar.setOriginalName(fileOriginalName); avatar.setGeneratedName(fileNameToSave); avatar.setSize(fileSize); avatar.setUser(user); return avatarRepository.save(avatar); } public void deleteAvatarByGeneratedName(String generatedName, Avatar avatar) { avatar = findAvatarByGeneratedName(generatedName); avatarRepository.deleteById(avatar.getId()); } 

AvatarManager.java

public class AvatarManager { AvatarService avatarService; @Autowired Avatar avatar; public AvatarManager(AvatarService avatarService) { this.avatarService = avatarService; } public String saveAvatar(User user, MultipartFile file) { deleteAvatarByUser(user); String[] ext = file.getOriginalFilename().split(Pattern.quote(".")); String generatedName = new UUIDGenerator().generateId(avatar).toString() + "." + ext[ext.length - 1]; avatarService.saveAvatar(user, file.getOriginalFilename(), generatedName, file.getSize() + ""); new FileStorageService(new FileStorageProperties()).uploadFile(file, generatedName); new UploadFileResponse(generatedName, file.getContentType(), file.getSize()); return generatedName; } public void deleteAvatar(String generatedName) { Avatar avatar = avatarService.findAvatarByGeneratedName(generatedName); if (avatar != null) { new FileStorageService(new FileStorageProperties()).deleteFile(generatedName); avatarService.deleteAvatarByGeneratedName(generatedName, avatar); } } public void deleteAvatarByUser(User user) { // System.out.println(user); avatar = avatarService.findAvatarByUser(user); // System.out.println(avatar.getGeneratedName()); if (avatar != null) { deleteAvatar(avatar.getGeneratedName()); } } public ResponseEntity<Resource> downloadAvatar(String avatarGeneratedName, HttpServletRequest request) { // System.out.println(request); return new FileStorageService(new FileStorageProperties()).downloadFile(avatarGeneratedName, request); } } 

Now Controller. I am giving two mapping. The first one is not involved with file manager. It works on both server. The another one is working on spring boot embedded server but not on standalone tomcat. It also is not showing any error or create any url.

Here is the Controller.java;

@CrossOrigin(origins = { "*" }) @RestController public class UserController { @Autowired EmployeeService employeeService; @Autowired UserService userService; @Autowired AvatarService avatarService; @Autowired BCryptPasswordEncoder passwordEncoder; //It works on both server @RequestMapping(value = "/login", method = RequestMethod.POST) public String loginEmployee(@RequestParam Map<String, String> data) { return new EmployeeManager(employeeService, userService) .validateUserLogin(data.get("0").toString(), data.get("1"), passwordEncoder).toString(); } //It doesn't work with standalone server @RequestMapping(value = "/edit-employee-profile", method = RequestMethod.POST) public void editProfileEmployee(@RequestParam(value = "avatar", required = false) MultipartFile file, @RequestParam(value = "user") String data) { JSONParser jp = new JSONParser(data); System.out.println(jp); LinkedHashMap<String, Object> userInfo; try { userInfo = jp.parseObject(); User user = userService.findUserByEmail(userInfo.get("email").toString()); System.out.println(user); user.setAvatarExistance(true); userService.updateUser(user); // Employee employee = employeeService.findEmployeeByUser(user); System.out.println(data); new EmployeeManager(employeeService, userService).employeeProfileEdit(data); if (file != null) { System.out.println(file); new AvatarManager(avatarService).saveAvatar(user, file); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } // return ""; } 
8
  • It may sound obvious but curl/postman request that leads to 404 could be useful too. Commented Nov 21, 2019 at 13:37
  • Do you have any other configuration classes for spring? Commented Nov 21, 2019 at 13:39
  • Sorry for wrong controller. Now I have edited the question. The project is on given link. drive.google.com/open?id=1PjGVp-hu2lFGjThy4WTrSV47yIWbdp6C Commented Nov 23, 2019 at 7:34
  • Are you uploading the file content as request param (part of the URL)? Commented Nov 23, 2019 at 10:24
  • Thanks guys for participating. I figured out the problem with exception handling in controller. If I do exception handling on controller it is not creating that url mapping else ok. Commented Nov 23, 2019 at 10:33

1 Answer 1

0

Post the file as request body (rather than as URL parameter and @RequestParam) to not excced the safe maximum URL length:

@RequestMapping(value = "/uploadFile", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) public void uploadFile(ModelMap m, MultipartHttpServletRequest request) { MultiValueMap<String, MultipartFile> multiFileMap = request.getMultiFileMap(); List<MultipartFile> files = multiFileMap.isEmpty() ? null : multiFileMap.values().iterator().next(); MultipartFile file = files != null && !files.isEmpty() ? files.get(0) : null; // ... } 
Sign up to request clarification or add additional context in comments.

2 Comments

I think I used post there. You may revise again. :) BTW thanks for reminder. Should I avoid @RequestParam for MultipartFile file.
You are right, of course, thanks! See revised answer

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.