월 24,200원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
BindingResult의 타입오류시 400 오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 가격에 문자를 입력하면 400 에러가 발생합니다. Controller @PostMapping("/add") public String addItemv3(@ModelAttribute Item item, RedirectAttributes redirectAttributes, BindingResult bindingResult) { // bindingResult 스프링 제공 검증 기능 //검증 로직 if(!StringUtils.hasText(item.getItemName())){ // bindingResult.addError(new FieldError("item","itemName","상품 이름은 필수 입니다.")); bindingResult.addError(new FieldError("item","itemName",item.getItemName(),false,new String[]{"required.item.itemName"},null,null)); } if (item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000) { // bindingResult.addError(new FieldError("item","price","가격은 1,000 ~ 1,000,000 까지 허용합니다.")); bindingResult.addError(new FieldError("item","price",item.getPrice(),false,new String[]{"range.item.price"},new Object[]{1000,1000000},null)); } if (item.getQuantity() == null || item.getQuantity() >= 9999) { // bindingResult.addError(new FieldError("item","quantity","수량은 최대 9,999 까지 허용합니다.")); bindingResult.addError(new FieldError("item","quantity",item.getQuantity(),false,new String[]{"max.item.quantity"},new Object[]{9999},null)); } //특정 필드가 아닌 복합 룰 검증 if (item.getPrice() != null && item.getQuantity() != null) { int resultPrice = item.getPrice() * item.getQuantity(); if (resultPrice < 10000) { bindingResult.addError(new ObjectError("item",new String[]{"totalPriceMin"},new Object[]{10000,resultPrice},null)); } } log.info("bindingResult ={}"+bindingResult); //검증에 실패하면 다시 입력 폼으로 if (!bindingResult.hasErrors()) { log.info("errors={}",bindingResult); return "validation/v2/addForm"; } // 성공 로직 Item savedItem = itemRepository.save(item); redirectAttributes.addAttribute("itemId", savedItem.getId()); redirectAttributes.addAttribute("status", true); return "redirect:/validation/v2/items/{itemId}"; } @GetMapping("/add") public String addForm(Model model) { model.addAttribute("item", new Item()); return "validation/v2/addForm"; } 강의에서는 error 출력하는 부분에서 스프링에서 제공하는 메세지가 뜨는데 저는 위와 같이 결과가 나옵니다.로그는 2023-07-13 08:31:36.584 WARN 20844 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errorsField error in object 'item' on field 'price': rejected value [qq]; codes [typeMismatch.item.price,typeMismatch.price,typeMismatch.java.lang.Integer,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.price,price]; arguments []; default message [price]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Integer' for property 'price'; nested exception is java.lang.NumberFormatException: For input string: "qq"]] 이렇게 나옵니다. 혹시 원인을 알 수 있을까여?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Error parsing HTTP request header 문제
안녕하세요.MVC 2편 파일 업로드 강의를 수강하는 중 발생하는 문제 질문드립니다.스프링 버전 문제인가 싶어서, 강사님 프로젝트를 그대로 다운로드해서 빌드했는데도 (2.5.1 버전), 모든 페이지에서 저렇게 에러가 발생합니다.(index페이지만가도) 어떤 부분을 수정해야할까요 ? 2023-07-08 12:06:39.541 INFO 8668 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'2023-07-08 12:06:39.542 INFO 8668 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'2023-07-08 12:06:39.543 INFO 8668 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms2023-07-08 12:06:39.636 DEBUG 8668 --- [nio-8080-exec-1] o.a.coyote.http11.Http11InputBuffer : Before fill(): parsingHeader: [true], parsingRequestLine: [true], parsingRequestLinePhase: [0], parsingRequestLineStart: [0], byteBuffer.position(): [0], byteBuffer.limit(): [0], end: [728]2023-07-08 12:06:39.636 DEBUG 8668 --- [nio-8080-exec-1] o.a.coyote.http11.Http11InputBuffer : Received []2023-07-08 12:06:39.637 DEBUG 8668 --- [nio-8080-exec-1] o.apache.coyote.http11.Http11Processor : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@240fb734:org.apache.tomcat.util.net.NioChannel@3c42f742:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:53200]], Status in: [OPEN_READ], State out: [OPEN]2023-07-08 12:06:43.954 DEBUG 8668 --- [nio-8080-exec-2] o.a.coyote.http11.Http11InputBuffer : Before fill(): parsingHeader: [true], parsingRequestLine: [true], parsingRequestLinePhase: [0], parsingRequestLineStart: [0], byteBuffer.position(): [0], byteBuffer.limit(): [0], end: [728]2023-07-08 12:06:43.955 DEBUG 8668 --- [nio-8080-exec-3] o.a.coyote.http11.Http11InputBuffer : Before fill(): parsingHeader: [true], parsingRequestLine: [true], parsingRequestLinePhase: [0], parsingRequestLineStart: [0], byteBuffer.position(): [0], byteBuffer.limit(): [0], end: [0]2023-07-08 12:06:43.970 DEBUG 8668 --- [nio-8080-exec-2] o.apache.coyote.http11.Http11Processor : Error parsing HTTP request headerjava.io.EOFException: null at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1345) ~[tomcat-embed-core-9.0.46.jar:9.0.46] at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1255) ~[tomcat-embed-core-9.0.46.jar:9.0.46] at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:799) ~[tomcat-embed-core-9.0.46.jar:9.0.46] at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:359) ~[tomcat-embed-core-9.0.46.jar:9.0.46] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:261) ~[tomcat-embed-core-9.0.46.jar:9.0.46] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.46.jar:9.0.46] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.46.jar:9.0.46] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) ~[tomcat-embed-core-9.0.46.jar:9.0.46] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.46.jar:9.0.46] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.46.jar:9.0.46] at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]2023-07-08 12:06:43.970 DEBUG 8668 --- [nio-8080-exec-3] o.apache.coyote.http11.Http11Processor : Error parsing HTTP request header
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
3분에 테스트돌리면 에러가나옵니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.똑같이 테스트만들고 런 했지만 아래와 같은 에러가 나옵니다빌드를 gradle로 설정했고 utf8로 설정도했습니다이건 어떤것떄문에 그럴가요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
인터셉터가 제대로 동작하지 않습니다.
안녕하세요, 이 강의를 완강이후 프로젝트를 수행중인 학부생입니다.로그인 기능 구현과 관련하여 강의 예제 코드를 참고하며 구현하던 중이해할 수 없는 현상이 발생하여 질문 드립니다. 코드LoginInterceptor.javapackage Alchole_free.Cockpybara.interceptor; import Alchole_free.Cockpybara.constant.SessionLoginConst; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @Slf4j //@Component public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(); log.info("session = {}", session); if(session==null || session.getAttribute(SessionLoginConst.LOGIN_MEMBER)==null){ log.info("로그인되지 않은 사용자"); response.sendRedirect("/login"); return false; } log.info("정상 요청"); return true; } } WebConfig.javapackage Alchole_free.Cockpybara.config; import Alchole_free.Cockpybara.interceptor.LoginInterceptor; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; //@Slf4j @Configuration //@RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { // private final LoginInterceptor loginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()) .order(1) .addPathPatterns("/**") .excludePathPatterns("/", "/join", "/login", "/css/**", "/*.ico", "/error"); } } 문제위와 같이 코드를 구성하고 애플리케이션을 동작시켰는데, 인터셉터가 아예 로그에 남지않는(생성되지 않는 것으로 보이는) 현상이 발생하였습니다. 관련하여 구글링을 하다보니인터셉터 클래스를 빈으로 등록해주는 형태가 아니면 동작하지 않을 수 있다고 하여,빈으로 등록하고 WebConfig 클래스에서 생성자를 통해 주입받는 형태로 구현도 해보았는데여전히 같은 문제가 발생하더군요. 도대체 어느 부분에서 문제가 발생하는 것인지 파악하기가 힘들어 고민끝에 질문드립니다. 혹시 몰라 아래 빌드, 설정 파일도 첨부합니다. 문제 실행 화면/hello 로 Controller @GetMapping 메서드를 구현해놓고 요청을 보냈으나 인터셉터 관련 로그가기록되지 않는 모습입니다. build.gradleplugins { id 'java' id 'org.springframework.boot' version '2.7.13' id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group = 'Alchole_free' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '11' } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-validation' compileOnly 'org.projectlombok:lombok' runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' //swagger 설정 implementation group:'io.springfox', name:'springfox-swagger2', version:'2.8.0' implementation group:'io.springfox', name:'springfox-swagger-ui', version:'2.8.0' } tasks.named('test') { useJUnitPlatform() } application.properties# DataSource spring.datasource.url=jdbc:mariadb://localhost:3306/cockpybara spring.datasource.username=root spring.datasource.password=cockpybara spring.datasource.driver-class-name=org.mariadb.jdbc.Driver # JPA spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect #show parameter binding logging.level.org.hibernate.type.descriptor.sql=DEBUG logging.level.org.hibernate.SQL=DEBUG
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
날짜 데이터 넘기는 법
안녕하세요 타임리프에서 LocalDate 넘기는 방법중에 타임리프에서 format을 하시던데 제가 프론트 코드를 일하면서 못봐서 그런건지는 모르겠는데 json으로 date를 포맷팅 해서 넘겨주는 방식은 본 것 같거든요 혹시 타임리프에서 date를 직접 받아와서 사용 하는 방식중 어느 방식이 더 좋을까요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
파일 절대경로 질문
가끔 서버끄고 절대경로로 html 보여주실때 화면에 나올 수 있는것은 서버랑 client가 같은 컴퓨터라서 가능한거죠??
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
강의 다 듣고 혼자 하는중인데 도저히 이해가 안가서 여쭤봅니다..
<tr th:each="festival : ${festivalList}"> <td><a th:href="@{/festival/one(param=${festival})}" th:text="${festival.name}"></a> </td> 뷰 단에서 fetivalList을 보여줍니다. 그리고 리스트에서 each문 돌면서 모두 잘보여줍니다. 그리고 festival을 다시 쓸일이 있어서 url에 담아서 컨트롤러로 넘어가면 못받습니다. for문 뿐 아니라 객체 하나만 있는 상황에서도 안넘어가요 @GetMapping("/festival/one/search") public String searchFestivalOne(@ModelAttribute("param") Festival festival, Model model) throws IOException { System.out.println(festival.getName()); String[][] searchList = festivalService.jsonToList(festival.getName()); model.addAttribute(searchList); model.addAttribute(festival.getName()); return "/festival/festival_search.html"; }festival모델에 생성자문제라 생각해서 어노테이션 각각적용해서 모든 케이스 다해봤는데도 안되네요.. 에러는 안뜨고 그냥 null값만 나옵니다.타임리프에서 festival.(변수) 는 모두 잘넘어가는데 festival 만넘기면 바인딩처리가 안됩니다.@Entity @Getter @Setter @NoArgsConstructor @AllArgsConstructor public class Festival { @Id private long id; private String name; //축제명 private String location; //개최장소 private String startDate ;//축제시작일자 private String endDate ; //축제종료일자 private String content ; //축제내용 private String org ; //주관기관 private String open_org; //주최기관 private String sponsor; //후원기관 private String phone_num; //전화번호 private String homepage; //홈페이지주소 private String etc; //관련정보 private String location1; //소재지도로명주소 private String location2; //소재지지번주소 }
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
첨부 파일 코드자체 에러발생합니다. Test시에
Execution failed for task ':test'.> There were failing tests. See the report at: file:///C:/Users/kimta/Desktop/김영한%20강의자료/mvc2/message/build/reports/tests/test/index.html* Try:Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
addForm의 멀티 체크박스에서 질문이 있습니다!
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]<div> <div>등록 지역</div> <div th:each="region : ${regions}" class="form-check form-check-inline"> <input type="checkbox" th:field="*{regions}" th:value="${region.key}" class="form-check-input"> <label th:for="${#ids.prev('regions')}" th:text="${region.value}" class="form-check-label">서울</label> </div> </div>이런 코드였는데 궁금한점은th:field="*{regions}" th:value="${region.key}" 이렇게하면 체크박스를 만약 선택하면 th:value="${region.key} 이렇게 설정한 value의 값이 th:field="*{regions}" item의 regions라는 리스트에 알아서 매핑이 되는건가요??? 또<div> <div>배송방식</div> <select th:field="*{deliveryCode}" class="form-select"> <option value="">==배송 방식 선택==</option> <option th:each="deliveryCode : ${deliveryCodes}" th:value="${deliveryCode.code}" th:text="${deliveryCode.displayName}">FAST</option> </select> </div>여기서 th:value="${deliveryCode.code}" 여기서 선택한 value가 th:field="*{deliveryCode}" 이것에 의해 타임리프에서 알아서 매핑이 되는건가요?? 알아서 매핑이 되는 것이라면 deliveryCode라는 객체에 code와 displayName이 있는데 여기서 code에 알아서 매핑이 되는건지 궁금합니다,,!
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
postman으로 테스트 해봤는데 안되는 이유를 모르겠습니다!
1. 강의 내용과 관련된 질문인가요? (예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예 @Slf4j @RestController @RequiredArgsConstructor public class TemController { private final temRepository temRepository; private final FileStore fileStore; @GetMapping("/tems/kkk") public String kkk(){ return "temtem"; } @GetMapping("/tems/new") public String newItem(@ModelAttribute TemDto dto) { return "item-form"; } @PostMapping("/tems/new") public String saveItem(@ModelAttribute TemDto dto) throws IOException { /*// UploadFile attachFile = fileStore.storeFile(dto.getAttachFile()); UploadFile attachFileee=fileStore.storeFile(attachFile); //데이터베이스에 저장 Tem tem = new Tem(); tem.setTemName(temName); tem.setAttachFile(attachFileee); temRepository.save(tem);*/ UploadFile attachFile = fileStore.storeFile(dto.getAttachFile()); //데이터베이스에 저장 Tem tem = new Tem(); tem.setTemName(dto.getTemName()); tem.setAttachFile(attachFile); temRepository.save(tem); return "ok"; } @ResponseBody @GetMapping("/images/{filename}") public Resource downloadImage(@PathVariable String filename) throws MalformedURLException { return new UrlResource("file:" + fileStore.getFullPath(filename)); } @GetMapping("/attach/{temId}") public ResponseEntity<Resource> downloadAttach(@PathVariable Long temId) throws MalformedURLException { Tem tem = temRepository.findById(temId); String storeFileName = tem.getAttachFile().getStoreFileName(); String uploadFileName = tem.getAttachFile().getUploadFileName(); UrlResource resource = new UrlResource("file:" + fileStore.getFullPath(storeFileName)); log.info("uploadFileName={}", uploadFileName); String encodedUploadFileName = UriUtils.encode(uploadFileName, StandardCharsets.UTF_8); String contentDisposition = "attachment; filename=\"" + encodedUploadFileName + "\""; return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition) .body(resource); } } 교재와 거의 흡사하게 RestController로 짰습니다.서버에 저장할때는 saveItem을 사용했습니다. 실제로 지정된 경로에 이미지가 저장이 되었습니다.그런데 postman통해서 이미지를 확인하고 싶어서 responseEntity<Resource>를 사용했는데...이렇게 이미지가 나오는게 아니라 다 깨져서 나옵니다. 혹시 뭐가 잘못되었는지 아실까요?
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
WAS에서 /error 요청 동작 방식
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]ResponseStatusException 이나 스프링 기본 예외의 경우 response.senderror()를 사용하기 때문에 was에서 /error 요청을 다시 보내는 것으로 이해했습니다. (기본 요청 + 에러 요청)이걸 확인해보고 싶어 필터와 인터셉터를 하나 만들어서 uri를 출력하는 테스트를 수행했는데 인터셉터의 경우 2번 모두 출력되지만 필터는 초기 요청만 출력하고 있습니다.was의 재요청이므로 필터 또한 2번 출력되어야할 것 같은데 잘 이해가 가지 않습니다.
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
마지막 파일 저장 부분 전체적인 흐름 정리 질문
전체적인 흐름에 있어서 생각하는 부분들이 맞는지에 대한 궁금증이 생겨 질문드립니다다른 글들을 참고하였을 때Item은 현재, 별도의 DB가 없기 때문에 DB 역할을 하는 ItemRepository에 저장하기 위해 UploadFile(사용자가 업로드한 파일)를 사용하는 것이 맞나요?ItemForm은 form에서 넘어오는 file 타입을 저장하기 위해서는 MultipartFile 인터페이스를 사용해야 하기 때문에 MultipartFile 참조형을 가져오는 것이 맞나요?FileStore의 경우 실제 파일들이 저장되는 곳이며, 실제 파일들을 저장하고, Repository(실제 파일이 아닌 경로)에 저장하기 위해 형변환을 하는 역할을 하는 것이 맞나요?김영한 강사님에 말씀에 따르면 Repository는 실제 파일들을 저장하는 곳이 아닌 경로를 저장하는 곳이라고 말씀하셨는데 이 말은 즉 Repository에는 경로를 저장하고 해당 실제 파일은 FileStore에 저장되어 있다가 Repository를 통해 호출되면 해당 파일이 호출되는 것이 맞는지 궁금합니다.김영한 강사님께서 쉽고 자세하게 설명해주셨음에도 불구하고 이해가 많이 부족하여 여러가지 질문을 남깁니다...
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
html entity 인식 후 변환 시점
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]이해한 내용HTML 엔티티에 해당하는 html entity(<, >) 문자열을 입력했을때, escape(<, &rt) 문자로 변환된다.Thymeleaf 라이브러리에서 th:text, [[...]] 를 파싱할때는 escape 문자로 변환, th:utext, [(...)] 를 파싱할때는 < 를 문자열 그대로 입력 .위의 내용대로 이해하였습니다!제대로 이해한게 맞다면 어떤 시점에서 이뤄지는것인지 궁금합니다.궁금한 점어떤 시점에서 escape 문자로 변환 혹은 문자열 입력이 되는것인지 궁금합니다.escape 문자로 변환 혹은 문자열 그대로 입력이 되는 시점이 SSR(서버사이드 렌더링)과정에서 이뤄지는것이 맞는지 궁금합니다!
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
검증 관련해서 궁금한 점이 있습니다.
검증 관련해서 궁금한 점이 있습니다. Controller-Service-Repository 구조 + validator 인터페이스를 구현한 클래스가 있다고 했을 때, 사용자가 보낸 uuid가 DB에 존재하는지 여부 검증을 Repository 또는 Service에서 하는게 좋은가요? validator 인터페이스를 구현한 클래스에서 하는게 좋은가요? 아니면, 일관되게 개인이 정하면 되는건가요?
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
오타 제보합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]간단한 경계값 범위 오타 같아요.강의 자료 검증1 5page if (item.getQuantity() == null || item.getQuantity() >= 9999) { errors.put("quantity", "수량은 최대 9,999 까지 허용합니다."); } item.getQuantity() > 9999 로 조건문 범위 변경.그외 13,18,22,24,35page도 마찬가지로 수정이 필요한것 같습니다.
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
로그인 시에 세션객체
스프링 세큐리티의 userDetails를 이용해서 로그인을 구현할 때멤버 테이블의 모든 정보를 담지말라고 하던데... 여기에 pk정도만 담는게 맞을까요?public class CustomMemberDetails implements UserDetails { private String username; private String password; private Collection<? extends GrantedAuthority> authorities; }
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Exception evaluating SpringEL expression: "#fields.hasGlobalErrors()"
먼저 html은 다음과 같이 작성되어있습니다.<form th:action method="post" th:object="${form}" enctype="multipart/form-data"> <input class="form-control" accept=".txt" type="file"> <div th:if="${#fields.hasGlobalErrors()}"> <p class="field-error" th:each="err: ${#fields.globalErrors()}" th:text="${err}">전체 오류 메시지</p> <button class="btn btn-primary">Submit</button> </form>그리고 controller에서는 다음과 같이 작성했습니다.@PostMapping public String getFile(@Validated @ModelAttribute("form") ConvertInputForm inputForm, Model model, BindingResult bindingResult) { if (inputForm.getAttachFile() == null || inputForm.getAttachFile().isEmpty()) { bindingResult.reject("FileSelected", "파일을 다시 선택하세요."); } if (bindingResult.hasErrors()) { return "[위에 작성된 html]"; } ... }ConvertInputForm은 다음과 같이 작성했습니다.@Data public class ConvertInputForm { private MultipartFile attachFile; @NotEmpty private String version; }위와 같이 코드를 작성하고 돌린 다음 파일을 선택하지 않고 버튼을 눌렀습니다.버튼을 눌렀을때 제가 기대한 결과는 bindingResult에 reject("FileSelected", "파일을 다시 선택하세요.") 가 들어가고 html에서 ${#fields.globalErrors() 를 통해서 메시지를 받는 것입니다.그런데 실제 결과는 버튼을 눌렀을때 다음과 같은 에러가 발생합니다.org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "#fields.hasGlobalErrors()"구글링해보면서 해결해보려고 해도 모르겠습니다.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
이 경우에는 어떻게 하나요??
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예[질문 내용]저희가 보았던 인증은 /add/items에 접근을 할 수 있느냐 없느냐 였구 이 과정에서 interceptor에서 걸렀습니다.그런데 자신만의 page에서는 동작 방식이 어떻게 되나요?예를 들면 제 아이디가 dionisos198이니까 dionisos198만 수정 가능한 아이디 변경이라던가 이런 것이요.어떤 과정이 일어나는 것인가요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
스프링 인터셉터 API 인증 궁금합니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예[질문 내용]postman에서 제가 logout api를 직접 만들어 봤습니다.근데 밑 화면에 보면 cookies가 그대로 살아있습니다. 왜 그럴까요?로그인을 하고 다른 api 호출하면 잘 되고 이렇게 로그 아웃 api 호출하고 다른 api호출하면 안되는 상황입니다. 즉 로그아웃 api를 잘 구현한 것 같습니다. 근데 왜 로그아웃 api 호출한 이후에도 밑에 cookies가 남아있을까요?저것의 의미가 response에서 받은 쿠키 얘기 하는 것아닌가요?response.addCookie안에 setMaxage가 0인것으로 갈아껴서 그거 나타내는 것일까요? 그리고 실무에서 api를 통해서는 이렇게 log in,log out 구현하는거 맞을까요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
API 인증 실험 중 궁금한 거 있습니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예[질문 내용]postman으로 필터를 통한 API인증을 실험해 보고 있었습니다.위 그림처럼 /api/items/api/add 를 하면 인증이 안되어야 하므로 뭐 튕기거나 그런 것은 이해 가능인데 Cookies는 대체 왜 생기는 건가요!