inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

173만명의 커뮤니티!! 함께 토론해봐요.

이미지가 안보입니다...ㅠ(도움이 필요합니다!! 꼭 봐주세요!)

미해결

애플 웹사이트 인터랙션 클론!

안녕하세요 선생님 강의 잘 듣고 있습니다! 다름이 아니라 밑에 수강생분 처럼 저도 이미지가 안보이고 Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLCanvasElement or HTMLImageElement or HTMLVideoElement or ImageBitmap or OffscreenCanvas or SVGImageElement or VideoFrame)'. 이런 에러가 계속 뜨는데.. 어떻게 해야할지 모르겠습니다..ㅠㅠㅠ 분명 계속 이미지 경로도 확인하고 문제가 없는거같은데...대체 뭐가 문제인지 도움이 필요합니다..!! 너무 해결이 안되니까 꼭...해결하고싶습니다.. 잘되던 텍스트 애니메이션도 작동이 안됩니다. 보니까 playanimaion함수에서 sequence도 console.log에 찍으면 undefined로 찍히는데 도저히 뭐가 잘못 됐는지 모르겠습니다. 선생님이 주신 완성 코드를 대입해도 안뜨네요ㅠㅠㅠ (() => { let yOffset = 0; // window.pageYOffset대신 쓸 변수 let prevScrollHeight = 0; //현재 스크롤 위치(yOffset)보다 이전에 위치한 스크롤 섹션들의 높이값의 합 let currentScene = 0; //현재 활성화된(눈 앞에 보고있는) 씬(scroll-section) // sceneInfo는 애니메이션을 처리하는 정보를 담아놓는 변수 let enterNewScene = false;//새로운 scene이 시작되는 순간 true로 바뀜 const sceneInfo = [ { //0 type: 'sticky', heightNum:5,//브라우저 높이의 5배로 scrollHeight 세팅 scrollHeight: 0, // 애니메이션을 조작할 오브젝트를 objs에 담음 objs:{ container: document.querySelector('#scroll-section-0'), messageA: document.querySelector('#scroll-section-0 .main-message.a'), messageB: document.querySelector('#scroll-section-0 .main-message.b'), messageC: document.querySelector('#scroll-section-0 .main-message.c'), messageD: document.querySelector('#scroll-section-0 .main-message.d'), canvas: document.querySelector('#video-canvas-0'), //context객체의 메서드인 getContext를 인자 2d를 넣어 호출해 그림을 그려주는 기초를 연다. context: document.querySelector('#video-canvas-0').getContext('2d'), //비디오 이미지를 배열에 넣을 예정이다. videoImages: [] }, //오브젝트를 어느시점에 보이고 안보이게 할지를 담을 곳 css제어 //시작값 :0 끝값 :1 values: { videoImageCount: 300, //스크롤에 따른 이미지 순서의 [초기값,최종값] messageA와 다르게 섹션의 부분에서 실행될 이미지가 아닌 한스크롤에서 쭉 이어지므로 start,end구간이 필요없다 imageSequence:[0 , 299], messageA_opacity_in: [0, 1, { start: 0.1, end: 0.2 }], messageB_opacity_in: [0, 1, { start: 0.3, end: 0.4 }], //30%~ 40% messageC_opacity_in: [0, 1, { start: 0.5, end: 0.6 }], messageD_opacity_in: [0, 1, { start: 0.7, end: 0.8 }], // 글자를 20%에서 0으로 가는건데 %는 css에 나중에 작업할 예정 세번째 인수에는 타이밍이 들어간다(=어느 타이밍에 효과를 줄것인가) messageA_translateY_in: [20, 0, { start: 0.1, end: 0.2 }], messageB_translateY_in: [20, 0, { start: 0.3, end: 0.4 }], messageC_translateY_in: [20, 0, { start: 0.5, end: 0.6 }], messageD_translateY_in: [20, 0, { start: 0.7, end: 0.8 }], messageA_opacity_out: [1, 0, { start: 0.25, end: 0.3 }], messageB_opacity_out: [1, 0, { start: 0.45, end: 0.5 }], messageC_opacity_out: [1, 0, { start: 0.65, end: 0.7 }], messageD_opacity_out: [1, 0, { start: 0.85, end: 0.9 }], messageA_translateY_out: [0, -20, { start: 0.25, end: 0.3 }], messageB_translateY_out: [0, -20, { start: 0.45, end: 0.5 }], messageC_translateY_out: [0, -20, { start: 0.65, end: 0.7 }], messageD_translateY_out: [0, -20, { start: 0.85, end: 0.9 }] // messageA_opacity:[200,900] } }, { //1 type: 'normal', //heightNum은 scrollHeight를 결정할 때 innerheight의 몇배로 할지 정해주는 수 였는데 normal은 원래 본인 default높이로 설정하므로 필요가 없다 // heightNum:5, scrollHeight: 0, objs:{ container: document.querySelector('#scroll-section-1') } }, { //2 type: 'sticky', heightNum:5, scrollHeight: 0, objs:{ container: document.querySelector('#scroll-section-2'), messageA: document.querySelector('#scroll-section-2 .a'), messageB: document.querySelector('#scroll-section-2 .b'), messageC: document.querySelector('#scroll-section-2 .c'), pinB: document.querySelector('#scroll-section-2 .b .pin'), pinC: document.querySelector('#scroll-section-2 .c .pin') }, values: { messageA_translateY_in: [20, 0, { start: 0.15, end: 0.2 }], messageB_translateY_in: [30, 0, { start: 0.5, end: 0.55 }], messageC_translateY_in: [30, 0, { start: 0.72, end: 0.77 }], messageA_opacity_in: [0, 1, { start: 0.15, end: 0.2 }], messageB_opacity_in: [0, 1, { start: 0.5, end: 0.55 }], messageC_opacity_in: [0, 1, { start: 0.72, end: 0.77 }], messageA_translateY_out: [0, -20, { start: 0.3, end: 0.35 }], messageB_translateY_out: [0, -20, { start: 0.58, end: 0.63 }], messageC_translateY_out: [0, -20, { start: 0.85, end: 0.9 }], messageA_opacity_out: [1, 0, { start: 0.3, end: 0.35 }], messageB_opacity_out: [1, 0, { start: 0.58, end: 0.63 }], messageC_opacity_out: [1, 0, { start: 0.85, end: 0.9 }], pinB_scaleY: [0.5, 1, { start: 0.5, end: 0.55 }], pinC_scaleY: [0.5, 1, { start: 0.72, end: 0.77 }], pinB_opacity_in: [0, 1, { start: 0.5, end: 0.55 }], pinC_opacity_in: [0, 1, { start: 0.72, end: 0.77 }], pinB_opacity_out: [1, 0, { start: 0.58, end: 0.63 }], pinC_opacity_out: [1, 0, { start: 0.85, end: 0.9 }] } }, { //3 type: 'sticky', heightNum:5, scrollHeight: 0, objs:{ container: document.querySelector('#scroll-section-3') } } ]; function setCanvasImages() { let imgElem; for (let i = 0; i < sceneInfo[0].values.videoImageCount; i++){ //이미지 객체가 만들어짐 new Image(); 대신에 document.createElement('img')랑 같은말이다. imgElem = new Image(); imgElem.src = `./video/001/IMG_${6726 + i}.JPG`; sceneInfo[0].objs.videoImages.push(imgElem); } } setCanvasImages(); function setLayout() { //각 스크롤 섹션의 높이 세팅 for (let i = 0; i < sceneInfo.length; i++){ if (sceneInfo[i].type === 'sticky') { sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight; } else if (sceneInfo[i].type === 'normal') { //container본연의 높이로 가져와서 그 크기만큼으로만 normal부분을 설정한다. sceneInfo[i].scrollHeight = sceneInfo[i].objs.container.offsetHeight; } sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px`; } yOffset = window.pageYOffset; let totalScrollHeight = 0; for (let i = 0; i < sceneInfo.length; i++){ totalScrollHeight += sceneInfo[i].scrollHeight; if (totalScrollHeight >= yOffset) { currentScene = i; break; } } // 변수랑 문자열이 섞여있으면 ``을 써야한다. document.body.setAttribute('id', `show-scene-${currentScene}`); // console.log(sceneInfo); //초기화 할 때 실행되는 setLayout은 currentScene이 정해지지 않은 상태에서 currentScene을 구하는 것이고, // 스크롤 할 때마다 실행되는 scrollLoop는 현재 활성화된 currentScene 까지의 스크롤양(prevScrollHeight)을 기준으로 일정량의 스크롤이 지나갔을 때 currentScene을 +1 또는 -1 하는 것이랍니다. } function calcValues(values, currentYOffset) { //여기서 인자 currentYOffset은 현재 씬에서 얼마나 스크롤 됐는지 //현재 섹션에서 얼마나 스크롤 되었는지를 비율로 구한다 스클로의 비율을 0~1사이로 정한다. 비율을 구해서 그 값을 css값에 대입해준다. //yoffset변수는 전체 레이아웃에서 스크롤이 어디 위치해있는지 알려주는 변수이다. 현재 씬에서 스크롤이 얼마나됐는지는 알 수 없다. let rv; const scrollHeight = sceneInfo[currentScene].scrollHeight; //현재 씬(스크롤섹션)에서 스크롤된 범위를 비율로 구하기 ==>let scrollRation = 현재 씬에서 스크롤된 값 / 현재 씬 전체 const scrollRatio = currentYOffset / sceneInfo[currentScene].scrollHeight; if (values.length === 3) { // start~end사이에 애니메이션 실행 const partScrollStart = values[2].start * scrollHeight; const partScrollEnd = values[2].end * scrollHeight; const partScrollHeight = partScrollEnd - partScrollStart; if (currentYOffset >= partScrollStart && currentYOffset <= partScrollEnd) { rv = (currentYOffset - partScrollStart) / partScrollHeight * (values[1] - values[0]) + values[0]; } else if (currentYOffset < partScrollStart) { //스크롤섹션에서 스크롤이 start에 도달하지 못했을 때 rv = values[0]; //opacity가 0이라는 뜻 } else if (currentYOffset > partScrollEnd) { //스크롤섹션에서 스크롤이 end를 완전히 벗어났을 때 rv = values[1]; //opacity가 1이라는 뜻 } else { rv = scrollRatio * (values[1] - values[0]) + values[0]; } // rv = parseInt(scrollRatio * (values[1] - values[0]) + values[0]); return rv; } } //애니메이션 함수 function playAnimation() { // 모든 섹션에 애니메이션을 주는 것은 비효율적이므로 switch문을 이용해서 현재 보고있는 섹션의 요소에만 애니메이션을 준다 const objs = sceneInfo[currentScene].objs; const values = sceneInfo[currentScene].values; const currentYOffset = yOffset - prevScrollHeight; const scrollHeight = sceneInfo[currentScene].scrollHeight; const scrollRatio = currentYOffset / sceneInfo[currentScene].scrollHeight; switch (currentScene) { case 0: let sequence = calcValues(values.imageSequence, currentYOffset); objs.context.drawImage(objs.videoImages[sequence], 0, 0); console.log(sequence); if (scrollRatio <= 0.22) { // in objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.42) { // in objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.62) { // in objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.82) { // in objs.messageD.style.opacity = calcValues(values.messageD_opacity_in, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageD.style.opacity = calcValues(values.messageD_opacity_out, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_out, currentYOffset)}%, 0)`; } break; case 2: // console.log('2 play'); if (scrollRatio <= 0.25) { // in objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.57) { // in objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } else { // out objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } if (scrollRatio <= 0.83) { // in objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } else { // out objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } break; case 3: // console.log('3 play'); break; } } // keyframe이란: 애니메이션이 진행중에 변화가 있는 지점을 keyframe이라고 한다. function scrollLoop() { enterNewScene = false; prevScrollHeight = 0;//누적을 막기 위해서 // 현재 보고잇는 section이 몇번째 section인지 판별하려고함 for (let i = 0; i < currentScene; i++){ prevScrollHeight = prevScrollHeight + sceneInfo[i].scrollHeight; } // console.log(prevScrollHeight); if (yOffset > prevScrollHeight + sceneInfo[currentScene].scrollHeight) { enterNewScene = true; currentScene++; document.body.setAttribute('id', `show-scene-${currentScene}`); // setLayout함수에서 이미 id값이 정해져있지만 스크롤에 변함에 따라 체크하는 방식으로 쓴다 } if (yOffset < prevScrollHeight) { if (currentScene === 0) return;//브라우저 바운스 효과로 인해 마이너스가 되는 것을 방지(모바일) enterNewScene = true; currentScene--; document.body.setAttribute('id', `show-scene-${currentScene}`); } // console.log(currentScene); // enterNewScene이 참이라는것은 씬이 바뀌는순간인 것이고 참일때 return, 즉 playAnimation함수를 한타임 실행하지 않는다는것으로 음수값이 무시되고 다시 playAnimation함수가 실행된다. if (enterNewScene) return; playAnimation(); } window.addEventListener('scroll', () => { yOffset = window.pageYOffset; scrollLoop(); }); window.addEventListener('load', setLayout); // window의 모든 문서(html, 이미지, 동영상..)가 완료되고 나서 // 레이아웃 잡는 setLayout함수를 실행한다 // window.addEventListener('DOMContentLoaded', setLayout); //반대로 window의 html구조들만 완료되면 반대로 이미지는 로드되지않아도 setlayout함수를 실행하는것 //인데 load보다는 빨리 setlayout을 실행한다. window.addEventListener('resize', setLayout); // 윈도우가 리사이즈 되었을 때 setLayout을 호출한다 })(); <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>AirMug Pro</title> <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;900&display=swap" rel="stylesheet"> <link rel="stylesheet" href="css/default.css"> <link rel="stylesheet" href="css/main.css"> <script defer src="js/main.js"></script> </head> <body> <div class="container"> <nav class="global-nav"> <div class="global-nav-links"> <a href="#" class="global-nav-item">Rooms</a> <a href="#" class="global-nav-item">Ideas</a> <a href="#" class="global-nav-item">Stores</a> <a href="#" class="global-nav-item">Contact</a> </div> </nav> <nav class="local-nav"> <div class="local-nav-links"> <a href="#" class="product-name">AirMug Pro</a> <a href="#">개요</a> <a href="#">제품사양</a> <a href="#">구입하기</a> </div> </nav> <section class="scroll-section" id="scroll-section-0"> <h1>AirMug Pro</h1> <!-- p태그의 값들을 sticky, 즉 스티커처럼 고정해놓고 스트롤의 값에 따라 보여지도록 p태그를 감싸고 있는 div에 class를 준다. --> <div class="sticky-elem sticky-elem-canvas"> <canvas id ="video-canvas-0" width="1920px" height="1080px"></canvas> </div> <div class="sticky-elem main-message a"> <p>온전히 빠져들게 하는<br>최고급 세라믹</p></div> <div class="sticky-elem main-message b"> <p>주변 맛을 느끼게 해주는<br>주변 맛 허용 모드</p> </div> <div class="sticky-elem main-message c"> <p>온종일 편안한<br>맞춤형 손잡이</p> </div> <div class="sticky-elem main-message d"> <p>새롭게 입가를<br>찾아온 매혹</p> </div> </section> <section class="scroll-section" id="scroll-section-1"> <p class="description"> <strong>보통 스크롤 영역</strong> Lorem ipsum dolor sit amet consectetur adipisicing elit. Quas minus praesentium incidunt tempora repellendus? Laudantium sed excepturi quo nemo quisquam totam, cumque nam sit incidunt, corrupti libero temporibus obcaecati enim facilis dolore itaque minima dolorem sequi explicabo. Modi alias in ullam labore, minima voluptates ipsa ex laborum deleniti tempora incidunt architecto iure aut, molestias ab! Fugiat aliquam veritatis ad voluptatibus, quaerat officia doloribus aliquid nulla repellat quidem rem magni perferendis labore similique reprehenderit aut. Cum quis omnis ex iusto natus iste nisi magnam, nesciunt fugit aspernatur ullam? Temporibus, dolores ipsa. Odit odio aliquam sunt error corporis ab facere, illum sequi! Explicabo nulla, ipsum necessitatibus laboriosam eligendi aspernatur quam nostrum. Debitis est ad, vel in corrupti voluptas laboriosam quo, reiciendis quos quas culpa, atque voluptate tempora tempore quam accusamus ipsa asperiores voluptatibus adipisci non vero aspernatur eum nesciunt quis. A cum, molestiae eaque repellat similique esse eligendi reprehenderit amet omnis minus quae voluptatum delectus dolores repudiandae? Distinctio aut aspernatur, iure nemo, eum soluta error necessitatibus minus voluptatum laborum rem dignissimos quae. Error ut recusandae ullam magnam quas molestiae repellat culpa. Ab nihil sint voluptatum in? Enim suscipit debitis earum culpa sint maxime hic, repudiandae nulla ad error voluptatem fugiat blanditiis odit! </p> </section> <section class="scroll-section" id="scroll-section-2"> <div class="sticky-elem main-message a"> <p> <small>편안한 촉감</small> 입과 하나 되다 </p> </div> <div class="sticky-elem desc-message b"> <p> 편안한 목넘김을 완성하는 디테일한 여러 구성 요소들, 우리는 이를 하나하나 새롭게 살피고 재구성하는 과정을 거쳐 새로운 수준의 머그, AirMug Pro를 만들었습니다. 입에 뭔가 댔다는 감각은 어느새 사라지고 오롯이 당신과 음료만 남게 되죠. </p> <div class="pin"></div> </div> <div class="sticky-elem desc-message c"> <p> 디자인 앤 퀄리티 오브 스웨덴,<br>메이드 인 차이나 </p> <div class="pin"></div> </div> </section> <section class="scroll-section" id="scroll-section-3"> <p class="mid-message"> <strong>Retina 머그</strong><br> 아이디어를 광활하게 펼칠<br> 아름답고 부드러운 음료 공간. </p> <p class="canvas-caption"> Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet at fuga quae perspiciatis veniam impedit et, ratione est optio porro. Incidunt aperiam nemo voluptas odit quisquam harum in mollitia. Incidunt minima iusto in corporis, dolores velit. Autem, sit dolorum inventore a rerum distinctio vero illo magni possimus temporibus dolores neque adipisci, repudiandae repellat. Ducimus accusamus similique quas earum laborum. Autem tempora repellendus asperiores illum ex! Velit ea corporis odit? Ea, incidunt delectus. Sapiente rerum neque error deleniti quis, et, quibusdam, est autem voluptate rem voluptas. Ratione soluta similique harum nihil vel. Quas inventore perferendis iusto explicabo animi eos ratione obcaecati. </p> </section> <footer class="footer"> 2020, 1분코딩 </footer> </div> </body> </html>

  • HTML/CSS
  • 웹 디자인
  • 인터랙티브-웹
  • svg
  • javascript
  • 클론코딩
jayoo8665 댓글 2 좋아요 0 조회수 865

MemberRepository 에서 cannot find symbol 오류

미해결

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 안녕하세요!! 동영상 강의 잘 보고 있습니다. 강의 내용 대로 따라서 하고 있는데 MemberRepository 를 작성하고 나면 cannot find symbol 오류가 발생합니다. 자동으로 import 되는게 강의와 다르게 import java.lang.reflect.Member; 로 되고 있습니다. 동영상 강의에는 import hello.hellospring.domain.Memeber; 되어 있는데 여기에서 오류가 발생하고 있습니다. 어느 부분이 잘못 됐을까요.. package hello.hellospring.repository ; import java.lang.reflect.Member ; import java.util.List ; import java.util.Optional ; public interface MemberRepository { Member save (Member member) ; Optional<Member> findById (Long id) ; Optional<Member> findByName (String name) ; List<Member> findAll () ; }

  • MemberRepository
  • member
  • java
  • MVC
  • spring
  • spring-boot
SSK 댓글 1 좋아요 0 조회수 1516

그림 불러오기

미해결

비전공자를 위한 진짜 입문 올인원 개발 부트캠프

그랩마켓이라는 이미지 불러오기가 안되네요... 어떻게 해야될까요???

  • express
  • tensorflow
  • HTML/CSS
  • nodejs
  • javascript
  • 머신러닝 배워볼래요?
  • react-native
  • react
댓글 1 좋아요 0 조회수 244

Props 강의 관련해서 질문!!

해결됨

한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지

안녕하세요. OddEvenResult 관련 부분 설명 시, 저는 decideodd 라고 했을 때는 인식이 되지 않다가 Decideodd 라고 하게 되면 인식이 되는 모습을 볼 수 있었습니다. 즉. 함수명은 소문자로 시작하면 에러가 발생을 합니다. 관련해서는 무조건 대문자로 시작을 해야하는건가요??

  • javascript
  • react
  • nodejs
이종민 댓글 1 좋아요 0 조회수 299

React alert창 띄운 후 확인 버튼 누르면 값 갱신 안되게 하는 방법ㅠㅠ

미해결

안녕하세요, react로 웹 페이지를 제작 중입니다. 다름이 아니라 3개 이상 선택하면 alert창으로('3개까지만 선택 가능합니다')라고 띄우는 것 까지는 썼는데 이제 확인을 누르면 4개도 다시 클릭이 되더라구요.. 이걸 막는 방법은 뭐가 있을까요..? 관련된 함수랑 코드를 써놓겠습니다..! const [ number , setNumber ] = useState ( 0 ); const increaseNumber = () => { setNumber ( number + 1 ) }; const decreaseNumber = () => { // number의 값을 감소시키는 함수 setNumber ( number - 1 ); }; const over3 =() => { if ( number >= 3 ){ alert ( '3개까지만 선택 가능합니다!' ); } } //onClick에 카운트 세는 함수 설정되어있습니다. < div className = 'movieposter' > { datas . map (( movie , i ) => ( movie . value === true ? < img className = 'img-responsive_clicked' src = "https://movie-phinf.pstatic.net/20220214_120/1644825641315cvVKI_JPEG/movie_image.jpg?type=f125" alt = { i } onClick = { () => { decreaseNumber (); handleClickImage ( i );} } /> : < img className = 'img-responsive' src = 'img/movie_image1.jpg' alt = { i } onClick = { () => { increaseNumber (); handleClickImage ( i ); over3 ()} } /> )) } </ div >

  • react
  • reactjs
  • 웹페이지
  • 프론트엔드
namuneulbo 댓글 1 좋아요 0 조회수 3179

csrf 토큰 과 jwt 토큰

미해결

스프링 시큐리티

제가 jwt를 사용하고 싶은데 그런 경우에는 jwt를 사용하면 csrf 기능을 사용하면 안되는 건가요?

  • Spring Security
  • java
  • spring-boot
seonjun Moon 댓글 1 좋아요 2 조회수 2447

Runwith, springboottest어노테이션이 없이 테스트 하면 어떻게 되나요?

미해결

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

이전에는 그 어노테이션 없이 test를 진행했던것같은데 이번에는 저 어노테이션이 추가가되어있네요 어떤 차이인거죠? runwith 어노테이션은 junit에 내장된 러너를 사용하는 대신 어노테이션에 정의된 러너 클래스(springrunner.class)를 사용한다는데.. junit에 내장된 러너랑 어노테이션에 정의된 러너클래스랑은 무슨차이인건가요?

  • JPA
  • 웹앱
  • spring
  • java
  • spring-boot
김민지 댓글 1 좋아요 1 조회수 1954

영속성 컨텍스트와 트랜잭션에 대한 질문입니다.

해결됨

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

안녕하세요 영한님. 늘 강의 잘 듣고 있습니다. 강의에서는 Controller단에서 찾아서 넘기면 JPA와 관계가 없는 애가 넘어온다고 하셔서 아래 코드로 테스트 해보았는데, 값이 변경되길래 조금 찾아보았고, 제가 이해한 것이 맞는건가 확인차 질문 올립니다. 1. Spring에서 Controller단의 경우 트랜잭션 범위 밖이기 때문에 읽기만 가능하며, 읽을때에도 영속성 컨텍스트에 등록은 된다. (기본적으로 open-in-view : true이기 때문에) 2. 하지만 말 그대로 "읽기"이기 때문에 persist / merge / flush 등을 호출시 에러를 터트려 트랜잭션 범위 밖에서는 값을 변경할 수 없다. 3. 그럼에도 아래의 코드로 item의 price와 name이 변경되는 것은 1번에 의해 item은 영속성 컨텍스트로 관리되고 있었기 때문이고 orderService의 order()가 종료될 때 플러시 발생 -> 더티체킹 동작시 DB에서 불러왔을때와 다르니 정상적으로 update 발생 4. 만약 application.yml에서 open-in-view : false로 변경 시 컨트롤러단에서 find 한 엔티티들은 영컨에 등록되지 않아 더티체킹도 안될 뿐더러 넘겨받은 member / item을 service단에서 그대로 사용하려 할 경우 에러 발생 (org.hibernate.LazyInitializationException: could not initialize proxy ) ``` @PostMapping ( "/order" ) public String order ( @RequestParam ( "memberId" ) Long memberId , @RequestParam ( "itemId" ) Long itemId , @RequestParam ( "count" ) int count) { // orderService.order(memberId, itemId, count); // 테스트 Member member = memberRepository .findOne(memberId) ; Item item = itemRepository .findOne(itemId) ; item.setPrice( 88888 ) ; // 더티체킹이 일어나는 시점은 트랜잭션 종료 지점이라 해당 지점에서는 변경이랑 관련이 없다 . // 그래서 트랜잭션이 있는 서비스 메소드 부분을 주석쳐버리면 변경은 일어나지 않는다 . // 얘네는 다 에러 // entityManager.flush(); // memberRepository.save(member); // itemRepository.save(item); orderService .order(member , item , count) ; return "redirect:/orders" ; } @Transactional public Long order (Member member , Item item , int count) { item.setName( " 변경된 책 이름 " ) ; // 배송정보 생성 Delivery delivery = new Delivery() ; delivery.setAddress(member.getAddress()) ; delivery.setStatus(DeliveryStatus. READY ) ; // 주문상품 생성 OrderItem orderItem = OrderItem. createOrderItem (item , item.getPrice() , count) ; // 주문 생성 Order order = Order. createOrder (member , delivery , orderItem) ; // 주문 저장 orderRepository .save(order) ; return order.getId() ; } ``` 으로 이해했는데 맞는지 모르겠습니다...

  • spring-boot
  • spring
  • java
  • 웹앱
  • JPA
kim.min.seok 댓글 1 좋아요 8 조회수 495

왜 비디오가 이미지보다 늦게 요청되는 걸까요?

해결됨

프론트엔드 개발자를 위한, 실전 웹 성능 최적화(feat. React) - Part. 2

네트워크 탭으로 분석했을 때 비디오 리소스가 팬딩상태였다가 이미지 로드 완료 후 요청되는데 왜 항상 비디오가 이미지보다 늦게 요청되는 걸까요? 리소스 타입에 따른 브라우저 네트워크 상의 우선순위같은 것이 있는지 궁금합니다!

  • react
  • devtools
ㅇㅈㅇ 댓글 1 좋아요 1 조회수 348

글씨 색

해결됨

한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지

선생님 혹시 진짜 별거 아니긴한데 module.exports 여기에 색 들어오게 하는건 어떻게 하셨나요 ㅠㅠ 저는 그냥 흰색으로 나와서 뭔가 밋밋해서 바꾸고싶은데 방법을 모르겠네요

  • javascript
  • react
  • nodejs
명원 댓글 1 좋아요 0 조회수 406

zerocho 님 eslint 설정관련해서 질문이 있습니다.

미해결

[리뉴얼] React로 NodeBird SNS 만들기

안녕하세요 zerocho 님 eslint 설정관련해서 질문이 있습니다. eslint에서 env쪽에 node: true를 주시면서 node에서 사용하니까 주셨다고 하셨는데 next.js는 Browser환경에서 실행되지 않나요? server 코드가 따로 있는게 아닌 것 같아서요 혹시 이유를 알 수 있을까요?

  • express
  • redux
  • nodejs
  • react
  • Next.js
댓글 1 좋아요 0 조회수 271

card영역이 footer 영역을 침범하여 문의드려요

미해결

비전공자를 위한 진짜 입문 올인원 개발 부트캠프

강의 뒷부분에서 나온다고 댓글 확인했는데 아직 안나와서요.. height:100%는 어디다 적용되었는지 모르겠네요

  • HTML/CSS
  • nodejs
  • 머신러닝 배워볼래요?
  • tensorflow
  • javascript
  • react
  • express
  • react-native
기본땡땡이 댓글 2 좋아요 1 조회수 387

회원 관리 예제 - 웹 MVC 개발 / 회원 웹기능 - 조회를 듣고있는데

미해결

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

강사님 께서는 회원목록 버튼을 클릭하면 이러한 창이 뜨지만 제가 누를때는 이렇게 오류 창이 뜹니다 딱히 오류로 잡히는것도 없어서 단순히 제 코드 실수인가 싶어서 강의를 여러번 돌려가며 최대한 강사님의 코드를 그대로 타이핑 했는데도 오류가 계속 납니다. 다른분들 보니 H2관련해서 오류가 뜨는데 저는 아직 H2파트를 들어가기도 전이고 강사님도 아직 강의내에서 H2를 건드리지 않고 초기 제가 올렸던 사진 처럼 창이 떴는데 도대체 왜 오류가 나는지 궁금합니다 https://drive.google.com/file/d/187dnQjeFv08hwhpoNglqi6TrnZpRXZYI/view?usp=sharing

  • java
  • spring-boot
  • MVC
  • spring
댓글 1 좋아요 0 조회수 291

오늘부터 인터렉티브 공부 시작합니다

미해결

인터랙티브 웹 개발 제대로 시작하기

평소에도 인터랙티브 강의에 관심ㅇ 있었는데 마침 세일하길래 몽땅 사버렸습니다 오늘부터 천천히 공부를 시작해보겠습니다~~~

  • javascript
  • HTML/CSS
  • 인터랙티브-웹
댓글 1 좋아요 1 조회수 233

django 관련 질문

해결됨

파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트

안녕하세요! 이제 강의를 들을려고 합니다. 먼저 저의 상황은 이와 같습니다. Django를 통해 전체적인 웹개발에 대한 흐름을 공부해볼려고 시작합니다. 그 후, backend web 개발자나 Devops나 Data 분야로 가는 것을 결정해볼라고 합니다. Django에 대해 그냥 유튜브 검색을 해보니 [Django를 추천하지 않는 이유](https://www.youtube.com/watch?v=ObelJbEt8-Y) 를 보게 되었습니다. 이 영상에서 봤을 때, 웹 개발을 공부하고 싶으면 Django를 하지 말고 Spring을 해야 한다는 의견이었습니다. Django는 너무 dB에 집중되어 있다고 했습니다. 3년 전 영상이라 지금은 어떨지 모르겠습니다. java spring 시장이 한국에서 매우 거대하여 python Django가 상대적으로 적어도, 절대적으로는 적은 수는 아니라고 생각합니다. (그리고 python은 너무너무 가용성이 좋은 언어라 개인적으로 좋아하는 언어입니다 : ) ) 이에 대해 어떻게 생각하시는 지 궁금합니다.

  • django
  • react
  • python
  • django
  • docker
김제하 댓글 1 좋아요 0 조회수 640

프록시 초기화 시 만들어지는 실제 엔티티

미해결

자바 ORM 표준 JPA 프로그래밍 - 기본편

프록시 객체가 초기화 할 때 영속성 컨텍스트를 통해서 실제 엔티티를 생성하고 생성된 실제 엔티티를 프록시 객체의 target 변수에 참조해준다고 하셨는데 이 때 만들어진 실제 엔티티는 영속성 컨텍스트에 존재하고 있는 건가요? 그렇기 때문에 getReference() -> 초기화 -> find()의 과정을 했 을 때 find() 시점에 select 쿼리문이 안나오는 게 맞나요?

  • JPA
  • java
나 좀 도와줘요 댓글 1 좋아요 0 조회수 248

기타 파일 설치 관련하여

해결됨

풀스택 리액트 토이프로젝트 - REST, GraphQL (for FE개발자)

안녕하세요! 환경세팅부분에서 계속막히는데요 ,,저는 yarn 설치 시 yarn lock 이 생성되지 않아 touch lock으로 생성하였습니다. 그 후 client 폴더에서 sass와 axios webpack을 설치하려 하니 다음과 같이 뜹니다. 어느 파일에 무얼 추가하면 될까요? 하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.

  • rest-api
  • react
  • graphql
mh1020697 댓글 1 좋아요 1 조회수 242

api 응답객체 네이밍 및 new에 대해

해결됨

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

안녕하세요. 강의 너무 잘 보고 있습니다. 좋은 컨텐츠를 제공해주시는 인프런과 영한님, 서포터분들께 감사드립니다. api응답 객체 네이밍에 대해 질문이 있습니다. 등록,수정의 경우 응답객체 네이밍이 ~~Response 조회의 경우 MemberDTO 를 Result로 래핑해서 보내는데 DTO와 Response로 네이밍하는 기준이 있는지 궁금합니다. 또 하나는, 좀 엉뚱한 질문일 수도 있는데 응답시마다 new를 통해 응답객체를 생성하는데 대규모 시스템에 성능에 크게 문제가 없는지와 응답 객체를 싱글톤으로 만드는 패턴같은것도 있는지 궁금합니다. 감사합니다.

  • spring-boot
  • spring
  • java
  • JPA
cw k 댓글 1 좋아요 0 조회수 661

Connection is closed 에러발생(해결)

미해결

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

안녕하세요 강사님! 덕분에 수업 잘 듣고있습니다. 스프링 통합 테스트 강의에서, 테스트 코드의 join함수를 실행시켰더니 java.lang.IllegalStateException: java.sql.SQLException: Connection is closed 에러가 발생했습니다. 원인파악을 위해 join함수 처음부터 천천히 디버깅을 시도했는데, JdbcMemberRepository 클래스의 save함수에서 try 구문의 conn을 할당받는 첫번째 pstmt변수에서 IllegalStateException을 발생시켰습니다. 어떤 원인으로 에러가 발생했으며, 해결방법이 궁금합니다. 아래에 제가 작성한 오류와 연관된 코드들과 에러메시지 첨부합니다. *close함수에서 conn.close()를 close(conn)으로 수정했더니 해결됐습니다. [테스트코드] [JdbcMemberRepository 클래스] [MemberService 클래스] [에러메시지]

  • spring-boot
  • spring
  • MVC
  • java
한종승 댓글 4 좋아요 2 조회수 6700

다름이 아니라 DB 설계 관련 질문이 있습니다.

미해결

[리뉴얼] React로 NodeBird SNS 만들기

안녕하세요 강의 잘보고 있습니다! DB 관련해서 제가 몇가지 궁금한게 있는데 1. 예를 들어 하나의 테이블에서 다 대 다일때 즉 user 와 user에 다대다 일때 중간테이블 follow를 만들어주지 않고 한 User 테이블에 컬럼을 늘리는건 별로 안좋은 방식인가요? 예를 들어서 follow 테이블을 만들지 않고 User 테이블안에 팔로우, 팔로잉 수 컬럼을 넣는 방식 2. 다 대 다 관계일시 중간테이블 관련 다 대 다 관계일시 데이터베이스 이론적으로는 중간테이블을 만드는걸로 저도 배우긴 했는데 근데 이게 프로그래밍 관점에서 테이블을 너무 많이 늘리고 join이 많아질시 성능이 안좋다고 배웠던 기억이 있어서요 그래서 이게 실무에서도 다대다일시 중간테이블로 쪼개고 join을 자주 발생시키는지 궁금해요 로그인 같은경우에도 팔로우,잉,쓴글갯수를 유지하기 위해 로그인을 할때마다 post 테이블 follow 테이블 과의 3개의 테이블을 조인시켜서 select 하는 경우인데 과연 이런식의 3중조인을 로그인할때마다 해줘야 하는건가에 대한 생각 꼭 조인을 이렇게 많이해야 저 데이터를 가지고 올 수있나에 대한 DB설계에 대한 생각이 공존합니다. 아니면 제가 너무 오버하는 것일지 문제가 되지 않는 것인지... 그래서 실제로도 실무에서도 이런식으로 중간테이블과 db설계관련 또한 그걸로 인한 많은 join 관련해서 궁금하네요 ++ 제가 이런 생각이 든 이유가 게시판을 만들때 게시물 상세 페이지에 파일갯수랑, 댓글 갯수를 게시물 리스트에 명시해주는 로직을 짜다가 join 몇번해서 select 해서 가져와보자 했는데.. 다른분께서 이유는 말안하셨지만 join 그렇게 하지말라고 하셨거든요 그래서 그래서 게시물 DB에 갯수에 대한 컬럼을 늘려서 게시물 상세페이지 작성시 댓글, 파일 insert 할때 게시물 db에 갯수counting 해서 insert 하고 조인 없이 list 뿌려지는 형태로 바꿨거든요 그게 생각이나서요(insert 시 다른 db에는 count+1 insert 한 동작에 각 테이블의 2번의 insert 작업) 3. db 생성시 post.js user.js -> 실 테이블 posts, users 뒤에 s가 붙는데 이건 왜 붙는건 가요? 제가 실무 경험이 없어서 꼭 알고 싶은 포인트입니다.. ** 질문이 많은데 읽어주셔서 감사합니다.

  • nodejs
  • react
  • express
  • redux
  • Next.js
ts 댓글 1 좋아요 0 조회수 504

인기 태그

인프런 TOP Writers

주간 인기글