안녕하세요! 강의를 들으며 결국 HandlerAdapter는 내부 로직을 통해 핸들러 종류에 관계없이 ModelAndView를 생성해 DispatcherServlet에게 전달해준다고 이해했습니다. 그렇다면, @ResponseBody 등을 사용해 HTTP 메시지 바디에 값을 직접 입력하는 경우에도 ModelAndVIew가 반환되나요? ModelAndVIew 가 내부적으로 뭔가 HTTP 메시지 바디를 그대로 들고있을 수 있는 field 같은 것이 있는건지 궁금합니다. 감사합니다!
안녕하세요 선생님 이번에 선생님 강의를 수강하려고 막 시작한 학생입니다. 좋은 강의를 만들어 주셔서 감사합니다. 현재 기초를 수강중인데 이에앞서 질문드립니다. 강의수강 방법은 먼저 문제를 풀어보고 강의를 보며 코드 비교 방식으로 수강을 하는 방법을 추천하시는것 같은데 DFS 나 스택 큐 등 개념강의나 이론공부를 따로하지않고 바로 풀기 및 수강을 하는게 나은지요? 문제당 고민시간은 어느정도로 잡아야 괜찮을지요?.. 강의 수강 및 복습을 하고나면 백준에서 바로 삼성이나 카카오등의 기업 기출문제를 바로 풀기 시작하면될까요?
안녕하세요. 강의 잘 듣고있습니다! 다름이 아니라 요청마다 쓰레드를 생성하여 다중 요청에 대응하는 부분을 보고 질문이 생겨서 남깁니다. servlet은 서블릿 컨테이너에 의해 싱글톤으로 관리되는 것으로 배웠는데, 기존 쓰레드가 요청 1을 servlet을 사용하여 처리하고 있는 와중에 새로운 요청 2가 들어와서 새로운 쓰레드가 생성되고 servlet을 사용하려고 하면 이미 요청 1이 servlet을 사용하고 있기 때문에 사용할 수 없지 않은지 질문드립니다. 감사합니다.
n, m = map(int, input().split()) a = list(map(int, input().split())) cnt = 0 for lt in range(n): rt = lt + 1 tot = 0 while tot < m and rt <= n: tot = sum(a[lt:rt]) if tot == m: cnt += 1 break rt += 1 print(cnt) 4, 5번 테스트 케이스에서 시간초과가 나옵니다 ㅜ
안녕하세요! 논리 뷰 이름 획득 이후 적합한 ViewResolver를 찾는 방식에 대해 질문드립니다. HandlerAdapter 때와 비슷하게 ViewResolver에 메시지를 보내 특정 논리 뷰 이름에 대응하는 View를 생성할 수 있는 ViewResolver인지(?) 확인하는 방식으로 찾게 되는건가? 하고 생각했는데 이러한 방식이 맞는 것일지 궁금합니다! 감사합니다.
안녕하세요? 지난번에 Collection Bean 검증 관련해서 질문 글을 올렸었어요. 지난번 글은 아래 링크를 통해서 보실수 있습니다. https://www.inflearn.com/questions/639710 Collection Bean 검증까지도 잘 되었고 1차 중첩 검증 까지는 잘 되었었습니다. 코드를 보여드리자면... @Component @Slf4j @RequiredArgsConstructor public class CollectionValidator implements ConstraintValidator<CustomValid, Object> { private final ElementValidator validator; @Override public void initialize(CustomValid constraintAnnotation) { ConstraintValidator.super.initialize(constraintAnnotation); } @Override public boolean isValid(Object values, ConstraintValidatorContext context) { log.info("validator 로직 실행 {}", values.toString()); DataBinder dataBinder = new DataBinder(values); BindingResult bindingResult = dataBinder.getBindingResult(); //bindingResult를 생성해서 전달 validator.validate(values,bindingResult);//필드에 선언된 어노테이션에 따라 검증 if(bindingResult.hasErrors())return false; return true; } }//지난번 글에서 David님의 조언에 따라 수정되었습니다. @Data public class Item { @CustomValid private PatternDto pattern;//내부에는 phonNumber라는 필드와 @Pattern으로 전화번호 형식인지 검사합니다 public Item() { } } @PostMapping("/nested") public Object nested(@RequestBody @Validated Item item){ return item; } 여기까지는 검증이 잘 되었습니다. 즉 POST: /nested 로 아래 형식으로는 잘 검증이 되었습니다. { "pattern" : { "phoneNumber":"01045309731" } } 하지만 PatternDto안에 새로운 객체 ItemValid를 넣고 검증 어노테이션을 추가하게 되면 ItemValid에 대한 검증이 되지 않아요. 즉, 정리하자면 POST: /nested url로 Item 객체에 선언된 PatternDto pattern 필드 객체는 검증이 잘 되지만, PatternDto 클래스 안에 있는 ItemChild의 @Min(10) value에 대한 검증은 이뤄지지 않네요. @Data @NoArgsConstructor public class ItemChild { @Min(10) private Long value; } @Data @EqualsAndHashCode @NoArgsConstructor public class PatternDto { @Pattern(regexp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$", message ="잘못된 번호 형식입니다.") private String phoneNumber; @CustomValid private ItemChild itemChild; } 이렇게 domain을 수정 후에 다음과 같이 요청을 보내면 { "pattern" : { "phoneNumber":"01045309731", "itemChild":{ "value":10 } } } 아래 사진과 같은 에러가 나옵니다. 구글링 해도 잘 안나오는데 어떻게 해결할 수 있을까요?
@Data @AllArgsConstructor public class ErrorResult { private String code; private String message; private Map<String, Object> map; } @Slf4j @RestControllerAdvice public class ExControllerAdvice { @ExceptionHandler public ResponseEntity<ErrorResult> userExHandler(UserException e, Map<String, Object> map) { log.error("[exceptionHandler] ex", e); ErrorResult errorResult = new ErrorResult("USER-EX", e.getMessage(), map); return new ResponseEntity(errorResult, HttpStatus.BAD_REQUEST); } } public class UserException extends RuntimeException { public UserException() { super(); } public UserException(String message) { super(message); } public UserException(String message, Throwable cause) { super(message, cause); } public UserException(Throwable cause) { super(cause); } protected UserException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } } 이렇게 만들고 컨트롤러에서 사용을 할려고 ... Map<String, Object> returnMap = new HashMap<>(); returnMap.put("errorTitle", "titleMsg"); throw new UserException("ERROR", returnMap); ... 이런식으로 만들었는데 UserException 클래스에서 두 번째 파라미터로 받는 부분이 Throwable 타입이라 오류가 발생되는데.. 혹시 두번째 파라미터에 맵이나 리스트나 String등 원하는 값을 받아서 ResponseEneity 타입으로 보내줄려고 하면 어떻게 수정을 해야할까요? UserException을 아래처럼 수정을 했는데 public UserException(String message, Map<String, Object> map) { super(message); this.map = map; } 포스트맨으로 테스트를 해 보면 원하는 에러코드가 출력되는게 아니라 기본적인 오류코드가 출력이 되어버리네요..
안녕하세요. 영한님 항상 강의 잘 보고 있습니다. 현재 강의에서는 모든 예제가 Thymeleaf 기준으로 진행되고 있는데, 현재 Bean Validator 기술이 다른 뷰 템플릿이나 / 리액트에는 적용되지 않는 것인지 궁금합니다. 만약 적용되지 않는다면 리액트와 스프링 부트를 활용한 프로젝트를 진행할 때 어떠한 방향으로 예외처리를 진행해야 할지 궁금합니다!
안녕하세요! 영한님! 항상 강의 잘 보고 있습니다. 사실은 영한님 팬이기도 해요. 아무튼 제가 며칠 계속 고민하던 부분이 있어요. 제 목표는 컬렉션 타입과 상관 없이 컬렉션 안에 선언되어 있는 객체의 Bean Validation을 수행하고 싶어요. @RequestBody @Validated List<ItemSaveForm> 를 사용하게 되면 ItemSaveForm에 대한 검증이 아닌 List에 대한 검증 처리가 되더라고요. 그렇다고 List<@Validated ItemSaveForm> 는 컴파일 에러가 납니다. 물론 저 스스로 해결하고자 많은 곳을 돌아 다녀 보았고 찾아낸 방법은 Validator를 구현한 객체(CollectionValidator)를 만들어서 validate 메서드 구현 을 했습니다. 이후 ItemController에서 CollectionValidation 를 주입 받아 collectionValidator.validate(itemList, bindingResult);를 통해서 검증 처리를 하는 법을 알아냈습니다. 하지만 모든 Collection 마다 주입과 collectionValidator.validate 코드를 넣는게 비효율적이라 생각해서 어노테이션으로 만들거나 인터셉터에서 처리하고 싶었습니다. 인터셉터에서 처리하고 싶었지만 CollectionValidation의 validate 메서드는 Errors 객체를 인자로 받는데 HandlerMethodArgumentResolver의 resolveArgument인자에서 errors 객체를 뽑아낼 방법이 안보이네요. 어노테이션으로 만들고자 한 부분은 어노테이션 안에 Errors 객체를 선한 할 수가 없어서 CollectionValidator를 불러낼 수가 없었습니다. 다른 해결 책이 있을 까요? 아니면 제가 보지 못한 부분이 있었던 걸까요? 혹시 결국 스프링 입문때 잠시 다루었던 AOP를 통해서만 해결할 수 있는 걸까요? 어노테이션 만들기를 검색하다보니 AOP를 결국 다뤄야 하더라고요 ㅜㅜ 아래 제 코드와 함께 올리겠습니다. @Data public class PatternDto { //이 어노테이션에게 검증을 맡기고자 합니다. @Pattern(regexp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$", message ="잘못된 번호 형식입니다.") private String phoneNumber; } @RestController public class ValidationItemApiController { //private final CollectionValidator validator; @PostMapping("/list") public Object addList(@RequestBody List<PatternDto> request, BindingResult bindingResult){ //validator.validate(request, bindingResult); -> 이 부분을 어노테이션이나 인터셉터로 처리하고 싶어요. log.info("list valid"); if(bindingResult.hasErrors()){ log.error("검증 오류 발생 {}", bindingResult); return bindingResult.getAllErrors(); } log.info("성공 로직 실행"); return request; } } @Component @Slf4j public class CollectionValidator implements Validator { private SpringValidatorAdapter validator; public CollectionValidator() { this.validator = new SpringValidatorAdapter( Validation.buildDefaultValidatorFactory().getValidator() ); } @Override public boolean supports(Class<?> clazz) { return true; } @Override public void validate(Object target, Errors errors) { if(target instanceof Collection){ Collection collection = (Collection) target; for (Object o : collection) { validator.validate(o,errors); } } else validator.validate(target,errors); } } //이 검증기를 통해 List<@Valid PatternDto>와 같이 검증하고 싶었지만 //validtor.validate에게 검증을 위임하려고 할때(많은 검증 로직들이 간소화 되기 때문에) validate메서드의 두번째 인자인 errors //에 넣을 값을 찾지 못한게 문제였습니다. //ArgumentResolver를 통해 해결하고자 했지만 이때도 validate의 errors 인자를 넣을 값을 못찾았습니다. @Component @Slf4j @RequiredArgsConstructor public class CustomValidator implements ConstraintValidator<CustomValid, List<PatternDto>> { private final CollectionValidator validator; @Override public void initialize(CustomValid constraintAnnotation) { ConstraintValidator.super.initialize(constraintAnnotation); } @Override public boolean isValid(List<PatternDto> values, ConstraintValidatorContext context) { log.info("validator 로직 실행"); validator.validate(values,null); //null 대신에 어떤 값을 넣어야 할까요? 이 부분만 해결 되어도 문제가 해결 될거 같아요. return true; } }