I have a MarkdownService which does the following:
Opens a transaction
Fetches the Markdown entity from the repository
Markdown markdown = markdownRepository
.findById(markdownId)
.orElseThrow(EntityNotFoundException::new);
- Retrieves the original filename and together with the markdownId, creates a new filename according to the business rules.
String originalFilename = storageService.getOriginalFilename(file);
String filename = Markdown.normalizeMdPath(markdownId + "-" + originalFilename);
- Saves the file to disk at a certain path, /articles/markdowns
storageService.store(
file,
this.uploadMarkdownsPath,
filename
);
- Updates the entity with the filename only, not the full path
markdown.setMdPath(filename);
- Maps the Markdown entity to it's corresponding MarkdownDto using mapstruct
MarkdownDto dto = MarkdownMapper.INSTANCE.toMarkdownDto(markdown);
- Now, because the application is running locally, gets the full path of the uploaded Markdown file and updates the DTO, returning it to the controller.
String fullPath = ServletUriComponentsBuilder
.fromCurrentContextPath()
.path("/markdown/download/")
.path(dto.getMdPath())
.toUriString();
dto.setMdPath(fullPath);
return dto;
Now, the application will also run in production in AWS Fargate, under a certain domain name, and the actual markdowns will be stored in the cloud, not even in the file system.
My question is, can I somehow modify the Mapstruct mapper to set the full path of the markdown file at the DTO level, depending on a Spring environment variable? I would avoid doing this manual mapping on every controller method which returns a markdown DTO.
@Mapper
public interface MarkdownMapper {
MarkdownMapper INSTANCE = Mappers.getMapper(MarkdownMapper.class);
MarkdownDto toMarkdownDto(Markdown markdown);
}
Is there a better way to handle this? Maybe a totally different solution?
Here is the full code:
@Transactional
public MarkdownDto uploadMarkdownFile(Long markdownId, MultipartFile file) throws FileNotFoundException {
Markdown markdown = markdownRepository
.findById(markdownId)
.orElseThrow(EntityNotFoundException::new);
String originalFilename = storageService.getOriginalFilename(file);
String filename = Markdown.normalizeMdPath(markdownId + "-" + originalFilename);
storageService.store(
file,
this.uploadMarkdownsPath,
filename
);
markdown.setMdPath(filename);
MarkdownDto dto = MarkdownMapper.INSTANCE.toMarkdownDto(markdown);
String fullPath = ServletUriComponentsBuilder
.fromCurrentContextPath()
.path("/markdown/download/")
.path(dto.getMdPath())
.toUriString();
dto.setMdPath(fullPath);
return dto;
}
Thank you!
You could use inject a context into the mapper call and define an @AfterMapping.