Как хранить изображение? Насколько я знаю, их можно запихивать прямо в PostgreSQL, но я склоняюсь в сторону того, что изображения надо сохранять в ресурсы, а в бд хранить только ссылки.
@Entity
@Data
@NoArgsConstructor
@Table(name = "attachments")
public class Attachment {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long attachId;
private String attachTitle;
@Column(nullable = false, updatable = false)
private LocalDate uploadDate;
private String extension;
private String downloadLink;
}
@Repository
public interface AttachmentRepository extends JpaRepository<Attachment, Long> {}
public interface AttachmentService {
/**
* Загрузить новый файл
*
* @param file
* @param user
* @throws IOException
*/
Attachment addAttachment(MultipartFile file, User user) throws IOException;
/**
* Найти Вложение по его ID
*
* @param attachId
* @return
*/
Attachment findAttachById(Long attachId);
/**
* Скачать файл
*
* @param uploadYear
* @param fileName
* @return
* @throws MalformedURLException
*/
Resource loadFileAsResource(String uploadYear, String fileName) throws MalformedURLException;
}
@Service
@RequiredArgsConstructor
public class AttachmentServiceImpl implements AttachmentService {
private final AttachmentRepository attachmentRepository;
private final AppProperties appProperties;
private final FileTools fileTools;
/**
* Загрузить новый файл
*
* @param file
* @param user
* @throws IOException
*/
@Override
public Attachment addAttachment(MultipartFile file, User user) throws IOException {
// Создаем директорию если ее не существует
File uploadDir = new File(appProperties.getUploadPath());
// Если директория uploads не существует, то создаем ее
if (!uploadDir.exists()) {
uploadDir.mkdirs();
}
String curDate = LocalDateTime.now().toString();
// Создаем уникальное название для файла и загружаем файл
String fileName =
"attach_" + curDate + "_" + file.getOriginalFilename().toLowerCase().replaceAll(" ", "-");
file.transferTo(new File(uploadDir + "/" + fileName));
Attachment attachment = Attachment.builder()
.attachTitle(fileName)
.uploadDate(LocalDate.now())
.extension(fileTools.getFileExtension(file.getOriginalFilename()))
.downloadLink("/attachments/get/" + Year.now() + "/" + fileName)
.build();
attachmentRepository.save(attachment);
return attachment;
}
/**
* Найти Вложение по его ID
*
* @param attachId
* @return
*/
@Override
public Attachment findAttachById(Long attachId) {
return attachmentRepository
.findById(attachId)
.orElseThrow(() -> new AttachmentNotFoundException("Attachment not found!"));
}
/**
* Скачать файл
*
* @param fileName
* @return
* @throws MalformedURLException
*/
@Override
public Resource loadFileAsResource( String fileName)
throws MalformedURLException {
Path fileStorageLocation =
Paths.get(appProperties.getUploadPath()).toAbsolutePath().normalize();
Path filePath = fileStorageLocation.resolve(fileName).normalize();
return new UrlResource(filePath.toUri());
}
}
@Controller
@RequiredArgsConstructor
@RequestMapping("/attachments")
public class AttachmentController {
private final AttachmentService attachmentService;
private final UserService userService;
/**
* Загрузить новое вложение
*
* @param file
* @return
* @throws IOException
*/
@PostMapping(value = "/add", produces = "application/json")
@ResponseBody
public ResponseEntity<Map<String, String>> uploadAttachment(
@RequestPart(value = "file") MultipartFile file)
throws IOException {
Attachment attachment = attachmentService.addAttachment(file);
Map<String, String> attachmentStatus = new HashMap<>();
attachmentStatus.put("status", "ok");
attachmentStatus.put("attachId", attachment.getAttachId().toString());
return ResponseEntity.ok(attachmentStatus);
}
/**
* Получить ссылку на скачивание загруженного файла
*
* @param filename
* @param request
* @return
* @throws IOException
*/
@GetMapping("/get/{filename:.+}")
public ResponseEntity<Resource> serveFile(
@PathVariable String filename, HttpServletRequest request)
throws IOException {
Resource resource = attachmentService.loadFileAsResource(filename);
String contentType;
contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
if (contentType == null) {
contentType = "application/octet-stream";
}
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(contentType))
.header(
HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
}
}
@Configuration
@ConfigurationProperties(prefix = "custom")
public class AppProperties {
// названия полей должны соответствовать названиям из properties.
private String baseUrl;
private String uploadPath;
// тут геттеры
}
custom.base_url=http://localhost:8080
custom.upload_path=/home/example.com/uploads
@ConfigurationProperties(prefix = "custom")
custom.base_url
custom является префиксом.bin/consol debug:route <route>
, где <route>
— путь от path, можно через grep искать: bin/console d:r | grep <route_part>
$ bin/console d:r home
+--------------+----------------------------------------------------------------+
| Property | Value |
+--------------+----------------------------------------------------------------+
| Route Name | home |
| Path | /{_locale} |
| Path Regex | {^/(?P<_locale>en|ru)?$}sDu |
| Requirements | _locale: en|ru |
| Class | Symfony\Component\Routing\Route |
| Defaults | _controller: \App\Controller\HomeController::index() |
| | _locale: en |
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
| | utf8: true |
+--------------+----------------------------------------------------------------+
bin/consol debug:route
название вашего роута (справа пути с выражениями, слева названия роута — его и подставить в первую команду нужно):users.show ANY ANY ANY /admin/users/{id}
app_login ANY ANY ANY /login
app_logout GET ANY ANY /logout
oauth.fake ANY ANY ANY /fake_login
auth.signup ANY ANY ANY /signup
if ($form->isSubmitted() && $form->isValid())
и уже внедряете свою капчуПроблема что настораживает что на Yii особо крупного ничего не писали
многие недолюбливают из за черезмерной сложности и.т.д.
Виртуальня машина java это тоже интерпретатор по сути