照片因数据库中尚存在而无法上传,如何覆盖?

huangapple go评论128阅读模式
英文:

Photo doesn't upload because yet in db, how to overwrite?

问题

以下是您提供的代码翻译部分:

  1. 我是Java的新手,但我正在编写的Web应用的后端是用Java编写的,我的团队中没有人可以帮助我。
  2. 我的问题:在用户个人资料组件中,我有一个输入来编辑照片,但每次都返回错误消息。
  3. 似乎是因为文件已经存在于数据库中,所以照片从未更新。
  4. 我认为在后端可能有一些问题或缺失。
  5. 前端(angular
  6. -------------
  7. **expert-profile.component.html**
  8. ```lang-js
  9. <!-- [...] -->
  10. <!-----------------------------------------
  11. 图片配置文件
  12. -------------------------------------------->
  13. <div
  14. class="profileImg"
  15. [ngStyle]="{ 'background-image': 'url(' + photoUrl + ')' }"
  16. *ngIf="this.userInfos"
  17. >
  18. <!-- 上传或更改个人资料照片 -->
  19. <input
  20. type="file"
  21. accept="image/*"
  22. style="display: none;"
  23. #file
  24. (change)="changeProfilePhoto($event.target.files)"
  25. />
  26. <mat-icon
  27. class="editIcon"
  28. *ngIf="ownProfile"
  29. (click)="file.click()"
  30. matTooltip="仅支持.png或.jpg/.jpeg格式的图片,最小大小:KB,最大大小:KB"
  31. >
  32. 编辑
  33. </mat-icon>
  34. </div>
  35. <!-- [...] -->

expert-profile.component.ts

  1. // 导入...
  2. @Component({
  3. selector: 'app-expert-profile',
  4. templateUrl: './expert-profile.component.html',
  5. styleUrls: ['./expert-profile.component.less'],
  6. })
  7. export class ExpertProfileComponent implements OnInit {
  8. //[...]
  9. async changeProfilePhoto(file: FileList) {
  10. console.log(' async changeProfilePhoto....', file);
  11. console.log('---------------------请求------------------------------');
  12. this.fileService
  13. .uploadProfilePhoto(file[0], this.profileId)
  14. .subscribe((res) => {
  15. console.log('changeProfilePhoto (res)', res); // 测试 res= null
  16. if (res == null) {
  17. this.snackbar.open('错误(待处理):文件已上传', '', {
  18. duration: 2500,
  19. });
  20. } else {
  21. console.log('加载成功');
  22. location.reload();
  23. }
  24. });
  25. console.log('------------------------ 结束 ---------------------------');
  26. }
  27. }

console.log 返回--- >

  1. [...]
  2. ------------------------ 结束 ---------------------------
  3. changeProfilePhoto (res) null

浏览器返回 --- >
一个带有消息的 snackbar:

错误(待处理):文件已上传

照片已上传但未使用。

后端

FileUploadController.java

  1. /* uploadprofilephoto #1 */
  2. @PostMapping("/user/{userId}/avatar")
  3. public ResponseEntity<UserInfo> uploadProfilePhoto(@PathVariable UUID userId, @RequestParam MultipartFile avatar,
  4. HttpServletRequest request) throws IOException {
  5. System.out.println("............................................................................");
  6. System.out.println(" uploadprofilephoto #1 ");
  7. System.out.println("............................................................................");
  8. try {
  9. System.out.println("............................ 尝试 ......................................");
  10. UserInfo u = storageService.addUserAvatar(userId, avatar.getOriginalFilename(), avatar.getInputStream());
  11. URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{userId}").buildAndExpand("").toUri();
  12. return ResponseEntity.created(location).body(u);
  13. } catch(Exception e) {
  14. System.out.println("....................................... 捕获:(以下为 e) .....................................");
  15. System.out.println(e);
  16. System.out.println("............................................................................");
  17. return ResponseEntity.ok().body(null);
  18. }
  19. }

FileStorageService.java 中的 addUserAvatar()

  1. /* #uploadprofilephoto #2*/
  2. public UserInfo addUserAvatar(UUID userId, String filename, InputStream fileContent) {
  3. System.out.println("---------------------------------------------------- ");
  4. System.out.println(" #2 - 更改我的个人资料图片: "+filename);
  5. System.out.println("---------------------------------------------------- ");
  6. UserEntity user = userServiceActions.findById(userId);
  7. //如果userProfile中的fileId已经存在于filedatabase中,则在filedatabase + 目录中将其删除
  8. //#3
  9. try {
  10. this.delete(user.getImage());
  11. } catch(Exception e) {}
  12. //为新头像创建路径+目录以存储它
  13. Path directory = router.getOrCreatePathFromFilename(userId, filename, "avatar");
  14. Path location = fileSaver.store(filename, fileContent, directory);
  15. //为新文件请求
  16. var f = new FileRequest();
  17. f.filename = filename;
  18. f.projectId = Optional.of(userId);
  19. MediaType mediaType = MediaType.parseMediaType(getContentType(location));
  20. //使用唯一Id为此文件创建实体,并将其添加到文件数据库中
  21. //#4 + #5
  22. FileEntity fileEntity = fileServiceActions.add(UUID.randomUUID(), mediaType.getType(), mediaType.getSubtype(), f , "avatar");
  23. //使用新的Id更新user数据库中的imageId
  24. //#6
  25. user.setImage(fileEntity.getId());
  26. System.out.println("---------------------------------------------------- ");
  27. System.out.println(" #6 - 在用户数据库中保存新的imageId: "+user.getImage());
  28. System.out.println("---------------------------------------------------- ");
  29. userRepository.save(user);//如果以前已经上传过带有相同文件名的照片,似乎会阻塞
  30. //返回新数据并更新个人资料
  31. UserInfo userInfo = mapper.map(user, UserInfo.class);
  32. return userInfo;
  33. }

FileStorageService.java 中的 delete()(一切似乎都正常)

  1. /* #uploadprofilephoto #3*/
  2. public void delete(UUID id) throws ResourceNotFoundException {
  3. System.out.println("---------------------------------------------------- ");
  4. System.out.println(" #3 - 删除: "+id);
  5. System.out.println("---------------------------------------------------- ");
  6. FileEntity file = fileServiceActions.findById(id);
  7. Path directory = router.getOrCreatePathFromFilename(file.getProjectId(), file.getFilename(), file.getCategory());
  8. fileSaver.deleteFromDisk(directory, file.getFilename());
  9. fileServiceActions.delete(id);
  10. System.out.println("end delete ---------------------------------------------------- ");
  11. }

FileServiceActions.java 中的 add() 和 save()(问题可能出在 save)

  1. /**
  2. * #uploadprofilephoto #4
  3. * 允许为文件提供预生成的UUID。当我们想在将记录添加到数据库之前获得UUID时很有用。
  4. */
  5. public FileEntity add(UUID fileId, String type, String subtype, FileRequest req , String category) {
  6. FileEntity fileEntity;
  7. try {
  8. ProjectEntity proj = null;
  9. proj = projectServiceActions.findById(req.projectId.orElseThrow());
  10. fileEntity = toEntity(proj.getId(), req, type, subtype,
  11. <details>
  12. <summary>英文:</summary>
  13. I am new to Java, but the back of the web app I am coding is in Java and no one in my team can help me.
  14. My problem: In the user profile component, I have an input to edit the photo but every time it returns an error message.
  15. It seems it&#39;s because file already exists in the database, so the photo is never updated.
  16. I think there is something wrong or missing **in the back side** .
  17. FRONT (angular)
  18. -------------
  19. **expert-profile.component.html**
  20. ```lang-js
  21. &lt;!-- [...] --&gt;
  22. &lt;!-----------------------------------------
  23. img profile
  24. --------------------------------------------&gt;
  25. &lt;div
  26. class=&quot;profileImg&quot;
  27. [ngStyle]=&quot;{ &#39;background-image&#39;: &#39;url(&#39; + photoUrl + &#39;)&#39; }&quot;
  28. *ngIf=&quot;this.userInfos&quot;
  29. &gt;
  30. &lt;!-- upload or change profile photo --&gt;
  31. &lt;input
  32. type=&quot;file&quot;
  33. accept=&quot;image/*&quot;
  34. style=&quot;display: none;&quot;
  35. #file
  36. (change)=&quot;changeProfilePhoto($event.target.files)&quot;
  37. /&gt;
  38. &lt;mat-icon
  39. class=&quot;editIcon&quot;
  40. *ngIf=&quot;ownProfile&quot;
  41. (click)=&quot;file.click()&quot;
  42. matTooltip=&quot;Only .png or .jpg/.jpeg img with min-size: Ko and max-size: Ko&quot;
  43. &gt;
  44. edit
  45. &lt;/mat-icon&gt;
  46. &lt;/div&gt;
  47. &lt;!-- [...] --&gt;

expert-profile.component.ts

  1. // imports...
  2. @Component({
  3. selector: &#39;app-expert-profile&#39;,
  4. templateUrl: &#39;./expert-profile.component.html&#39;,
  5. styleUrls: [&#39;./expert-profile.component.less&#39;],
  6. })
  7. export class ExpertProfileComponent implements OnInit {
  8. //[...]
  9. async changeProfilePhoto(file: FileList) {
  10. console.log(&#39; async changeProfilePhoto....&#39;, file);
  11. console.log(&#39;---------------------REQUEST------------------------------&#39;);
  12. this.fileService
  13. .uploadProfilePhoto(file[0], this.profileId)
  14. .subscribe((res) =&gt; {
  15. console.log(&#39;changeProfilePhoto (res)&#39;, res); // test res= null
  16. if (res == null) {
  17. this.snackbar.open(&#39;Error (to handle) : File already uploaded&#39;, &#39;&#39;, {
  18. duration: 2500,
  19. });
  20. } else {
  21. console.log(&#39;loading ok&#39;);
  22. location.reload();
  23. }
  24. });
  25. console.log(&#39;------------------------ END ---------------------------&#39;);
  26. }
  27. }

console.log return--->

  1. [...]
  2. ------------------------ END ---------------------------
  3. changeProfilePhoto (res) null

browser return --->
a snackbar with message:
>Error (to handle) : File already uploaded

Photo is uploaded but not used.

Back End

FileUploadController.java

  1. /* uploadprofilephoto #1 */
  2. @PostMapping(&quot;/user/{userId}/avatar&quot;)
  3. public ResponseEntity&lt;UserInfo&gt; uploadProfilePhoto(@PathVariable UUID userId, @RequestParam MultipartFile avatar,
  4. HttpServletRequest request) throws IOException {
  5. System.out.println(&quot;............................................................................&quot;);
  6. System.out.println(&quot; uploadprofilephoto #1 &quot;);
  7. System.out.println(&quot;............................................................................&quot;);
  8. try {
  9. System.out.println(&quot;............................ TRY ......................................&quot;);
  10. UserInfo u = storageService.addUserAvatar(userId, avatar.getOriginalFilename(), avatar.getInputStream());
  11. URI location = ServletUriComponentsBuilder.fromCurrentRequest().path(&quot;/{userId}&quot;).buildAndExpand(&quot;&quot;).toUri();
  12. return ResponseEntity.created(location).body(u);
  13. } catch(Exception e) {
  14. System.out.println(&quot;....................................... CATCH: (e below) .....................................&quot;);
  15. System.out.println(e);
  16. System.out.println(&quot;............................................................................&quot;);
  17. return ResponseEntity.ok().body(null);
  18. }
  19. }

addUserAvatar() in FileStorageService.java

  1. /* #uploadprofilephoto #2*/
  2. public UserInfo addUserAvatar(UUID userId, String filename, InputStream fileContent) {
  3. System.out.println(&quot;---------------------------------------------------- &quot;);
  4. System.out.println(&quot; #2 - change my profile img by &quot;+filename);
  5. System.out.println(&quot;---------------------------------------------------- &quot;);
  6. UserEntity user = userServiceActions.findById(userId);
  7. //If fileId in userProfile is already present in filedatabase , it delete it in filedatabase + directory
  8. //#3
  9. try {
  10. this.delete(user.getImage());
  11. } catch(Exception e) {}
  12. //create path for a new avatar + directory to store it
  13. Path directory = router.getOrCreatePathFromFilename(userId, filename, &quot;avatar&quot;);
  14. Path location = fileSaver.store(filename, fileContent, directory);
  15. //request for a new file
  16. var f = new FileRequest();
  17. f.filename = filename;
  18. f.projectId = Optional.of(userId);
  19. MediaType mediaType = MediaType.parseMediaType(getContentType(location));
  20. //Create an entity for this file with a uniq Id, and add it in file db
  21. //#4 + #5
  22. FileEntity fileEntity = fileServiceActions.add(UUID.randomUUID(), mediaType.getType(), mediaType.getSubtype(), f , &quot;avatar&quot;);
  23. //update the imageId in user db with the new one
  24. //#6
  25. user.setImage(fileEntity.getId());
  26. System.out.println(&quot;---------------------------------------------------- &quot;);
  27. System.out.println(&quot; #6 - CrudRepository save in user the new imageId: &quot;+user.getImage());
  28. System.out.println(&quot;---------------------------------------------------- &quot;);
  29. userRepository.save(user);//seems to block if a photo was allready uploaded by past with the same filename
  30. //return the new data and update profile
  31. UserInfo userInfo = mapper.map(user, UserInfo.class);
  32. return userInfo;
  33. }

(see return of console print below)

delete() in FileStorageService.java (everything seems ok)

  1. /* #uploadprofilephoto #3*/
  2. public void delete(UUID id) throws ResourceNotFoundException {
  3. System.out.println(&quot;---------------------------------------------------- &quot;);
  4. System.out.println(&quot; #3 - delete &quot;+id);
  5. System.out.println(&quot;---------------------------------------------------- &quot;);
  6. FileEntity file = fileServiceActions.findById(id);
  7. Path directory = router.getOrCreatePathFromFilename(file.getProjectId(), file.getFilename(), file.getCategory());
  8. fileSaver.deleteFromDisk(directory, file.getFilename());
  9. fileServiceActions.delete(id);
  10. System.out.println(&quot;end delete ---------------------------------------------------- &quot;);
  11. }

add() & save() in FileServiceActions.java (Pb comes from the save according to me )

  1. /**
  2. * #uploadprofilephoto #4
  3. * Allows to give a pre-generated UUID to the file. Useful when we want to have the
  4. * UUID before adding a record to the database.
  5. */
  6. public FileEntity add(UUID fileId, String type, String subtype, FileRequest req , String category) {
  7. FileEntity fileEntity;
  8. try {
  9. ProjectEntity proj = null;
  10. proj = projectServiceActions.findById(req.projectId.orElseThrow());
  11. fileEntity = toEntity(proj.getId(), req, type, subtype, category);
  12. } catch(Exception e) {
  13. UserEntity user = null;
  14. user = userServiceActions.findById(req.projectId.orElseThrow());
  15. fileEntity = toEntity(user.getId(), req, type, subtype, category);
  16. }
  17. fileEntity.setId(fileId);
  18. System.out.println(&quot;----------------------------------------------------&quot;);
  19. System.out.println(&quot; #4 add this new file in file db &quot;);
  20. System.out.println(fileEntity);
  21. System.out.println(&quot;----------------------------------------------------&quot;);
  22. return save(fileEntity).orElseThrow();
  23. }
  24. [...]
  25. /**
  26. * #uploadprofilephoto #5
  27. * If any error happens, Optional.empty() is returned.
  28. */
  29. private Optional&lt;FileEntity&gt; save(FileEntity file) {
  30. System.out.println(&quot;---------------------------------------------------- &quot;);
  31. System.out.println(&quot; #5 - Save &quot;);
  32. System.out.println(&quot;---------------------------------------------------- &quot;);
  33. FileEntity savedUser = fileRepository.save(file);
  34. System.out.println(&quot;----&gt;#5 : savedUser: &quot;+savedUser);//pb is during the save, this consolePrint never be return when img allready exist in db
  35. return Optional.ofNullable(savedUser);
  36. }

save() in CrudRepository.class ('Pb' comes from this save according to me )

  1. @NoRepositoryBean
  2. public interface CrudRepository&lt;T, ID&gt; extends Repository&lt;T, ID&gt; {
  3. /**
  4. * Saves a given entity. Use the returned instance for further operations as the save operation might have changed the
  5. * entity instance completely.
  6. *
  7. * @param entity must not be {@literal null}.
  8. * @return the saved entity will never be {@literal null}.
  9. */
  10. &lt;S extends T&gt; S save(S entity);
  11. [...]
  12. }

Terminal when it fails:

(look the 2)
screenshot_1/2
screenshot_1/2

Terminal when it works:

screenshot

Somebody have an idea How to resolve my problem?

I think the solution is
either:

  • if fileName allready exist , just change the id by the newOne (or catch its id and use it for the imageId in user db)
    or:
    -if fileName allready exist , delete it and save the newOne

What do you think about this solution?
How to code it in Java?

答案1

得分: 0

我修复了我的问题。
根据规格的更新,我只在数据库和目录中为每个用户保留一张图片/头像。

因此,我已将删除操作(delete(user.imageId))更改为删除所有与用户ID和类别('avatar')匹配的项。

英文:

I fixed my pb.
According to the update of the specifications, I keep in db and directory only one img/avatar for each user.

So I have changed the delete(user.imageId) by deleteAllByUserIdAndCategory(user.id, 'avatar').

huangapple
  • 本文由 发表于 2020年8月27日 23:16:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/63619117.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定