th:href="@{findOne/(id=${tour.id})}"
Converter<S, T>
или же либу MapStruct, ModelMapper и др.BeanUtils.copyProperties()
например, для обновления сущности.@ResponseBody
public Tour findOne(Integer id) {
return tourRepository.findById(id).get();
}
get()
лучше использовать например, orElseThrow()
и выбросить исключение, которое впоследствиее можно при помощи ExceptionHandler обработать и вернуть корректный http ответ. Например, когда объект не найден (404) @Autowired
private TourRepository tourRepository;
@PostMapping("/save")
public String save(@ModelAttribute(name = "tour") Tour tour) {
tourRepository.save(tour);
return "redirect:/";
}
@PostMapping("/admin/saveTour")
public String saveTourInModal(@ModelAttribute(name = "tour") Tour tour) {
tourRepository.save(tour);
return "redirect:/admin/tourList";
}
Само модальное окно вызывается и заполняется данными объекта. После нажатия на кнопку сохранения, у меня стало выводить исключение org.hibernate.exception.ConstraintViolationException: could not execute statement, и что поля бд title и description не могут быть null.
Hibernate: update tour set description=?, end_time=?, image=?, price=?, start_time=?, title=? where code=?
Hibernate: insert into tour (description, end_time, image, price, start_time, title) values (?, ?, ?, ?, ?, ?)
public String saveUser(@ModelAttribute("currentUser") User user,Model model, Principal principal) {
User tempUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
tempUser.setEmail(user.getEmail());
tempUser.setUsername(user.getUsername());
userService.save(tempUser);
Set-Cookie: tph_uuid=<token>; expires=Wed, 08 Feb 2023 05:42:55 GMT; path=/; secure; HttpOnly
Как тогда Паша понимает, что я - это я?Устанавливает тебе печеньки, потом читает их.
Проблема заключается в том, что ни в локальном хранилище, ни в сессиях, ни в куках нет вообще никаких данных.Не совсем верно. Во вкладке "Приложение" их нет, а вот во вкладке "Сеть" по клике на запрос - есть.
Но потом, когда я загружу проект на сервер, то там же другая файловая система, другие директории и т.д. - как с этим быть?
upload.path
будет /home/Desktop/uploads
, а для prod профиля будет uploads/
и т.д.Во-вторых - а как быть с безопасностью? Как-то же надо фильтровать то, что мне загружают? А то скрипт какой-нибудь загрузят или ещё что-то. Как это вообще отслеживать?
image/*
и т.д.Как отслеживать оставшееся место на диске?
Но потом, когда я загружу проект на сервер, то там же другая файловая система, другие директории и т.д.
как быть с безопасностью?не давать пользователю загружать что попало. То что пользователь загрузил - никогда не запускать.
Как отслеживать оставшееся место на диске?
Как хранить изображение? Насколько я знаю, их можно запихивать прямо в 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);
}
}