package com.koreait.day6.model.network;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Header<T> { //제네릭을 받는 이유: response / request 같이 받을 수 있어서
private LocalDateTime transactionTime;
private String resultCode;
private T data; //객체 넣을 곳
private String description; //에러 발생했을때 넣을 곳
public static <T> Header<T> OK(){
return (Header<T>) Header.builder().transactionTime(LocalDateTime.now())
.resultCode("OK").description("정상").build();
public static <T> Header<T> OK(T data){
return (Header<T>)Header.builder().transactionTime(LocalDateTime.now())
.resultCode("OK").description("정상").data(data).build();
}
public static <T> Header<T> ERROR(String description){
return (Header<T>)Header.builder().transactionTime(LocalDateTime.now())
.resultCode("Error").description("에러!").build();
}
}
OK호출시 저걸 리턴시켜줌! 클라이언트가 요청하면 아래처럼 출력
{
transactionTime: 현재시간,
resultCode: 200,
desctiption: "정상"
}
package com.koreait.day6.ifs;
import com.koreait.day6.model.network.Header;
public interface CrudInterface<Req,Res> {
Header<Res> create(Header<Req> request);
Header<Res> read(Long id);
Header<Res> update(Header<Req> request);
Header<Res> delete(Long id);
}
package com.koreait.day6.controller;
import com.koreait.day6.ifs.CrudInterface;
import com.koreait.day6.model.network.Header;
import org.springframework.stereotype.Component;
@Component //Component: 기본적으로 타입기반의 자동주입 어노테이션 (Autowired 비슷한 기능)
public abstract class CrudController<Req, Res, Entity> implements CrudInterface<Req, Res> {
@Override
public Header<Res> create(Header<Req> request) {
return null;
}
@Override
public Header<Res> read(Long id) {
return null;
}
@Override
public Header<Res> update(Header<Req> request) {
return null;
}
@Override
public Header<Res> delete(Long id) {
return null;
}
}
package com.koreait.day6.controller.api;
import com.koreait.day6.controller.CrudController;
import com.koreait.day6.model.entity.Users;
import com.koreait.day6.model.network.Header;
import com.koreait.day6.model.network.request.UserApiRequest;
import com.koreait.day6.model.network.response.UserApiResponse;
import com.koreait.day6.service.UserApiLogicService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/user") //http://localhost:8888/api/user
@RequiredArgsConstructor
public class UserApiController extends CrudController<UserApiRequest, UserApiResponse, Users> {
private final UserApiLogicService userApiLogicService;
//final 메소드: 더이상 오버라이딩 되지않도록 함
/* //헤더를 통해서 오게됨
{
"transaction_time": "2022-12-14",
"resultCode": "ok",
"description": "정상",
"data":{
"userid":"ryuzy",
"userpw":"1111",
"name":"류정원",
"hp":"010-1111-1111",
"email":"ryuzy@naver.com"
}
}
*/
@Override
@PostMapping("") //http://localhost:8888/api/user (post)
public Header<UserApiResponse> create(@RequestBody Header<UserApiRequest> request) {
return userApiLogicService.create(request);
}
@Override
@GetMapping("{id}") //http://localhost:8888/api/user/{id} (get)
public Header<UserApiResponse> read(@PathVariable(name="id") Long id) {
return userApiLogicService.read(id);
}
@Override
@PutMapping("") //http://localhost:8888/api/user (put)
public Header<UserApiResponse> update(@RequestBody Header<UserApiRequest> request) {
return userApiLogicService.update(request);
}
@Override
@DeleteMapping("{id}") //http://localhost:8888/api/user/{id} (delete)
public Header<UserApiResponse> delete(@PathVariable Long id) {
return userApiLogicService.delete(id);
}
}
BaseService
package com.koreait.day6.service;
import com.koreait.day6.ifs.CrudInterface;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
@Component //자동주입?
public abstract class BaseService<Req,Res,Entity> implements CrudInterface<Req,Res> {
// 빈 타입을 못찾거나 의존성 주입을 할 수 없는 경우 null 에러가 발생, optional로 설정->빈생성 무조건
@Autowired(required = false)
protected JpaRepository<Entity, Long> baseRepository;
}
UserApiLogicService
package com.koreait.day6.service;
import com.koreait.day6.model.entity.Users;
import com.koreait.day6.model.enumclass.UserStatus;
import com.koreait.day6.model.network.Header;
import com.koreait.day6.model.network.request.UserApiRequest;
import com.koreait.day6.model.network.response.UserApiResponse;
import com.koreait.day6.repository.UsersRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import java.time.LocalDateTime;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class UserApiLogicService extends BaseService<UserApiRequest, UserApiResponse, Users >{
private final UsersRepository usersRepository; //자동주입되려면 꼭 private final
//메소드만들자!! json보내주는걸로 여기서만 쓸거니까 private
//객체를 리턴시켜주면 json으로 나오는거 알쥐!!?
private UserApiResponse response(Users users){
UserApiResponse userApiResponse = UserApiResponse.builder()
.id(users.getId())
.userid(users.getUserid())
.userpw(users.getUserpw())
.name(users.getName())
.hp(users.getHp())
.email(users.getEmail())
.regDate(users.getRegDate())
.status(users.getStatus())
.build();
return userApiResponse;
}
@Override
public Header<UserApiResponse> create(Header<UserApiRequest> request) {
UserApiRequest userApiRequest = request.getData(); //@Component 상속받아서 빈이 채워짐?
Users users = Users.builder().userid(userApiRequest.getUserid())
.userpw(userApiRequest.getUserpw()).name(userApiRequest.getName())
.hp(userApiRequest.getHp()).email(userApiRequest.getEmail())
.status(UserStatus.REGISTERED).build();
Users newUsers = baseRepository.save(users);
return Header.OK(response(newUsers));
}
@Override
public Header<UserApiResponse> read(Long id) {
return baseRepository.findById(id).map(users -> response(users))
.map(Header::OK).orElseGet(()->Header.ERROR("데이터 없음"));
}
@Override
public Header<UserApiResponse> update(Header<UserApiRequest> request) {
/* 내코드
UserApiRequest userApiRequest = request.getData();
Optional<Users> users = baseRepository.findById(1L);
users.ifPresent(
selectUsers -> {
selectUsers.setUserpw(userApiRequest.getUserpw());
selectUsers.setName(userApiRequest.getName());
baseRepository.save(selectUsers);
}
);
return null;
*/
UserApiRequest userApiRequest = request.getData();
Optional<Users> users = usersRepository.findByUserid(userApiRequest.getUserid());
return users.map(
user -> {
user.setUserpw(userApiRequest.getUserpw());
user.setName(userApiRequest.getName());
user.setHp(userApiRequest.getHp());
user.setEmail(userApiRequest.getEmail());
return user;
}).map(user -> usersRepository.save(user))
.map(user -> response(user))
.map(Header::OK)
.orElseGet(()->Header.ERROR("데이터 없음")
);
}
@Override
public Header delete(Long id) {
/*내코드
Optional<Users> users = baseRepository.findById(id);
users.ifPresent(
selectUsers ->{
baseRepository.delete(selectUsers);
}
);
return null;
*/
Optional<Users> users = baseRepository.findById(id);
return users.map(user->{
baseRepository.delete(user);
return Header.OK();
}).orElseGet(()->Header.ERROR("데이터 없음"));
}
}