묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
spring mvc vo int 받기 문의 드립니다
spring mvc vo int 받기 문의 드립니다 안녕하세요 강사님프로젝트 도중에 막히는 부분이 있어 질문드립니다보안 지적사항이 나와서 기존 소스 호출 get 방식으로 호출 하는 부분을모두 post 방식으로 변경 하라고 해서작업중입니다뷰 => 컨트롤러 => 서비스 => dao or repository 뷰 화면단에서 <form 에 있는 항목을 컨트롤러로 PostMapping 으로 넘겨 vo 로 받고 싶은데바인딩예외가 발생합니다. vo 클래스에는 현재 int 형으로선언이 되어 있는데 get으로 넘길때는 에러가 없었으나post 로 변경해서 컨트롤러로 넘어가지 않습니다제가 뷰화면단에서 <form 안에 input 타입을 "text" or "number" 형으로 변경 해가면서 테스트 해봐도 마찬가지네요 혹시해결 방법이 있을까요?<<■■■■ 뷰 화면 단 >><form <input type="text" => post 넘기면 에러 발생 <input type="number" => post 넘기면 에러 발생 <<■■■■ 컨트롤러 단 >>@PostMapping('~.do')public getSomeMethod(SomeVoClass param){ //■■메서드파라미터 SomeVoClass 안에 int 형 sn 항목 있습니다<<■■■■ vo 클래스 >>pubiic class SomeVoClass{ private int sn;//■■게시판일련번호 int 형으로 선언됨}<<■■■■ 자바에러메세지 >>org.springframework.validation.BindException:org.springframework.validation.BeanPropertyBindingResult typeMissmatch.SomeVoClass.sntypeMissmatch.sntypeMissMatch.int.typeMismatchdefault message[Failed to convert property value of type 'java.lang.String[]'nested exception is java.lang.NumberFormatException: for input string ",1234"]혹시 시간 나실 때 알려주시면 감사하겠습니다 수고하세요..김동희 드림
-
해결됨[초급] 맛보자! 코틀린과 스프링으로 API 호출하기
Required request body is missing
Required request body is missing소스가 동일한데도 자꾸 위 에러가 나는데요혹시 스프링버전의 문제일까요?
-
미해결스프링 시큐리티 OAuth2
OAuth2.0 코드 부여 방식 인가서버를 REST API 서버 형태로 구현 질문
안녕하세요.. 선생님.. 드디어 완강했습니다.시간 엄청 걸리고 좀 힘들었네요. 다름이 아니라.모바일에서 요청하기 위한 자체 인가서버 OAuth2.0 authorization code 부여 방식 구현을 REST API 서버 형태로 구현할 수 있는지요?사용자 인증 시 웹 페이지 형태의 응답이 아닌 REST API 형태로 요청하고 응답을 받을 수 있도록 구현하려고 합니다. 원래는 인가서버에 사용자 로그인을 하고 동의해야 code 발급받고 클라이언트로 redirect 하여 클라이언트 서버가 대신 인가서버로 access token을 발급 받게 되는데.. 문제가 이 부분이네요.Spring Security 수업에서 ajax 방식으로 API 서버에 요청하면 보통 redirect 없이 응답만 받는 구조이다라고 선생님이 알려주셨는데요. 이와같이 redirect 없이 REST API로 구현할 수 있는 방법이 있는지요?인가서버 로그인은 form login 방식을 사용하지 않고 html 응답 없이 front end 단에서 fetch나 ajax API를 이용해서 POST 전송, json 형태로 username과 password 를 넣어서 요청하고 응답 처리를 할 수 있도록 커스텀하게 구현은 할 수는 있을 것 같긴 해요.. 동의화면은 그냥 false로 해서 안 나오게 하거나 아니면 login 완료 후 json 응답으로 동의가 필요하다는 응답을 주고 다시 POST 방식으로 동의하면 될 것 같긴하네요.클라이언트 서버는 그냥 리소스서버 처럼 사용해서, front end에서 클라이언트 서버로 access token을 전달하여 사용자 정보를 json 응답으로 가져오면 될 것 같아요. 하지만 문제는 redirect 처리를 어떻게 해야 하는지 잘 모르겠네요.인가서버에 임시코드 요청 시 json 응답으로 code를 주고 redirect 없시 다시 인가서버로 access token을 요청하는 방식으로 구현해야 하는지요?질문하면서도 authorization code 부여 방식에서 이렇게 구현을 하는게 맞는지? 의문이 드네요..이런 REST API OAuth2 인가서버라는게 표준 spec에 맞는지도 의문이고..모바일에서 REST API 방식으로 요청하고 인가서버에서 json 형태의 응답이 표준 spec 이랑 안 맞는 것 같기도 하고.. 무조건 html 웹 페이지 형태의 응답 기반으로 구현해야 하는지요? 여기에는 resource owner password 방식이 딱 맞는 것 같긴 한데 Deprecated 되어서 구현하면 안될 것 같고. 일반적으로 어떻게 구현하는지 알고 싶네요. 이런 케이스가 있는지요?어떻게 하면 좋을지 선생님 의견을 듣고 싶네요..감사합니다. ps 질문2. 클라이언 서버, 리소스서버로 딱딱 나누지 않고, 클라이언트 서버를 리소스서버 형태로 구현해서.. 사용자 인증 방식을 form login이 아닌 JwtDecoder 방식으로 인증 처리하여 클라이언트 서버가 서비스 정보를 주는 형태로 구현해도 되는지요?
-
해결됨실무 환경 그대로 주문게시판 만들기 웹개발 기초 마스터
주문 등록 및 주문 수정 그리드 업데이트 관련 문의드립니다.(3차 문의)
안녕하세요. 우선 연이어 질문 드려서 정말 죄송합니다. 어제 문의드렸던 내용 안내해주신대로 수정 팝업에 대한 함수 만들어서 구현해보았는데 여전히 수정 후, 게시판 메인화면에 조회버튼을 재클릭해야 수정사항이 반영되고 있습니다. 해결책이 마땅치 않아 재차 관련 내용 문의드리며, OB_001.xfdl l코드 블록 참조하여 문의 드립니다.아직 응용하기에 벅찬 부분이 있어 주문 수정과 함께 주문 등록도 같이 안내해주시면 정말 감사하겠습니다.재차 문의드려 번거롭게 해드려 죄송합니다. 이왕 시작한 것 꼭 구현해보고자 해서 문의드립니다.답변 주시면 정말 감사하겠습니다.감사합니다.(혹시 몰라 OB_001_01.xfdl과 OB_001_02.xfdl 코드블록도 참조드리겠습니다. 글자 수 제한 때매 다음 게시글에 첨부드리니 참조 해주시면 감사하겠습니다.) this.OB_001_onload = function(obj:nexacro.Form,e:nexacro.LoadEventInfo) { //alert("onload 함수 실행"); //OB_001.xfml 화면이 로드될 때, 검색 조건의 주문상태 콤보박스를 초기화 시킨다. //서버에 요청을 하기전에 서버에 전달해줘야할 인자값은 뭐가 있을지 생각해봐야 한다. //주문상태값만을 불러오기 위해선 TB_CD_MST 테이블의 WHERE절에 CD_VAL = '001'이라는 조건을 걸어줘야 한다. //따라서 DATASET에 001이라는 값을 넣어 서버로 전달 //ds_searchCombo 데이터셋을 생성하고 서버로 전달할 인자값 추가. this.ds_searchCombo.clearData();//데이터셋을 초기화 this.ds_searchCombo.addRow();//초기화한 데이터셋에 값을 세팅하기 위해 한줄을 추가 this.ds_searchCombo.setColumn(0,"CD_VAL","001");//추가된 0번째 ROW의 CD_VAL 컬럼에 001이라는 값을 추가 //서버로 데이터 전송 //서버로 데이터를 전송하기 전 필요한 값 세팅 var strSvcId = "selectCommonCode"; //넥사크로에서 트랜잭션을 구분하기 위한 id값, 이 id값은 차후 fncallback함수에 쓰인다. var strSvcUrl = "selectCommonCode.do"; //java Controller에서 요청을 처리 var inData = "ds_search=ds_searchCombo"; //서버로 전송할 데이터셋을 세팅 = 문자 기준으로 왼쪽이 서버, 오른쪽이 프론트 데이터셋 //서버측(.java)에도 = 기준 왼쪽 데이터셋명(ds_search)과 반드시 동일하게 명명해야한다. var outData = "ds_ordStatCombo=ds_commonCode"; //서버로부터 값을 전달받을 데이터셋을 세팅, inData와는 반대로 = 문자 기준으로 왼쪽이 프론트, 오른쪽이 서버 데이터셋 //서버측(.java)에서도 = 기준 오른쪽 데이터셋명(ds_commonCode)와 동일한 이름 사용해야함. var strAvg = ""; //데이터셋이 아닌 값을 보낼 때 쓰는 필드지만 데이터셋을 쓰는 것으로 통일 var callBackFnc = "fnCallback"; //서버로부터 값을 받은 이후 프론트에서 이행해야할 작업 코드를 fnCallback 함수에서 작성 this.gfnTransaction(strSvcId ,strSvcUrl ,inData ,outData ,strAvg ,callBackFnc); }; this.fn_search = function(nPageNo) { //alert("주문리스트 조회"); //1. 조회 버튼을 클릭했을 때, 우리는 db에서 데이터를 조회하여 값을 그리드에 뿌려줘야 한다. //프론트에서 값들을 데이터셋에 생성해서 서버로 보내줘야 한다. //검색조건에 있는 5개 조회 요건들의 맞게 값들을 담아서 서버로 보내줘야 한다. //값들을 주문 리스트 조회 시 where절에 넣어줘야 조건에 알맞은 데이터를 가져올 수 있다. //1. 따라서, 검색 조건들을 ds_searchList라는 데이터셋을 만들어서 값을 세팅하는 작업을 수행해야 한다. //2. 서버에서 가져온 주문리스트를 화면단에 그리드에 보여줘야 한다. // 만들어놓은 그리드 뼈대에 서버에서 보내준 결과인 ds_list 데이터셋을 만들어 바인딩한다. // 바인딩함으로써 그리드가 서버로부터 가져오는 ds_list값을 보여주도록 만든다. //3. this.gfnTransaction 함수를 통해 서버로 데이터를 전송하고 받는 작업 수행 this.ds_searchList.clearData();//ds_searchList 데이터셋 초기화 this.ds_searchList.addRow();//초기화한 데이터셋에 데이터 세팅할 ROW추가 // column별 데이터 추가 // 데이터를 추가하기 위해서 set으로 세팅한다. this.ds_searchList.setColumn(0,"ORD_NO",this.edt_ordNo.value); this.ds_searchList.setColumn(0,"CUST_NM",this.edt_custNm.value); this.ds_searchList.setColumn(0,"COMP_YN",this.chk_cmpYn.value); this.ds_searchList.setColumn(0,"ORD_STAT_CD",this.cbo_ordStat.value); this.ds_searchList.setColumn(0,"CUST_GBCD",this.rdo_custGb.value); trace("ds_searchList::::::: 조회 버튼 클릭시 로그 확인 :::::::::::::::::::::::::"); trace("ORD_NO :" + this.ds_searchList.getColumn(0,"ORD_NO")); trace("CUST_NM :" + this.ds_searchList.getColumn(0,"CUST_NM")); trace("COMP_YN :" + this.ds_searchList.getColumn(0,"COMP_YN")); trace("ORD_STAT_CD :" + this.ds_searchList.getColumn(0,"ORD_STAT_CD")); trace("CUST_GBCD :" + this.ds_searchList.getColumn(0,"CUST_GBCD")); var strSvcId = "selectOrdList"; //넥사크로에서 트랜잭션을 구분하기 위한 id값, 이 id값은 차후 fncallback함수에 쓰인다. var strSvcUrl = "selectOrdList.do"; //java Controller에서 요청을 처리 var inData = "ds_searchList=ds_searchList"; //서버로 전송할 데이터셋을 세팅 = 문자 기준으로 왼쪽이 서버, 오른쪽이 프론트 데이터셋 //서버측(.java)에도 = 기준 왼쪽 데이터셋명(ds_search)과 반드시 동일하게 명명해야한다. var outData = "ds_list=ds_list"; //서버로부터 값을 전달받을 데이터셋을 세팅, inData와는 반대로 = 문자 기준으로 왼쪽이 프론트, 오른쪽이 서버 데이터셋 //서버측(.java)에서도 = 기준 오른쪽 데이터셋명(ds_commonCode)와 동일한 이름 사용해야함. var strAvg = ""; //데이터셋이 아닌 값을 보낼 때 쓰는 필드지만 데이터셋을 쓰는 것으로 통일 var callBackFnc = "fnCallback"; //서버로부터 값을 받은 이후 프론트에서 이행해야할 작업 코드를 fnCallback 함수에서 작성 this.gfnTransaction(strSvcId ,strSvcUrl ,inData ,outData ,strAvg ,callBackFnc); } this.btn_selectOrd_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo) { this.fn_search(); }; this.btn_regOrd_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo) { //alert("주문 등록 팝업 오픈"); var oArg = {}; var oOption = {}; var sPopupCallBack = "fnPopupCallback"; this.gfnOpenPopup("popup","Board::OB_001_01.xfdl",oArg,sPopupCallBack,oOption); }; this.btn_updOrd_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo) { //alert("주문 수정 팝업 오픈"); var ordNo = this.ds_list.getColumn(this.ds_list.rowposition,"ORD_NO"); var oArg = {ordNo:ordNo}; var oOption = {}; var sPopupCallBack = "fnPopupCallback"; this.gfnOpenPopup("popup","Board::OB_001_02.xfdl",oArg,sPopupCallBack,oOption); }; this.btn_delOrd_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo) { //alert("주문 삭제 진행"); var ordNo = this.ds_list.getColumn(this.ds_list.rowposition,"ORD_NO"); //확인창 띄우기 var confirmResult = this.confirm("주문을 삭제하시겠습니까?"); if (confirmResult){ this.ds_delList.clearData(); this.ds_delList.addRow(); this.ds_delList.setColumn(0,"ORD_NO",ordNo); //서버로 deleteOrdList.do 라는 URL 요청에 ds_delList값을 담아 전송 var strSvcId = "deleteOrdList"; //넥사크로에서 트랜잭션을 구분하기 위한 id값, 이 id값은 차후 fncallback함수에 쓰인다. var strSvcUrl = "deleteOrdList.do"; //java Controller에서 요청을 처리 var inData = "ds_delList=ds_delList"; //서버로 전송할 데이터셋을 세팅 = 문자 기준으로 왼쪽이 서버, 오른쪽이 프론트 데이터셋 //서버측(.java)에도 = 기준 왼쪽 데이터셋명(ds_search)과 반드시 동일하게 명명해야한다. var outData = ""; //서버로부터 값을 전달받을 데이터셋을 세팅, inData와는 반대로 = 문자 기준으로 왼쪽이 프론트, 오른쪽이 서버 데이터셋 //서버측(.java)에서도 = 기준 오른쪽 데이터셋명(ds_commonCode)와 동일한 이름 사용해야함. var strAvg = ""; //데이터셋이 아닌 값을 보낼 때 쓰는 필드지만 데이터셋을 쓰는 것으로 통일 var callBackFnc = "fnCallback"; //서버로부터 값을 받은 이후 프론트에서 이행해야할 작업 코드를 fnCallback 함수에서 작성 this.gfnTransaction(strSvcId ,strSvcUrl ,inData ,outData ,strAvg ,callBackFnc); } }; this.grd_ordList_oncelldblclick = function(obj:nexacro.Grid,e:nexacro.GridClickEventInfo) { //그리드 셀 더블 클릭시 실행 }; this.chk_cnpYn_onchanged = function(obj:nexacro.CheckBox,e:nexacro.CheckBoxChangedEventInfo) { //alert("onchanged 함수 실행"); }; this.grd_ordList_onheadclick = function(obj:nexacro.Grid,e:nexacro.GridClickEventInfo) { //아래 속성에서 0은 그리드에서 0번째 column을 의미하며, text값을 가져오라는 의미 var chkVal = obj.getCellProperty("head", 0, "text"); // 0이면 체크 안된 상태이고 1이면 체크된 상태 if(chkVal == "1"){ // 이미 체크된 상태라면 체크 해지로 변환 chkVal = "0"; obj.setCellProperty("head", 0, "text", chkVal); // 프론트에 적용(HEAD 부분) for (var i=0; i<this.ds_list.rowcount; i++) { // 프론트에 적용(ROW 부분) this.ds_list.setColumn(i,"CHK","0"); } }else{ chkVal = "1"; // 체크 안 된 상태라면 체크 표시 obj.setCellProperty("head", 0, "text", chkVal); // 프론트에 적용(HEAD 부분) for(var i=0; i<this.ds_list.rowcount; i++){ // 프론트에 적용(ROW 부분) this.ds_list.setColumn(i,"CHK","1"); } } }; /******************************************************************************************* * CallbackFunction (서버수신 후 후처리 영역) ********************************************************************************************/ this.fnCallback = function(svcID, errorCode, errorMsg) { if(errorCode < 0){ alert("작업 실패 코드: " + errorCode + "\n" + errorMsg) return 0; } switch(svcID) { case "selectCommonCode" : this.ds_ordStatCombo.insertRow(0);//0번째 ROW에 라인 삽입 this.ds_ordStatCombo.setColumn(0,"CD_VAL1",""); this.ds_ordStatCombo.setColumn(0,"CD_NM1","전체"); break; case "deleteOrdList" : alert("주문 삭제 완료 되었습니다."); //조회버튼을 누르는 동작 this.fn_search(); break; } }; this.fnPopupCallback = function (strId, strVal) { trace("strId :" + strId + "strVal :" + strVal); switch(strId) { case "updatePopup" : this.fn_search(); break; } };
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
@JsonIgnore
@JsonIgnore의 위치는 양방향 연관관계 중 아무곳이나 적어줘도 되는 건가요??
-
미해결스프링 시큐리티 OAuth2
backchannel에 대해서
안녕하세요 섬세하고 친절한 강의 잘 듣고 있습니다.다름이 아니라 백채널과 프론트채널이 있는데백채널은 어떤 암호화기법이 추가로 있는 통신망을 뜻하는건지요?구체적인 차이점을 알고 싶습니다.감사합니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
MemberServiceIntegrationTest.java를 다 만들었는데 항상 이 문구만 떠요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. Expected java.lang.IllegalStateException to be thrown, but nothing was thrown 이게 문제인가요?이게 문제인가요? 중복처리에서 걸려야 하는데 안 걸려요
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
findByName 질문있습니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]findById의 리턴 값은 Optonal.ofNullable을 사용해서 값을 반환하는데findByName의 리턴 값은 왜 Optoinal.ofNullable을 사용하지 않나요?
-
해결됨
인터페이스 구현 문제
데이터베이스 연동해서 db의 데이터를 조회하고 싶은데 문제가 있어서 질문드립니다.MemberRepository(인터페이스)package com.project.web.repository; import com.project.web.domain.Member; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; import java.util.Optional; public interface MemberRepository extends JpaRepository<Member,Long>{ Optional<Member> findByIdAndPw(String id, String pw); } JpaMemberRespositorypackage com.project.web.repository; import com.project.web.domain.Member; import org.springframework.data.domain.Example; import org.springframework.stereotype.Repository; import javax.persistence.EntityManager; import javax.transaction.Transactional; import java.util.Optional; public class JpaMemberRepository implements MemberRepository { private final EntityManager em; public JpaMemberRepository(EntityManager em) { this.em = em; } @Override Optional<Member> findByIdAndPw(String id, String pw){ return null; }; } 이렇게 작성했는데 Class 'JpaMemberRepository' must either be declared abstract or implement abstract method 'findAll()' in 'JpaRepository이런 오류가 뜹니다. 함수를 implements하라는건 알겠는데 이렇게 많은 함수를 오버라이딩 하라고 뜨네요.. 제가 인터페이스에 작성한 내용만 작성하고 싶은데 뭐가 문제 일까요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
form프로젝트 import에러 해결했어요! 도움되시라고 작성해보았습니다~
안녕하세요.오늘 수업자료 다운로드 후 form-start파일을 form으로 프로젝트명 변경 하고 에러나는 부분때문에 2시간을 막연하게 보내고 구글링 + 인프런에 있는 수강자분들의 질문과 공식서포터즈 님들의 해결방법 작성해놓은것들 그대로 셋팅해봐도 안되었던 문제를 해결했어요.해결방법 공유를 위해 작성했습니다! (질문아니예요ㅠ)저는 설정하면서 총 3개의 문제를 겪음 ㅠ제가 겪고 해결한 부분이 도움될 분들이 계실거라 생각하고 몇자 적어봅니다. (사실 좀 길어요ㅠ 그래도 제가 버린시간을 다른분들께선 알차게 쓰시길 바라는 마음으로 작성중) [진행 및 문제를 확인]프로젝트를 import 한후 build.gradle 파일을 열어서 gradle 7버전 이상, java는 17로 사용하는 것으로 설정완료.이후 윈도우에서 인텔리제이를 사용하고 있어서 setting 접속한 후 해당설정 화면에서 gradle버전을 PC에 7.4버전이 설치되어 있는 경로로 설정, 그리고 자바도 17버전으로 설정을 해줍니다. refrash하는데 에러...저는 gardle 7.4-all버전을 사용하려고 설정을 모두 gradle설정하는부분은 7.4버전대로 설정했는데 뜬금없이 console에 나타난 에러메세지는 gradle을 gradle-6.8.2-bin.zip 로 설정되어있어서 안된다고 나오더라구요.에러메세지 : Unsupported Java.Your build is currently configured to use Java 17.0.4 and Gradle 6.8.2. [원인]분명히 setting > gradle 메뉴에가서 gradle을 7버전 사용한다고 설정했는데...뭐가 문제지? 싶어서 구글링해도 뭐해도 다 해봤던 설정만 나와서 답답하더라구요.그래서 그냥 우선 gradle관련 설정파일을 하나하나 확인해봐야겠다는 마음으로 gradle설정파일을 확인하는데 그중 gardle-wrapper.properties 파일에 문제가 있음을 확인사실 설정관련 정보는 저도 잘 몰라요.. 그런데 확실하게 알수 있었던건 distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip이 부분으로 인해 프로젝트가 gradle을 다른버전을 사용하도록 설정되어 있는걸 알게됨. [문제1 해결방법]1. form > gradle > wrapper > gradle-wrapper.properties 파일을 클릭해서 오픈2. distributionUrl에 있는 설정정보를 gradle을 7버전 이상으로 설정값을 변경그런데 저는 다른정보도 변경해줘야 할것 같아서 이전에 타임리프 프로젝트에서 설정되어있는 gradle-wrapper.properties 파일의 정보를 그대로 복붙했어요.(저는 여기서 gradle-8.5-bin.zip으로 설정되어있어서 그냥 그거 설정함)distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists 3. gradle refresh [문제2 또 에러 (자바9버전 이상에서 제공되지 않는 어노테이션 문제)그런데 refresh 한 후 여기까지 하고 또 에러가 납니다.프로젝트에 자바9버전이상에서 그냥 사용할 수 없는 어노테이션이 있나봐요. 영한님이 이전 servlet강의에서 말씀해주셨던 자바8인가? 9이상부터 제공되지 않는 어노테이션들이 자바 17버전에서 제공되지 않는 문제..사용하도록 설정해야되니까 관련 코드를 찾아서 dependencies에 추가해주는걸로 해결했어요.에러메세지 : path~~~~\dev\05_스프링mvc2-백엔드웹개발활용기술\form\src\main\java\hello\itemservice\TestDataInit.java:8: error: package javax.annotation does not existimport javax.annotation.PostConstruct;^ [문제2 해결방법]1.build.gradle 파일열기2. dependencies에 아래의 코드 추가implementation group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'3. gradle refresh [문제3 또 에러]문제1, 문제2 까지 겪고 해결방법대로 설정완료 후 잘되나 싶더만 아래의 에러메세지가 나타납니다.프로젝트가 빌드될때 java11이 사용되도록 설정이 되어있어서 발생된것 같아 17로 변경해줍니다.에러메세지 : * What went wrong: Execution failed for task ':ItemServiceApplication.main()'.> Process 'command 'C:\Program Files\Java\jdk-11.0.17\bin\java.exe'' finished with non-zero exit value 1 [문제3 해결방법]1. 우측상단 select Run/debug configuration 박스클릭2. Edit Configurations 클릭3. Run/Debug Configurations 설정 창에서 java version 7로 변경 이후 프로젝트가 잘 구동되어 강의 듣을수 있게 되었습니다 ㅋㅋㅋ 으..말주변 없어서 이거 작성하느냐고 1시간 걸림 ㅠㅠ 설명이랑 같이 작성하느냐고 두서없을수 있으나..한가지라도 도움되시길 바라면서 마침! ps. 프로젝트의 설정파일 정보가 변경되었으면 좋겠습니다!프로젝트를 다운받고 안되는 부분이 초보입장에선 동공에 지진이... 좋은강의 늘 감사합니다:)
-
미해결스프링 핵심 원리 - 기본편
OCP 개방-폐쇄 원칙에 관해
OCP 개방 -폐쇄 원칙확장에는 열려있으나 변경에는 닫혀 있어야 한다.-> 인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현그러면 소수의 메서드를 수정하고 싶은 경우, 본래 있던 클래스의 수정하지 않을 메서드들을 호출하여 사용해도 될까요?
-
미해결스프링 핵심 원리 - 기본편
이클립스 프로젝트 실행 시 오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]1. 이클립스에서 Ctrl + F11 누르고 실행했는데 다음과 같이 뜨는게 맞나요...2. 저는 영한님과 다르게 Exit Code 0 이 Console 창에 뜨지 않는데 상관없을까요
-
해결됨쥬쥬와 함께 하루만에 끝내는 스프링 테스트
Kafka테스트 다른 테스트랑 같이 돌리면 실패하는데 이유를 모르겠습니다..
예시 코드대로 카프카 테스트를 실행하면 잘 성공합니다. 그런데 다른 통합테스트들과 같이 실행시키면 실패합니다.로그를 보면잘 실행되고 문제도 없는데 process메서드를 잘 실행 했음에도 불구하고 수행되지 않았다고 나오는거 같습니다. @SlowTest public void kafkaSendAndConsumeTest() { String topic = "test-topic"; String expectValue = "expect-value"; kafkaProducerService.send(topic, expectValue); var stringCaptor = ArgumentCaptor.forClass(String.class); System.out.println("-----------mock-----------start"); Mockito.verify(kafkaConsumerService, Mockito.timeout(5000).times(1)) .process(stringCaptor.capture()); System.out.println("-----------mock-----------finish"); Assertions.assertEquals(expectValue, stringCaptor.getValue()); }혹시 관련 문제에 대해 아실까요? ㅠㅠ
-
미해결스프링 핵심 원리 - 기본편
AnnotationConfigApplicationContext(appconfig.class, DiscountService.class)
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]강의 3: 42초쯤에 스프링 컨테이너를 생성하여appconfig.class 도 함께 넣어주는데 이미 다른 테스트ex) AutoAppconfigTest같은 곳에서 빈으로 등록해주었는데 또 컨테이너 안에다가appconfig.class 를 빈으로 등록해주면 충돌이 나야할것같은데 잘 이해가 가지 않아서요!!1.혹시 테스트별로 컨테이너가 "독립적으로" 생겨서 다른 테스트와는 별도의 컨테이너로 여겨져서 그런것일까요?이유를 설명해주시면 감사하겠습니다!!^^1.혹시 테스트별로 컨테이너가 "독립적으로" 생겨서 다른 테스트와는 별도의 컨테이너로 여겨져서 그런것일까요?의존 관계 주입으로 @Autowired 를 쓰면 자동으로 이미 등록된 appconfig.class 의 discountPolicy 타입의 빈들을 불러올 수 있지 않을까요? 현재 지금까지 강의 들었을때 저번에 @Test basic scan() 으로 만들었던 컨테이너입니다. 여기다가 빈으로 자동 등록이 됐는데 또 다른테스트에서 만들어도 상관없는것인지위의 2개 이유를 들어 여쭤봅니다!!//-----------------------------------------------------제가 알기론 스프링 컨테이는 하나만 생성되는것으로 알고있는데 위배되는것이 아닌가 해서요!=>만약에 2개 이상 생성이 가능하다고 한다면 각 컨테이너에 동일한 빈들이 똑같이 들어가게 돼도 "컨테이너참조값이 다르기 때문에" 빈 중복 등록이 아닌것이 되나요?
-
미해결스프링 핵심 원리 - 고급편
http://localhost:8080/v0/request?itemId=hello 실행 시 에러
1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]예제 프로젝트 만들기에서 http://localhost:8080/v0/request?itemId=hello실행 시에 java.lang.IllegalArgumentException: Name for argument of type [java.lang.String] not specified, and parameter name information not found in class file either.이런 에러가 뜹니다.소스는 하도 안되서 다 복붙 해봤는데도 안됩니다.자바 17에 스프링부트 3.2.0 버전입니다.
-
미해결스프링 핵심 원리 - 기본편
강의 내용 질문입니다.
여기서 Map에다가 member 정보를 넣은 이유랑, private static으로 선언한 이유가 뭔지 궁금합니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
멀티스레드 동시성 문제
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]재고 감소 증가 로직은 멀티 스레드에 안전한가요? synchronized 키워드를 붙여야 안전할까요?
-
미해결스프링 핵심 원리 - 기본편
빈으로 등록하지 않았는데 @Autowired를 통해 의존성 주입할 때 충돌이 납니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요 @Autowired를 사용해 의존성 주입을 하다 충돌이 나서 질문드립니다.MemberRepository인터페이스 -> MemoryMemberRepository 구현체후자에만 @Component를 붙인 상황입니다.그런데Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'memberServiceImpl' defined in file [/Users/minsung/Desktop/study/core/out/production/classes/hello/core/member/MemberServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'hello.core.member.MemberRepository' available: expected single matching bean but found 2: memoryMemberRepository,memberRepository이런식으로 memberRepository 또한 빈으로 등록되어 있었습니다.@Autowired가 클래스 타입으로 조회한다는 것은 알고 있지만 빈으로 등록되어있는 애들 중에서 조회하는 것 아닌가요...?왜 memberRepository를 빈으로 등록하지 않았는데 빈으로 등록되어있는지@Autowired는 왜 빈으로 등록되지도 않은 memberRepository를 찾을 수 있었는지@Autowired 보다는 @RequiredArgsConstructor 사용을 권장하던데 이제 @Autowired는 잘 쓰이지 않는 것인지궁금합니다!
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
스프링 예외처리-필터 강의 질문
안녕하세요 localhost:8080/error-ex 호출로 임의로 RuntimeException 발생 시 에러 처리 로그 관련해서 질문 남깁니다.https://ballistic-uncle-12b.notion.site/eb9d5a1ee6e74d6db70c0658241aa8b1?pvs=4java.lang.RuntimeException: 예외발생 !!! ~~ 로그가 두 번 남겨져서 Exception이 2번 발생하는 지 확인하려고, Exception 발생이 두 번 남겨지는 지 확인하기 위해 “Error occurs” 는 로그 메시지를 추가했으나 위 로그 내용과 같이 Exception은 한 번만 던져졌습니다.흐름 상 최초 요청 시 /error-ex 를 통해 was -> 필터 -> 서블릿 -> 컨트롤러/error-ex: (예외발생)* was** <- 필터 <- 서블릿 <- 컨트롤러해당 Exception에 매핑된 요청 url 탐색(/error-page/500)탐색된 url(/error-page/500)로 다시 요청 was -> 필터 -> 서블릿 -> 컨트롤러/error-page/500 was <- 필터 <- 서블릿 <- 컨트롤러위 요청 흐름 상이나 개인적으로 추가한 “Error occurs” 로그에서도 확인한 것처럼 Exception은 * 시점에 1회 발생합니다.시점에서, java RuntimeException이라 java main thread의 최상단 함수(main)에서 해당 Exception에 대한 로그가 찍힌 것으로 생각되는데, RuntimeException에 관한 로그는 왜 2번 적히는지 궁금합니다.아울러 main 함수가 ** 시점에 존재하는 게 맞는지도 추가로 궁금하여서 질문 남깁니다.감사합니다.
-
해결됨실무 환경 그대로 주문게시판 만들기 웹개발 기초 마스터
주문 등록 및 주문 수정 그리드 업데이트 관련 문의드립니다.(2차 문의)
안녕하십니까. 우선 어제 문의드린 사항 친절히 답변주셔서 진심으로 감사드립니다. 도움 주신 덕분에 주문삭제 버튼 클릭시 바로 그리드에 반영되어 조회버튼 재클릭 없이 그리드 리스트에서 삭제 되는 부분과 체크박스 및 전체선택, 전체해제하는 부분까지 구현 하였습니다.도움주셔서 정말 감사드립니다. 다만, 주문 등록과 주문 수정은 주문삭제와 다르게 팝업창에서 진행되다보니 주문 삭제와 동일한 방식으로 아무리 해봐도 주문 삭제 버튼 클릭할 때와 다르게 그리드에 바로 적용되지 않고 조회버튼을 재클릭해야 그리드에 변경사항이 반영되는 상황인데 주문 등록과 주문 수정과 관련하여 어떻게 구현해야될지 재차 문의드립니다. 두 가지(주문 등록 및 주문수정 후 조회버튼 재클릭 없이 그리드리스트 업데이트 내용 바로 반영 구현) 관련하여 좀 더 상세히 설명해주시면 정말 감사하겠습니다..! 감사합니다.