전체적인 패키지 및 파일 생성
1. controller
1) FolderController
package com.sparta.myselectshop.scheduler;
import com.sparta.myselectshop.entity.Product;
import com.sparta.myselectshop.naver.dto.ItemDto;
import com.sparta.myselectshop.naver.service.NaverApiService;
import com.sparta.myselectshop.repository.ProductRepository;
import com.sparta.myselectshop.service.ProductService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
@RequiredArgsConstructor
public class Scheduler {
private final NaverApiService naverApiService;
private final ProductService productService;
private final ProductRepository productRepository;
@Scheduled(cron = "0 0 1 * * *")
public void updatePrice() throws InterruptedException {
log.info("가격 업데이트 실행");
List<Product> productList = productRepository.findAll();
for (Product product : productList) {
TimeUnit.SECONDS.sleep(1);
String title = product.getTitle();
List<ItemDto> itemDtoList = naverApiService.searchItems(title);
ItemDto itemDto = itemDtoList.get(0);
Long id = product.getId();
productService.updateBySearch(id, itemDto);
}
}
}
2) ProductController
package com.sparta.myselectshop.controller;
import com.sparta.myselectshop.dto.ProductMypriceRequestDto;
import com.sparta.myselectshop.dto.ProductRequestDto;
import com.sparta.myselectshop.dto.ProductResponseDto;
import com.sparta.myselectshop.entity.Product;
import com.sparta.myselectshop.service.ProductService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class ProductController {
private final ProductService productService;
@PostMapping("/products")
public ProductResponseDto createProduct(@RequestBody ProductRequestDto requestDto, HttpServletRequest request) {
return productService.createProduct(requestDto, request);
}
@GetMapping("/products")
public Page<Product> getProducts(
@RequestParam("page") int page,
@RequestParam("size") int size,
@RequestParam("sortBy") String sortBy,
@RequestParam("isAsc") boolean isAsc,
HttpServletRequest request
) {
return productService.getProducts(request, page-1, size, sortBy, isAsc);
}
@PutMapping("/products/{id}")
public Long updateProduct(@PathVariable Long id, @RequestBody ProductMypriceRequestDto requestDto, HttpServletRequest request) {
return productService.updateProduct(id, requestDto, request);
}
@PostMapping("/products/{productId}/folder")
public Long addFolder(
@PathVariable Long productId,
@RequestParam Long folderId,
HttpServletRequest request
) {
Product product = productService.addFolder(productId, folderId, request);
return product.getId();
}
}
3) ShopController
package com.sparta.myselectshop.controller;
import com.sparta.myselectshop.entity.User;
import com.sparta.myselectshop.jwt.JwtUtil;
import com.sparta.myselectshop.repository.UserRepository;
import com.sparta.myselectshop.service.FolderService;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequiredArgsConstructor
@RequestMapping("/api")
public class ShopController {
private final FolderService folderService;
private final JwtUtil jwtUtil;
private final UserRepository userRepository;
@GetMapping("/shop")
public ModelAndView shop() {
return new ModelAndView("index");
}
@GetMapping("/user-folder")
public String getUserInfo(Model model, HttpServletRequest request) {
model.addAttribute("folders", folderService.getFolders(request));
return "index :: #fragment";
}
@GetMapping("/user-info")
@ResponseBody
public String getUserName(HttpServletRequest request) {
String token = jwtUtil.resolveToken(request);
Claims claims;
if (token != null) {
if (jwtUtil.validateToken(token)) {
claims = jwtUtil.getUserInfoFromToken(token);
} else {
throw new IllegalArgumentException("Token Error");
}
User user = userRepository.findByUsername(claims.getSubject()).orElseThrow(
() -> new IllegalArgumentException("사용자가 존재하지 않습니다.")
);
return user.getUsername();
}else {
return "fail";
}
}
}
4) UserController
package com.sparta.myselectshop.controller;
import com.sparta.myselectshop.dto.LoginRequestDto;
import com.sparta.myselectshop.dto.SignupRequestDto;
import com.sparta.myselectshop.service.UserService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequiredArgsConstructor
@RequestMapping("/api/user")
public class UserController {
private final UserService userService;
@GetMapping("/signup")
public ModelAndView signupPage() {
return new ModelAndView("signup");
}
@GetMapping("/login")
public ModelAndView loginPage() {
return new ModelAndView("login");
}
@PostMapping("/signup")
public String signup(SignupRequestDto signupRequestDto) {
userService.signup(signupRequestDto);
return "redirect:/api/user/login";
}
@ResponseBody
@PostMapping("/login")
public String login(@RequestBody LoginRequestDto loginRequestDto, HttpServletResponse response) {
userService.login(loginRequestDto, response);
return "success";
}
}
2. dto
1) FolderRequestDto
package com.sparta.myselectshop.dto;
import lombok.Getter;
import java.util.List;
@Getter
public class FolderRequestDto {
List<String> folderNames;
}
2) LoginRequestDto
package com.sparta.myselectshop.dto;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
public class LoginRequestDto {
private String username;
private String password;
}
3) ProductMypriceRequestDto
package com.sparta.myselectshop.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ProductMypriceRequestDto {
private int myprice;
}
4) ProductRequestDto
package com.sparta.myselectshop.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ProductRequestDto {
private String title;
private String image;
private String link;
private int lprice;
}
5) ProductResponseDto
package com.sparta.myselectshop.dto;
import com.sparta.myselectshop.entity.Product;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
public class ProductResponseDto {
private Long id;
private String title;
private String link;
private String image;
private int lprice;
private int myprice;
public ProductResponseDto(Product product) {
this.id = product.getId();
this.title = product.getTitle();
this.link = product.getLink();
this.image = product.getImage();
this.lprice = product.getLprice();
this.myprice = product.getMyprice();
}
}
6) SignupRequestDto
package com.sparta.myselectshop.dto;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
public class SignupRequestDto {
private String username;
private String password;
private String email;
private boolean admin = false;
private String adminToken = "";
}
3. entity
1) Folder
package com.sparta.myselectshop.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@Entity
@NoArgsConstructor
public class Folder {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
private String name;
@ManyToOne
@JoinColumn(name = "USER_ID", nullable = false)
private User user;
public Folder(String name, User user) {
this.name = name;
this.user = user;
}
}
2) Product
package com.sparta.myselectshop.entity;
import com.sparta.myselectshop.dto.ProductMypriceRequestDto;
import com.sparta.myselectshop.dto.ProductRequestDto;
import com.sparta.myselectshop.naver.dto.ItemDto;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Getter
@Setter
@Entity
@NoArgsConstructor
public class Product extends Timestamped{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column(nullable = false)
private String image;
@Column(nullable = false)
private String link;
@Column(nullable = false)
private int lprice;
@Column(nullable = false)
private int myprice;
@Column(nullable = false)
private Long userId;
@ManyToMany
private List<Folder> folderList = new ArrayList<>();
public Product(ProductRequestDto requestDto, Long userId) {
this.title = requestDto.getTitle();
this.image = requestDto.getImage();
this.link = requestDto.getLink();
this.lprice = requestDto.getLprice();
this.myprice = 0;
this.userId = userId;
}
public void update(ProductMypriceRequestDto requestDto) {
this.myprice = requestDto.getMyprice();
}
public void updateByItemDto(ItemDto itemDto) {
this.lprice = itemDto.getLprice();
}
public void addFolder(Folder folder) {
this.folderList.add(folder);
}
}
3) Timestamped
package com.sparta.myselectshop.entity;
import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.time.LocalDateTime;
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class Timestamped {
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdAt;
@LastModifiedDate
@Column
private LocalDateTime modifiedAt;
}
4) User
package com.sparta.myselectshop.entity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Getter
@NoArgsConstructor
@Entity(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
private String password;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false)
@Enumerated(value = EnumType.STRING)
private UserRoleEnum role;
@OneToMany
List<Folder> folders = new ArrayList<>();
public User(String username, String password, String email, UserRoleEnum role) {
this.username = username;
this.password = password;
this.email = email;
this.role = role;
}
}
5) UserRoleEnum
package com.sparta.myselectshop.entity;
public enum UserRoleEnum {
USER,
ADMIN
}
4. jwt
jwtUtil
package com.sparta.myselectshop.jwt;
import com.sparta.myselectshop.entity.UserRoleEnum;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SecurityException;
import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.security.Key;
import java.util.Base64;
import java.util.Date;
@Slf4j
@Component
@RequiredArgsConstructor
public class JwtUtil {
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String AUTHORIZATION_KEY = "auth";
private static final String BEARER_PREFIX = "Bearer ";
private static final long TOKEN_TIME = 60 * 60 * 1000L;
@Value("${jwt.secret.key}")
private String secretKey;
private Key key;
private final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
@PostConstruct
public void init() {
byte[] bytes = Base64.getDecoder().decode(secretKey);
key = Keys.hmacShaKeyFor(bytes);
}
public String resolveToken(HttpServletRequest request) {
String bearerToken = request.getHeader(AUTHORIZATION_HEADER);
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(BEARER_PREFIX)) {
return bearerToken.substring(7);
}
return null;
}
public String createToken(String username, UserRoleEnum role) {
Date date = new Date();
return BEARER_PREFIX +
Jwts.builder()
.setSubject(username)
.claim(AUTHORIZATION_KEY, role)
.setExpiration(new Date(date.getTime() + TOKEN_TIME))
.setIssuedAt(date)
.signWith(key, signatureAlgorithm)
.compact();
}
public boolean validateToken(String token) {
try {
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);
return true;
} catch (SecurityException | MalformedJwtException e) {
log.info("Invalid JWT signature, 유효하지 않는 JWT 서명 입니다.");
} catch (ExpiredJwtException e) {
log.info("Expired JWT token, 만료된 JWT token 입니다.");
} catch (UnsupportedJwtException e) {
log.info("Unsupported JWT token, 지원되지 않는 JWT 토큰 입니다.");
} catch (IllegalArgumentException e) {
log.info("JWT claims is empty, 잘못된 JWT 토큰 입니다.");
}
return false;
}
public Claims getUserInfoFromToken(String token) {
return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
}
}
5. repository
1) FolderRepository
package com.sparta.myselectshop.repository;
import com.sparta.myselectshop.entity.Folder;
import com.sparta.myselectshop.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface FolderRepository extends JpaRepository<Folder, Long> {
List<Folder> findAllByUser(User user);
List<Folder> findAllByUserAndNameIn(User user, List<String> names);
}
2) ProductRepository
package com.sparta.myselectshop.repository;
import com.sparta.myselectshop.entity.Product;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface ProductRepository extends JpaRepository<Product, Long> {
Page<Product> findAllByUserId(Long userId, Pageable pageable);
Optional<Product> findByIdAndUserId(Long id, Long userId);
Page<Product> findAll(Pageable pageable);
Page<Product> findAllByUserIdAndFolderList_Id(Long userId, Long folderId, Pageable pageable);
Optional<Product> findByIdAndFolderList_Id(Long productId, Long folderId);
}
3) UserRepository
package com.sparta.myselectshop.repository;
import com.sparta.myselectshop.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
}
6. scheduler
Scheduler
package com.sparta.myselectshop.scheduler;
import com.sparta.myselectshop.entity.Product;
import com.sparta.myselectshop.naver.dto.ItemDto;
import com.sparta.myselectshop.naver.service.NaverApiService;
import com.sparta.myselectshop.repository.ProductRepository;
import com.sparta.myselectshop.service.ProductService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
@RequiredArgsConstructor
public class Scheduler {
private final NaverApiService naverApiService;
private final ProductService productService;
private final ProductRepository productRepository;
@Scheduled(cron = "0 0 1 * * *")
public void updatePrice() throws InterruptedException {
log.info("가격 업데이트 실행");
List<Product> productList = productRepository.findAll();
for (Product product : productList) {
TimeUnit.SECONDS.sleep(1);
String title = product.getTitle();
List<ItemDto> itemDtoList = naverApiService.searchItems(title);
ItemDto itemDto = itemDtoList.get(0);
Long id = product.getId();
productService.updateBySearch(id, itemDto);
}
}
}
7. service
1) FolderService
package com.sparta.myselectshop.service;
import com.sparta.myselectshop.entity.Folder;
import com.sparta.myselectshop.entity.Product;
import com.sparta.myselectshop.entity.User;
import com.sparta.myselectshop.jwt.JwtUtil;
import com.sparta.myselectshop.repository.FolderRepository;
import com.sparta.myselectshop.repository.ProductRepository;
import com.sparta.myselectshop.repository.UserRepository;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
@Service
@RequiredArgsConstructor
public class FolderService {
private final ProductRepository productRepository;
private final FolderRepository folderRepository;
private final UserRepository userRepository;
private final JwtUtil jwtUtil;
@Transactional
public List<Folder> addFolders(List<String> folderNames, HttpServletRequest request) {
String token = jwtUtil.resolveToken(request);
Claims claims;
if (token != null) {
if (jwtUtil.validateToken(token)) {
claims = jwtUtil.getUserInfoFromToken(token);
} else {
throw new IllegalArgumentException("Token Error");
}
User user = userRepository.findByUsername(claims.getSubject()).orElseThrow(
() -> new IllegalArgumentException("사용자가 존재하지 않습니다.")
);
List<Folder> existFolderList = folderRepository.findAllByUserAndNameIn(user, folderNames);
List<Folder> folderList = new ArrayList<>();
for (String folderName : folderNames) {
if (!isExistFolderName(folderName, existFolderList)) {
Folder folder = new Folder(folderName, user);
folderList.add(folder);
}
}
return folderRepository.saveAll(folderList);
} else {
return null;
}
}
@Transactional(readOnly = true)
public List<Folder> getFolders(HttpServletRequest request) {
String token = jwtUtil.resolveToken(request);
Claims claims;
if (token != null) {
if (jwtUtil.validateToken(token)) {
claims = jwtUtil.getUserInfoFromToken(token);
} else {
throw new IllegalArgumentException("Token Error");
}
User user = userRepository.findByUsername(claims.getSubject()).orElseThrow(
() -> new IllegalArgumentException("사용자가 존재하지 않습니다.")
);
return folderRepository.findAllByUser(user);
} else {
return null;
}
}
@Transactional(readOnly = true)
public Page<Product> getProductsInFolder(Long folderId, int page, int size, String sortBy, boolean isAsc, HttpServletRequest request) {
Sort.Direction direction = isAsc ? Sort.Direction.ASC : Sort.Direction.DESC;
Sort sort = Sort.by(direction, sortBy);
Pageable pageable = PageRequest.of(page, size, sort);
String token = jwtUtil.resolveToken(request);
Claims claims;
if (token != null) {
if (jwtUtil.validateToken(token)) {
claims = jwtUtil.getUserInfoFromToken(token);
} else {
throw new IllegalArgumentException("Token Error");
}
User user = userRepository.findByUsername(claims.getSubject()).orElseThrow(
() -> new IllegalArgumentException("사용자가 존재하지 않습니다.")
);
System.out.println("FolderService.getProductsInFolder");
System.out.println("folderId = " + folderId);
System.out.println("user = " + user.getId());
return productRepository.findAllByUserIdAndFolderList_Id(user.getId(), folderId, pageable);
} else {
return null;
}
}
private boolean isExistFolderName(String folderName, List<Folder> existFolderList) {
for (Folder existFolder : existFolderList) {
if (existFolder.getName().equals(folderName)) {
return true;
}
}
return false;
}
}
2) ProductService
package com.sparta.myselectshop.service;
import com.sparta.myselectshop.dto.ProductMypriceRequestDto;
import com.sparta.myselectshop.dto.ProductRequestDto;
import com.sparta.myselectshop.dto.ProductResponseDto;
import com.sparta.myselectshop.entity.Folder;
import com.sparta.myselectshop.entity.Product;
import com.sparta.myselectshop.entity.User;
import com.sparta.myselectshop.entity.UserRoleEnum;
import com.sparta.myselectshop.jwt.JwtUtil;
import com.sparta.myselectshop.naver.dto.ItemDto;
import com.sparta.myselectshop.repository.FolderRepository;
import com.sparta.myselectshop.repository.ProductRepository;
import com.sparta.myselectshop.repository.UserRepository;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class ProductService {
private final FolderRepository folderRepository;
private final ProductRepository productRepository;
private final UserRepository userRepository;
private final JwtUtil jwtUtil;
@Transactional
public ProductResponseDto createProduct(ProductRequestDto requestDto, HttpServletRequest request) {
String token = jwtUtil.resolveToken(request);
Claims claims;
if (token != null) {
if (jwtUtil.validateToken(token)) {
claims = jwtUtil.getUserInfoFromToken(token);
} else {
throw new IllegalArgumentException("Token Error");
}
User user = userRepository.findByUsername(claims.getSubject()).orElseThrow(
() -> new IllegalArgumentException("사용자가 존재하지 않습니다.")
);
Product product = productRepository.saveAndFlush(new Product(requestDto, user.getId()));
return new ProductResponseDto(product);
} else {
return null;
}
}
@Transactional(readOnly = true)
public Page<Product> getProducts(HttpServletRequest request,
int page, int size, String sortBy, boolean isAsc) {
Sort.Direction direction = isAsc ? Sort.Direction.ASC : Sort.Direction.DESC;
Sort sort = Sort.by(direction, sortBy);
Pageable pageable = PageRequest.of(page, size, sort);
String token = jwtUtil.resolveToken(request);
Claims claims;
if (token != null) {
if (jwtUtil.validateToken(token)) {
claims = jwtUtil.getUserInfoFromToken(token);
} else {
throw new IllegalArgumentException("Token Error");
}
User user = userRepository.findByUsername(claims.getSubject()).orElseThrow(
() -> new IllegalArgumentException("사용자가 존재하지 않습니다.")
);
UserRoleEnum userRoleEnum = user.getRole();
System.out.println("role = " + userRoleEnum);
Page<Product> products;
if (userRoleEnum == UserRoleEnum.USER) {
products = productRepository.findAllByUserId(user.getId(), pageable);
} else {
products = productRepository.findAll(pageable);
}
return products;
} else {
return null;
}
}
@Transactional
public Long updateProduct(Long id, ProductMypriceRequestDto requestDto, HttpServletRequest request) {
String token = jwtUtil.resolveToken(request);
Claims claims;
if (token != null) {
if (jwtUtil.validateToken(token)) {
claims = jwtUtil.getUserInfoFromToken(token);
} else {
throw new IllegalArgumentException("Token Error");
}
User user = userRepository.findByUsername(claims.getSubject()).orElseThrow(
() -> new IllegalArgumentException("사용자가 존재하지 않습니다.")
);
Product product = productRepository.findByIdAndUserId(id, user.getId()).orElseThrow(
() -> new NullPointerException("해당 상품은 존재하지 않습니다.")
);
product.update(requestDto);
return product.getId();
} else {
return null;
}
}
@Transactional
public void updateBySearch(Long id, ItemDto itemDto) {
Product product = productRepository.findById(id).orElseThrow(
() -> new NullPointerException("해당 상품은 존재하지 않습니다.")
);
product.updateByItemDto(itemDto);
}
@Transactional
public Product addFolder(Long productId, Long folderId, HttpServletRequest request) {
String token = jwtUtil.resolveToken(request);
Claims claims;
if (token != null) {
if (jwtUtil.validateToken(token)) {
claims = jwtUtil.getUserInfoFromToken(token);
} else {
throw new IllegalArgumentException("Token Error");
}
User user = userRepository.findByUsername(claims.getSubject()).orElseThrow(
() -> new IllegalArgumentException("사용자가 존재하지 않습니다.")
);
Product product = productRepository.findById(productId)
.orElseThrow(() -> new NullPointerException("해당 상품 아이디가 존재하지 않습니다."));
Folder folder = folderRepository.findById(folderId)
.orElseThrow(() -> new NullPointerException("해당 폴더 아이디가 존재하지 않습니다."));
Long loginUserId = user.getId();
if (!product.getUserId().equals(loginUserId) || !folder.getUser().getId().equals(loginUserId)) {
throw new IllegalArgumentException("회원님의 관심상품이 아니거나, 회원님의 폴더가 아닙니다~^^");
}
Optional<Product> overlapFolder = productRepository.findByIdAndFolderList_Id(product.getId(), folder.getId());
if(overlapFolder.isPresent()) {
throw new IllegalArgumentException("중복된 폴더입니다.");
}
product.addFolder(folder);
return product;
} else {
return null;
}
}
}
3) UserService
package com.sparta.myselectshop.service;
import com.sparta.myselectshop.dto.LoginRequestDto;
import com.sparta.myselectshop.dto.SignupRequestDto;
import com.sparta.myselectshop.entity.User;
import com.sparta.myselectshop.entity.UserRoleEnum;
import com.sparta.myselectshop.jwt.JwtUtil;
import com.sparta.myselectshop.repository.UserRepository;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final JwtUtil jwtUtil;
private static final String ADMIN_TOKEN = "AAABnvxRVklrnYxKZ0aHgTBcXukeZygoC";
@Transactional
public void signup(SignupRequestDto signupRequestDto) {
String username = signupRequestDto.getUsername();
String password = signupRequestDto.getPassword();
String email = signupRequestDto.getEmail();
Optional<User> found = userRepository.findByUsername(username);
if (found.isPresent()) {
throw new IllegalArgumentException("중복된 사용자가 존재합니다.");
}
UserRoleEnum role = UserRoleEnum.USER;
if (signupRequestDto.isAdmin()) {
if (!signupRequestDto.getAdminToken().equals(ADMIN_TOKEN)) {
throw new IllegalArgumentException("관리자 암호가 틀려 등록이 불가능합니다.");
}
role = UserRoleEnum.ADMIN;
}
User user = new User(username, password, email, role);
userRepository.save(user);
}
@Transactional(readOnly = true)
public void login(LoginRequestDto loginRequestDto, HttpServletResponse response) {
String username = loginRequestDto.getUsername();
String password = loginRequestDto.getPassword();
User user = userRepository.findByUsername(username).orElseThrow(
() -> new IllegalArgumentException("등록된 사용자가 없습니다.")
);
if(!user.getPassword().equals(password)){
throw new IllegalArgumentException("비밀번호가 일치하지 않습니다.");
}
response.addHeader(JwtUtil.AUTHORIZATION_HEADER, jwtUtil.createToken(user.getUsername(), user.getRole()));
}
}
application.properties
spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:db;MODE=MYSQL;
spring.datasource.username=sa
spring.datasource.password=
spring.thymeleaf.cache=false
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true
jwt.secret.key=7ZWt7ZW0OTntmZTsnbTtjIXtlZzqta3snYTrhIjrqLjshLjqs4TroZzrgpjslYTqsIDsnpDtm4zrpa3tlZzqsJzrsJzsnpDrpbzrp4zrk6TslrTqsIDsnpA=