From 9ef192ed32bb03e788ba3de8139fb2e5d8d799fd Mon Sep 17 00:00:00 2001 From: vladp Date: Wed, 10 Dec 2025 12:17:08 +0700 Subject: [PATCH] add strategy for controller --- .../no_copy/controller/ApiController.java | 94 +++++++------------ .../no_copy/controller/AuthController.java | 13 --- .../exception/ValidationException.java | 16 ++++ .../no_copy/handler/LoginRequestHandler.java | 47 ++++++++++ .../no_copy/handler/RegRequestHandler.java | 59 ++++++++++++ .../soune/no_copy/handler/RequestHandler.java | 9 ++ 6 files changed, 166 insertions(+), 72 deletions(-) create mode 100644 src/main/java/ru/soune/no_copy/exception/ValidationException.java create mode 100644 src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java create mode 100644 src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java create mode 100644 src/main/java/ru/soune/no_copy/handler/RequestHandler.java diff --git a/src/main/java/ru/soune/no_copy/controller/ApiController.java b/src/main/java/ru/soune/no_copy/controller/ApiController.java index 9b3c934..174fcf7 100644 --- a/src/main/java/ru/soune/no_copy/controller/ApiController.java +++ b/src/main/java/ru/soune/no_copy/controller/ApiController.java @@ -1,24 +1,20 @@ package ru.soune.no_copy.controller; -import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.http.ResponseEntity; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.*; import ru.soune.no_copy.dto.BaseRequest; -import ru.soune.no_copy.dto.LoginRequest; import ru.soune.no_copy.dto.MessageCode; -import ru.soune.no_copy.dto.RegRequest; -import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.exception.NotValidFieldException; -import ru.soune.no_copy.handler.RegRequestValidator; -import ru.soune.no_copy.repository.UserRepository; -import ru.soune.no_copy.service.AuthService; +import ru.soune.no_copy.exception.ValidationException; +import ru.soune.no_copy.handler.LoginRequestHandler; +import ru.soune.no_copy.handler.RegRequestHandler; +import ru.soune.no_copy.handler.RequestHandler; import java.util.HashMap; import java.util.List; @@ -30,65 +26,45 @@ import java.util.stream.Collectors; @RequestMapping("/api") @RequiredArgsConstructor public class ApiController { + private final ApplicationContext applicationContext; - private final ObjectMapper objectMapper; + private Map handlers = new HashMap<>(); - private final UserRepository userRepository; + @PostConstruct + public void init() { + RegRequestHandler regHandler = applicationContext.getBean(RegRequestHandler.class); + LoginRequestHandler loginHandler = applicationContext.getBean(LoginRequestHandler.class); - private final RegRequestValidator regRequestValidator; - - private final PasswordEncoder passwordEncoder; - - @Autowired - private AuthService authService; + handlers.put(20002, regHandler); + handlers.put(20001, loginHandler); + } @PostMapping("/v{version}/data") - public ResponseEntity handlePostRequest(@RequestBody BaseRequest request, @PathVariable("version") int version) { + public ResponseEntity handlePostRequest(@RequestBody BaseRequest request, + @PathVariable("version") int version) { Integer msgId = request.getMsgId(); - Map response; - switch (msgId) { - case 20002: - RegRequest regRequest = objectMapper.convertValue(request.getMessageBody(), RegRequest.class); + try { + RequestHandler handler = handlers.get(msgId); - if (userRepository.existsByEmail(regRequest.getEmail())) { - throw new NotValidFieldException("User already exists with email: " + regRequest.getEmail(), - msgId, MessageCode.REG_EMAIL_EXISTS.getCode(), MessageCode.REG_EMAIL_EXISTS.getDescription()); - } - - BindingResult bindingResult = new BeanPropertyBindingResult(regRequest, "regRequest"); - - regRequestValidator.validate(regRequest, bindingResult); - - if (bindingResult.hasErrors()) { - return createValidationErrorResponse(bindingResult, msgId); - } else { - authService.register(regRequest); - response = fillResponseInfo(msgId, MessageCode.SUCCESS.getCode(), - MessageCode.SUCCESS.getDescription()); - } - break; - case 20001: - LoginRequest loginRequest = objectMapper.convertValue(request.getMessageBody(), LoginRequest.class); - - if (!userRepository.existsByEmail(loginRequest.getEmail())) { - - throw new NotValidFieldException("User with email not found: " + loginRequest.getEmail(), - msgId, MessageCode.AUTH_EMAIL_NOT_FOUND.getCode(), - MessageCode.AUTH_EMAIL_NOT_FOUND.getDescription()); - } - - authService.login(loginRequest); - - response = fillResponseInfo(msgId, MessageCode.SUCCESS.getCode(), - MessageCode.SUCCESS.getDescription()); - break; - default: - return ResponseEntity.ok().body(fillResponseInfo(msgId, MessageCode.MSG_ID_NOT_FOUND.getCode(), + if (handler == null) { + return ResponseEntity.ok().body(fillResponseInfo(msgId, + MessageCode.MSG_ID_NOT_FOUND.getCode(), MessageCode.MSG_ID_NOT_FOUND.getDescription())); - } + } - return ResponseEntity.ok().body(response); + Map response = handler.handle(request); + + return ResponseEntity.ok().body(response); + + } catch (ValidationException e) { + return createValidationErrorResponse(e.getBindingResult(), e.getMsgId()); + } catch (NotValidFieldException e) { + throw e; + } catch (Exception e) { + log.error("Handler execution failed for msgId: {}", msgId, e); + throw new RuntimeException("Handler execution failed", e); + } } private ResponseEntity> createValidationErrorResponse( diff --git a/src/main/java/ru/soune/no_copy/controller/AuthController.java b/src/main/java/ru/soune/no_copy/controller/AuthController.java index 5586e80..8247049 100644 --- a/src/main/java/ru/soune/no_copy/controller/AuthController.java +++ b/src/main/java/ru/soune/no_copy/controller/AuthController.java @@ -1,13 +1,8 @@ package ru.soune.no_copy.controller; -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import ru.soune.no_copy.dto.AuthResponse; -import ru.soune.no_copy.dto.LoginRequest; -import ru.soune.no_copy.dto.LoginResponse; -import ru.soune.no_copy.dto.RegisterRequest; import ru.soune.no_copy.entity.AuthToken; import ru.soune.no_copy.exception.TokenNotFoundException; import ru.soune.no_copy.repository.AuthTokenRepository; @@ -25,14 +20,6 @@ public class AuthController { private final AuthTokenRepository authTokenRepository; - @PostMapping("/login") - public ResponseEntity login(@Valid @RequestBody LoginRequest request) { - AuthToken login = authService.login(request); - - return ResponseEntity.ok(new LoginResponse(true, login.getUser().getEmail(), - login.getToken(),login.getExpiresAt().toString())); - } - @PostMapping("/logout") public ResponseEntity logout(@RequestHeader("Authorization") String tokenHeader) { String token = tokenHeader.replace("Bearer ", ""); diff --git a/src/main/java/ru/soune/no_copy/exception/ValidationException.java b/src/main/java/ru/soune/no_copy/exception/ValidationException.java new file mode 100644 index 0000000..f9c9d52 --- /dev/null +++ b/src/main/java/ru/soune/no_copy/exception/ValidationException.java @@ -0,0 +1,16 @@ +package ru.soune.no_copy.exception; + +import lombok.Getter; +import org.springframework.validation.BindingResult; + +@Getter +public class ValidationException extends RuntimeException { + private final BindingResult bindingResult; + private final Integer msgId; + + public ValidationException(BindingResult bindingResult, Integer msgId) { + super("Validation failed"); + this.bindingResult = bindingResult; + this.msgId = msgId; + } +} diff --git a/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java b/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java new file mode 100644 index 0000000..0b2044a --- /dev/null +++ b/src/main/java/ru/soune/no_copy/handler/LoginRequestHandler.java @@ -0,0 +1,47 @@ +package ru.soune.no_copy.handler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import ru.soune.no_copy.dto.BaseRequest; +import ru.soune.no_copy.dto.LoginRequest; +import ru.soune.no_copy.dto.MessageCode; +import ru.soune.no_copy.exception.NotValidFieldException; +import ru.soune.no_copy.repository.UserRepository; +import ru.soune.no_copy.service.AuthService; + +import java.util.HashMap; +import java.util.Map; + +@Component +@RequiredArgsConstructor +public class LoginRequestHandler implements RequestHandler { + + private final UserRepository userRepository; + private final AuthService authService; + private final ObjectMapper objectMapper; + + @Override + public Map handle(BaseRequest request) { + LoginRequest loginRequest = objectMapper.convertValue(request.getMessageBody(), LoginRequest.class); + + if (!userRepository.existsByEmail(loginRequest.getEmail())) { + throw new NotValidFieldException("User with email not found: " + loginRequest.getEmail(), + request.getMsgId(), MessageCode.AUTH_EMAIL_NOT_FOUND.getCode(), + MessageCode.AUTH_EMAIL_NOT_FOUND.getDescription()); + } + + authService.login(loginRequest); + + return fillResponseInfo(request.getMsgId(), MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription()); + } + + private Map fillResponseInfo(Integer msgId, Integer messageCode, String messageDesc) { + Map response = new HashMap<>(); + response.put("msg_id", msgId); + response.put("message_code", messageCode); + response.put("message_desc", messageDesc); + return response; + } +} diff --git a/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java b/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java new file mode 100644 index 0000000..c6a83ed --- /dev/null +++ b/src/main/java/ru/soune/no_copy/handler/RegRequestHandler.java @@ -0,0 +1,59 @@ +package ru.soune.no_copy.handler; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.validation.BindingResult; +import ru.soune.no_copy.dto.BaseRequest; +import ru.soune.no_copy.dto.MessageCode; +import ru.soune.no_copy.dto.RegRequest; +import ru.soune.no_copy.exception.NotValidFieldException; +import ru.soune.no_copy.exception.ValidationException; +import ru.soune.no_copy.repository.UserRepository; +import ru.soune.no_copy.service.AuthService; + +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@Component +@RequiredArgsConstructor +public class RegRequestHandler implements RequestHandler { + + private final UserRepository userRepository; + private final RegRequestValidator regRequestValidator; + private final AuthService authService; + private final ObjectMapper objectMapper; + + @Override + public Map handle(BaseRequest request) throws ValidationException { + RegRequest regRequest = objectMapper.convertValue(request.getMessageBody(), RegRequest.class); + + if (userRepository.existsByEmail(regRequest.getEmail())) { + throw new NotValidFieldException("User already exists with email: " + regRequest.getEmail(), + request.getMsgId(), MessageCode.REG_EMAIL_EXISTS.getCode(), + MessageCode.REG_EMAIL_EXISTS.getDescription()); + } + + BindingResult bindingResult = new BeanPropertyBindingResult(regRequest, "regRequest"); + regRequestValidator.validate(regRequest, bindingResult); + + if (bindingResult.hasErrors()) { + throw new ValidationException(bindingResult, request.getMsgId()); + } + + authService.register(regRequest); + return fillResponseInfo(request.getMsgId(), MessageCode.SUCCESS.getCode(), + MessageCode.SUCCESS.getDescription()); + } + + private Map fillResponseInfo(Integer msgId, Integer messageCode, String messageDesc) { + Map response = new HashMap<>(); + response.put("msg_id", msgId); + response.put("message_code", messageCode); + response.put("message_desc", messageDesc); + return response; + } +} \ No newline at end of file diff --git a/src/main/java/ru/soune/no_copy/handler/RequestHandler.java b/src/main/java/ru/soune/no_copy/handler/RequestHandler.java new file mode 100644 index 0000000..d78e19b --- /dev/null +++ b/src/main/java/ru/soune/no_copy/handler/RequestHandler.java @@ -0,0 +1,9 @@ +package ru.soune.no_copy.handler; + +import ru.soune.no_copy.dto.BaseRequest; + +import java.util.Map; + +public interface RequestHandler { + Map handle(BaseRequest request) throws Exception; +}