172만명의 커뮤니티!! 함께 토론해봐요.
미해결
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
[제로초 강좌 질문 필독 사항입니다] 질문에는 여러분에게 도움이 되는 질문과 도움이 되지 않는 질문이 있습니다. 도움이 되는 질문을 하는 방법을 알려드립니다. https://www.youtube.com/watch?v=PUKOWrOuC0c 0. 숫자 0부터 시작한 이유는 1보다 더 중요한 것이기 때문입니다. 에러가 났을 때 해결을 하는 게 중요한 게 아닙니다. 왜 여러분은 해결을 못 하고 저는 해결을 하는지, 어디서 힌트를 얻은 것이고 어떻게 해결한 건지 그걸 알아가셔야 합니다. 그렇지 못한 질문은 무의미한 질문입니다. 1. 에러 메시지를 올리기 전에 반드시 스스로 번역을 해야 합니다. 번역기 요즘 잘 되어 있습니다. 에러 메시지가 에러 해결 단서의 90%를 차지합니다. 한글로 번역만 해도 대부분 풀립니다. 그냥 에러메시지를 올리고(심지어 안 올리는 분도 있습니다. 저는 독심술사가 아닙니다) 해결해달라고 하시면 아무런 도움이 안 됩니다. 2. 에러 메시지를 잘라서 올리지 않아야 합니다. 입문자일수록 에러메시지에서 어떤 부분이 가장 중요한 부분인지 모르실 겁니다. 그러니 통째로 올리셔야 합니다. 3. 코드도 같이 올려주세요. 다만 코드 전체를 다 올리거나, 깃헙 주소만 띡 던지지는 마세요. 여러분이 "가장" 의심스럽다고 생각하는 코드를 올려주세요. 4. 이 강좌를 바탕으로 여러분이 응용을 해보다가 막히는 부분, 여러 개의 선택지 중에서 조언이 필요한 부분, 제 경험이 궁금한 부분에 대한 질문은 대환영입니다. 다만 여러분의 회사 일은 질문하지 마세요. 5. 강좌 하나 끝날 때마다 남의 질문들을 읽어보세요. 여러분이 곧 만나게 될 에러들입니다. 6. 위에 적은 내용을 명심하지 않으시면 백날 강좌를 봐도(제 강좌가 아니더라도) 실력이 늘지 않고 그냥 코딩쇼 관람 및 한컴타자연습을 한 셈이 될 겁니다. 사진업로드를 하려할때 미리보기가 뜨지 않습니다. uploads에는 올린 사진들이 잘 뜹니다. 게시글을 업로드하려 짹짹을 누르면 post 라우터가 없다고 뜹니다. POST /post 라우터가 없습니다. 404 Error: POST /post 라우터가 없습니다. at C:\Users\jyoun\udr_node\lecture\ch9\app.js:53:18 at Layer.handle [as handle_request] (C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\layer.js:95:5) at trim_prefix (C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\index.js:328:13) at C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\index.js:286:9 at Function.process_params (C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\index.js:346:12) at next (C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\index.js:280:10) at C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\index.js:646:15 at next (C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\index.js:265:14) at C:\Users\jyoun\udr_node\lecture\ch9\routes\page.js:12:3 at Layer.handle [as handle_request] (C:\Users\jyoun\udr_node\lecture\ch9\node_modules\express\lib\router\layer.js:95:5) controllers/post.js const Post = require('../models/post'); const Hashtag = require('../models/hashtag'); exports.afterUploadImage = (req, res) => { console.log(req.file); res.json({ url: `/img/${req.file.filename}` }); }; exports.uploadPost = async (req, res, next) => { try { const post = await Post.create({ content: req.body.content, img: req.body.url, UserId: req.user.id, }); const hashtags = req.body.content.match(/#[^\s#]*/g); if (hashtags) { const result = await Promise.all(hashtags.map((tag) => { return Hashtag.findOrCreate({ where: { title: tag.slice(1).toLowerCase() } }); })); console.log('result', result); await post.addHashtags(result.map(r => r[0])); } res.redirect('/'); } catch (error) { console.error(error); next(error); } }; routes/post.js const express = require('express'); const multer = require('multer'); const path = require('path'); const fs = require('fs'); const { afterUploadImage, uploadPost } = require('../controllers/post'); const { isLoggedIn } = require('../middlewares'); const router = express.Router(); try { fs.readdirSync('uploads'); } catch (error) { console.error('uploads 폴더가 없어 uploads 폴더를 생성합니다.'); fs.mkdirSync('uploads'); } const upload = multer({ storage: multer.diskStorage({ destination(req, file, cb) { cb(null, '/uploads'); }, filename(req, file, cb) { const ext = path.extname(file.originalname); cb(null, path.basename(file.originalname, ext) + Date.now() + ext); }, }), limits: { fileSize: 5 * 1024 * 1024 }, }); // POST /post/img router.post('/img', isLoggedIn, upload.single('img'), afterUploadImage); // POST /post const upload2 = multer(); router.post('/', isLoggedIn, upload2.none(), uploadPost); module.exports = router; 개발자 도구로 보면 짹짹을 눌렀을때 갈곳이 없다는데 저는 깃헙 복사해서 똑같이 했는데 뭐가 문제인지 모르겠습니다. app.js const express = require('express'); const cookieParser = require('cookie-parser'); const morgan = require('morgan'); const path = require('path'); const session = require('express-session'); const nunjucks = require('nunjucks'); const dotenv = require('dotenv'); const passport = require('passport'); dotenv.config(); const pageRouter = require('./routes/page'); const authRouter = require('./routes/auth'); const { sequelize } = require('./models'); const passportConfig = require('./passport'); const app = express(); passportConfig(); // 패스포트 설정 app.set('port', process.env.PORT || 8001); app.set('view engine', 'html'); nunjucks.configure('views', { express: app, watch: true, }); sequelize.sync({ force: false }) .then(() => { console.log('데이터베이스 연결 성공'); }) .catch((err) => { console.error(err); }); app.use(morgan('dev')); app.use(express.static(path.join(__dirname, 'public'))); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser(process.env.COOKIE_SECRET)); app.use(session({ resave: false, saveUninitialized: false, secret: process.env.COOKIE_SECRET, cookie: { httpOnly: true, secure: false, }, })); app.use(passport.initialize()); app.use(passport.session()); app.use('/', pageRouter); app.use('/auth', authRouter); app.use((req, res, next) => { const error = new Error(`${req.method} ${req.url} 라우터가 없습니다.`); error.status = 404; next(error); }); app.use((err, req, res, next) => { res.locals.message = err.message; res.locals.error = process.env.NODE_ENV !== 'production' ? err : {}; res.status(err.status || 500); res.render('error'); }); app.listen(app.get('port'), () => { console.log(app.get('port'), '번 포트에서 대기중'); }); main.html {% extends 'layout.html' %} {% block content %} <div class="timeline"> {% if user %} <div> <form id="twit-form" action="/post" method="post" enctype="multipart/form-data"> <div class="input-group"> <textarea id="twit" name="content" maxlength="140"></textarea> </div> <div class="img-preview"> <img id="img-preview" src="" style="display: none;" width="250" alt="미리보기"> <input id="img-url" type="hidden" name="url"> </div> <div> <label id="img-label" for="img">사진 업로드</label> <input id="img" type="file" accept="image/*"> <button id="twit-btn" type="submit" class="btn">짹짹</button> </div> </form> </div> {% endif %} <div class="twits"> <form id="hashtag-form" action="/hashtag"> <input type="text" name="hashtag" placeholder="태그 검색"> <button class="btn">검색</button> </form> {% for twit in twits %} <div class="twit"> <input type="hidden" value="{{twit.User.id}}" class="twit-user-id"> <input type="hidden" value="{{twit.id}}" class="twit-id"> <div class="twit-author">{{twit.User.nick}}</div> {% if not followingIdList.includes(twit.User.id) and twit.User.id !== user.id %} <button class="twit-follow">팔로우하기</button> {% endif %} <div class="twit-content">{{twit.content}}</div> {% if twit.img %} <div class="twit-img"><img src="{{twit.img}}" alt="섬네일"></div> {% endif %} </div> {% endfor %} </div> </div> {% endblock %} {% block script %} <script> if (document.getElementById('img')) { document.getElementById('img').addEventListener('change', function(e) { const formData = new FormData(); console.log(this, this.files); formData.append('img', this.files[0]); axios.post('/post/img', formData) .then((res) => { document.getElementById('img-url').value = res.data.url; document.getElementById('img-preview').src = res.data.url; document.getElementById('img-preview').style.display = 'inline'; }) .catch((err) => { console.error(err); }); }); } document.querySelectorAll('.twit-follow').forEach(function(tag) { tag.addEventListener('click', function() { const myId = document.querySelector('#my-id'); if (myId) { const userId = tag.parentNode.querySelector('.twit-user-id').value; if (userId !== myId.value) { if (confirm('팔로잉하시겠습니까?')) { axios.post(`/user/${userId}/follow`) .then(() => { location.reload(); }) .catch((err) => { console.error(err); }); } } } }); }); </script> {% endblock %}
node.js mysql mongodb express typescript socket.io jwt
박예원[ 학부재학 / 컴퓨터융합
2023-11-29T08:29:26.970Z
댓글 1
좋아요 0
조회수 293
미해결
자바 ORM 표준 JPA 프로그래밍 - 기본편
[질문 내용] 준영속 상태와 비영속 상태의 차이점에 대해 이해한바는 다음과 같습니다. 비영속 상태 : 한번도 엔티티 매니저의 관리를 받아본적 없는 엔티티 준영속 상태 : 엔티티 매니저의 관리를 받다가 연결을 끊음으로써 더이상 관리 받지 않고있는 상태. 제가 아는 차이점은 이것 뿐인데 혹시나 이게 두 상태의 차이점의 전부라면 굳이 상태를 나눌 필요가 있나? 라는 생각이듭니다. 그냥 '준영속 상태' 라는 단계를 없애고 연결이 끊기면 비영속 상태 로 , 다시 연결을 맺으면 영속 상태 로 이렇게 단계를 줄여도 되지 않을까요? 혹시나 제가 모르거나 잘못이해하고 있는점이 있다면 알려주시면 감사드리겠습니다!!
정민우(Jhung)
2023-11-28T08:52:21.329Z
댓글 1
좋아요 0
조회수 429
해결됨
Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
안녕하세요 선생님 DWORD dwRead; OVERLAPPED aOl[3] = { 0 }; HANDLE aEvt[3] = { 0 }; //세 번의 비동기 쓰기 완료를 확인하기 위한 이벤트 객체를 생성한다. for (int i = 0; i < 3; ++i) { aEvt[i] = ::CreateEvent(NULL, FALSE, FALSE, NULL); aOl[i].hEvent = aEvt[i]; } //비동기 쓰기가 시작될 지점을 기술한다. //두 번째 쓰기는 세 번째 쓰기보다 나중에 이루어질 가능성이 높다. aOl[0].Offset = 0; //파일의 시작. aOl[1].Offset = 1024 * 1024 * 128; //5MB aOl[2].Offset = 16; //16바이트 //세 번의 비동기 쓰기를 순차적으로 수행한다. for (int i = 0; i < 3; ++i) { printf("%d번째 중첩된 쓰기 시도.\n", i); ::WriteFile(hFile, "0123456789", 10, &dwRead, &aOl[i]); //정상적인 경우 쓰기 시도는 지연(보류)된다! if (::GetLastError() != ERROR_IO_PENDING) exit(0); } 여기서 dwRead가 얼마나 쓰였는지 확인하는 바이트수를 나타낸다고 하는데 만약 쓰고 싶다면 //세 번의 비동기 쓰기가 완료되기를 대기한다. DWORD dwResult = 0; for (int i = 0; i < 3; ++i) { dwResult = ::WaitForMultipleObjects(3, aEvt, FALSE, INFINITE); printf("-> %d번째 쓰기 완료.\n", dwResult - WAIT_OBJECT_0); } sizeof("0123456789") == dwRead; 이런식으로 마지막에 비교할때 쓰이는건가요?
dohyun_lim
2023-11-28T07:10:03.169Z
댓글 1
좋아요 0
조회수 376
미해결
나도코딩의 자바 기본편 - 풀코스 (20시간)
for문이랑 while문 언제 쓰는지 느낌은 알겠는데 정확한 차이점을 모르겠어요 ,, 정확한 정의나 비교될 만한 예시가 있을까요??
김영란
2023-11-28T04:12:49.518Z
댓글 1
좋아요 0
조회수 1133
미해결
Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
안녕하세요 선생님 질문이 있습니다. 4:17에서 client에서 File List를 요구한 다음 server에서 보내는 패킷에서 사이즈가 796인게 MYCMD cmd; cmd.nCode = CMD_SND_FILELIST; cmd.nSize = sizeof(g_flist)+sizeof(g_aFInfo); MYCMD의 사이즈가 맞나요....?
dohyun_lim
2023-11-27T08:27:38.955Z
댓글 3
좋아요 0
조회수 458
해결됨
윤파고의 정보처리기사 DB/프로그래밍 All-In-One
혹시 기출문제 올인원은 어디서 볼 수 있나요?
python java c dbms/rdbms 정보처리기사
2023-11-24T08:23:55.180Z
댓글 2
좋아요 0
조회수 765
해결됨
Windows 소켓 프로그래밍 입문에서 고성능 서버까지!
안녕하세요 선생님 질문이 있습니다. 파일 송신을 할때 server가 100을 보내도 client가 빠르게 처리 못하는 경우 50정도 만간다는 예시에서 나머지 50은 tcp buffer(OS쪽) 에 남겨져 있다고 봐야하는건가요? 어디서 머무르고 있는것인가요?
dohyun_lim
2023-11-24T01:46:25.092Z
댓글 1
좋아요 0
조회수 271
미해결
자바 ORM 표준 JPA 프로그래밍 - 기본편
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 안녕하세요. 간단한 내용이지만 조금 고민이 있어서 질문드립니다. 요청을 통해서 받은 데이터를 통해서나 로직상에서 연관관계에 필요한 Entity의 id값을 알고 있는 경우 필요한 Entity를 DB에서 조회하는 과정 없이 id값만 초기화된 Entity를 생성하여 주입하는 방식이 가능한 것으로 알고 있습니다. 이 때, 그렇게 주입된 Entity는 persist된 상태가 아니라는 점인데요. ( cascade 옵션이 적용 안 되었다는 가정 ) 이런 경우에 두 가지 경우의 수를 고려하였습니다. 첫 번째는 연관관계 Entity가 연관관계 설정 외에는 사용될 일이 없는 로직의 경우이고 두 번째는 연관관계에 필요한 Entity가 이후에도 여러 로직에서 사용되는 경우입니다. 두 번째의 경우에는 사실 고민할 것 없이 ID를 이용해 Entity를 생성하는 것이 아닌 SELECT를 통해서 Entity를 조회하여 사용하는 것이 좋은 방법이고 EntityGraph를 맞추는 면에서도 당연히 해주어야 하는 것으로 사료됩니다. 하지만 첫 번째의 경우 굳이 Entity를 ID값을 통해 조회하는 과정이 필요한 지에 대한 의문입니다. 저런 단순한 로직의 경우 굳이 DB와의 정합성을 위해 조회 및 연관관계 편의메소드 등을 이용해서 EntityGraph를 맞춰줄 필요가 있나 싶었습니다. 이런 경우에서 실제 현업에서는 어떤식으로 처리하는 지 궁금합니다. 저렇게 각 상황에 따라 효율을 따져서 다르게 처리하는 지 아니면 ID를 통해 데이터를 조회하는 것은 크게 성능상 문제가 되지 않으니 불필요하더라도 로직의 통일성이나 혹시 모를 사이드 이펙트를 대비해서 조회한 뒤 연관관계 편의 메소드를 통해 EntityGraph까지 맞춰 주는 지 궁금합니다..! 저는 불필요하다고 생각하여 굳이 Entity그래프를 맞춰줄 필요가 없는 경우는 그런 과정을 생략하며 프로젝트를 하고 있었는데, 완성하고 보니 EntityGraph를 맞춰 주는 로직이 단 하나도 없는 걸 알게 되었습니다. 아무래도 복잡한 비즈니스 로직이 없어서 그럴 수도 있겠다는 생각은 들었지만 너무 심한 것 같아 제가 JPA를 제대로 쓰고 있는 게 맞나 싶어 질문드립니다..ㅠㅠ
공부용
2023-11-23T13:27:54.037Z
댓글 1
좋아요 0
조회수 462
미해결
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
너무 자주 잘문드려 죄송합니다... 2023-11-23T13:10:50.588Z 50b59392-754b-4b9c-90a1-ed48e95f40e1 ERROR AccessDenied: Access Denied at throwDefaultError (/var/task/node_modules/@smithy/smithy-client/dist-cjs/default- error -handler.js:8:22) at /var/task/node_modules/@smithy/smithy-client/dist-cjs/default- error -handler.js:18:39 at de_GetObjectCommandError (/var/task/node_modules/@aws-sdk/client-s3/dist-cjs/protocols/Aws_restXml.js:4330:20) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async /var/task/node_modules/@smithy/middleware-serde/dist-cjs/deserializerMiddleware.js:7:24 at async /var/task/node_modules/@aws-sdk/middleware-signing/dist-cjs/awsAuthMiddleware.js:14:20 at async /var/task/node_modules/@smithy/middleware-retry/dist-cjs/retryMiddleware.js:27:46 at async /var/task/node_modules/@aws-sdk/middleware-flexible-checksums/dist-cjs/flexibleChecksumsMiddleware.js:63:20 at async /var/task/node_modules/@aws-sdk/middleware-sdk-s3/dist-cjs/region-redirect-endpoint-middleware.js:14:24 at async /var/task/node_modules/@aws-sdk/middleware-sdk-s3/dist-cjs/region-redirect-middleware.js:9:20 { '$ fault ': 'client', '$metadata': { httpStatusCode: 403, requestId: 'S3JVT25F4WT5TH9H', extendedRequestId: 'i2FSNxeCIH5smb0tHWggtUQ7WWZIvDurOoQ4UGIZ1eVgwIPsJwrNC85V8Oh2XHVpCaFyITlXaaM=', cfId: undefined, attempts: 1, totalRetryDelay: 0 }, Code: 'AccessDenied', RequestId: 'S3JVT25F4WT5TH9H', HostId: 'i2FSNxeCIH5smb0tHWggtUQ7WWZIvDurOoQ4UGIZ1eVgwIPsJwrNC85V8Oh2XHVpCaFyITlXaaM=' } 이러한 에러가 발생했습니다. 찾아보니깐 s3 버컷 정책과 관련이 있는 것 같습니다. { "Version": "2012-10-17", "Statement": [ { "Sid": "AddPerm", "Effect": "Allow", "Principal": "*", "Action": [ "s3:GetObject", "s3:PutObject" ], "Resource": "arn:aws:s3:::whatsup1/*" } ] } 이게 저의 s3 버캣 정책입니다. 그리고 아래는 aws-upload의 index.js입니다 //이미지 리사이징 라이브러리 const sharp = require("sharp"); const { S3Client, GetObjectCommand, PutObjectCommand, } = require("@aws-sdk/client-s3"); //함수가 aws 람다에서 돌아가기 때문에 스크릿키랑 아이디를 자동으로 넣어준다 = > 아무것도 넣어줄 필요 x const s3 = new S3Client(); //람다는 3개의 매개변수를 제공하고 이 함수를 호출해준다. exports.handler = async (event, context, callback) => { const Bucket = event.Records[0].s3.bucket.name; const Key = decodeURIComponent(event.Records[0].s3.object.key); //original/리버풀.png const filename = Key.split("/").at(-1); const ext = Key.split(".").at(-1).toLowerCase(); const requiredFormat = ext === "jpg" ? "jpeg" : ext; console.log("name", filename, "ext", ext); try { const getObject = await s3.send(new GetObjectCommand({ Bucket, Key })); const buffers = []; for await (const data of getObject.Body) { buffers.push(data); } const imageBuffer = Buffer.concat(buffers); console.log("original", getObject); const resizedImage = await sharp(imageBuffer) .resize(200, 200, { fit: "inside" }) .toFormat(requiredFormat) .toBuffer(); await s3.send( new PutObjectCommand({ Bucket, Key: `thumb/${filename}`, Body: resizedImage, }) ); console.log("put", resizedImage.length); return callback(null, `thumb/${filename}`); } catch (error) { console.error(error); return callback(error); } }; 구글링 해보니깐 s3정책들이 비슷하면서 약간씩 다르던데 뭐가 맞는건지 잘 모르겠습니다..
node.js mysql mongodb express typescript socket.io jwt
김명재
2023-11-23T13:19:43.963Z
댓글 1
좋아요 0
조회수 563
미해결
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
stack": [ " Error : ", "Something went wrong installing the \"sharp\" module", "", "Cannot find module '../build/Release/sharp-linux-arm64v8.node'" 이렇게 에러가 발생했는데 람다에서 함수 생성시 선택사항에 보면 아키텍쳐 선택할때 제로초님은 기본적으로 선택되어있는 x86을 선택하셨고 저는 맥북에어 m2를 사용해서 arm64를 선택했는데 이거 때문에 에러가 난걸까요? 그리고 제로초님이 강의 만드실때는 node 18버전이 최신버전이였는데 지금은 20까지 나와서 20으로 했는데 이것도 문제가 될까요?
node.js mysql mongodb express typescript socket.io jwt
김명재
2023-11-23T11:17:07.166Z
댓글 1
좋아요 0
조회수 251
미해결
스프링 시큐리티
Cookie 값을 삭제 하며 여러 동작을 해보던 도중, 로그인을 하기 전부터 JSSESSIONID 값이 cookie 에 들어가 있는 것을 확인하였습니다. 처음에는 오류인가 싶어 값을 삭제하고 로그인하였더니, 로그인이 동작하지 않고 그냥 페이지가 reload 된 다음 임의의 JSSESSIONID 값을 가져왔습니다. 왜 reload 할 때마다 JSSESSIONID 값을 가져오는 걸까요? 그리고 왜 JSSESSIONID 값 없이는 로그인 동작 자체가 안 되는 걸까요?
java spring-boot spring-security
정재빈
2023-11-23T04:48:31.928Z
댓글 2
좋아요 0
조회수 501
해결됨
실전! Querydsl
plugins { id 'java' id 'org.springframework.boot' version '3.1.5' id 'io.spring.dependency-management' version '1.1.3' id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" } group = 'study' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '17' } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral () } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotationProcessor "com.querydsl:querydsl-apt: $ { dependencyManagement.importedProperties [ 'querydsl.version' ]} :jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api" testImplementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' } tasks. named ( 'test' ) { useJUnitPlatform () } clean { delete file ( 'src/main/generated' ) } tasks. named ( 'bootBuildImage' ) { builder = 'paketobuildpacks/builder-jammy-base:latest' } tasks. named ( 'test' ) { useJUnitPlatform () } //querydsl 세팅 시 def querydslDir = " $buildDir /generated/querydsl" querydsl { jpa = true querydslSourcesDir = querydslDir } sourceSets { main.java. srcDir querydslDir } configurations { querydsl. extendsFrom compileClasspath } compileQuerydsl { options.annotationProcessorPath = configurations. querydsl } 인프런에서 질문 & 답변을 보고 gradle 설정했는데도 오류가 계속 발생됩니다. Build and run using : Gradle 로 변경하면 발생 되는 오류 입니다. 오류 : Attempt to recreate a file for type study.querydsl.entity.QHello
Jun
2023-11-23T01:32:57.461Z
댓글 1
좋아요 0
조회수 3101
미해결
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
req.file을 보면 아래와 같이 나옵니다. { fieldname: 'img', originalname: 'á\x84\x89á\x85³á\x84\x8Fá\x85³á\x84\x85á\x85µá\x86«á\x84\x89á\x85£á\x86º 2023-11-22 á\x84\x8Bá\x85 © á\x84\x92á\x85 ® 8.36.00.png', encoding: '7bit', mimetype: 'image/png', size: 156946, bucket: 'whatsup1', key: 'original/1700700649389_á\x84\x89á\x85³á\x84\x8Fá\x85³á\x84\x85á\x85µá\x86«á\x84\x89á\x85£á\x86º 2023-11-22 á\x84\x8Bá\x85 © á\x84\x92á\x85 ® 8.36.00.png', acl: 'private', contentType: 'application/octet-stream', contentDisposition: null, contentEncoding: null, storageClass: 'STANDARD', serverSideEncryption: null, metadata: undefined, location: 'https://whatsup1.s3.ap-northeast-2.amazonaws.com/original/1700700649389_%C3%A1%C2%84%C2%89%C3%A1%C2%85%C2%B3%C3%A1%C2%84%C2%8F%C3%A1%C2%85%C2%B3%C3%A1%C2%84%C2%85%C3%A1%C2%85%C2%B5%C3%A1%C2%86%C2%AB%C3%A1%C2%84%C2%89%C3%A1%C2%85%C2%A3%C3%A1%C2%86%C2%BA%202023-11-22%20%C3%A1%C2%84%C2%8B%C3%A1%C2%85%C2%A9%C3%A1%C2%84%C2%92%C3%A1%C2%85%C2%AE%208.36.00.png', etag: '"9afb9409e1bcd41269629b6bb1100245"', versionId: undefined } 제로초님은 사진 파일 확장자가 jpg로 뜨는데 저는 png로 뜹니다.. s3에 저장되는 쪽이 아니라 사진을 파일로 만드는 부분에서 문제가 있는 것 같은데 어느부분에서 손을 봐야할지 잘 모르겠습니다.. const { S3Client } = require("@aws-sdk/client-s3"); const multerS3 = require("multer-s3"); const s3 = new S3Client({ credentials: { accessKeyId: process.env.S3_ACCESS_KEY_ID, secretAccessKey: process.env.S3_SECRET_ACCESS_KEY, }, region: "ap-northeast-2", }); const upload = multer({ storage: multerS3({ s3, bucket: "whatsup1", key(req, file, cb) { cb(null, `original/${Date.now()}_${file.originalname}`); }, }), limits: { fileSize: 5 * 1024 * 1024 }, }); 그리고 추가적인 질문이 있는데 localhost 로 서버를 작동시킬때 db는 잘 보이는데 lightsail로 작동시킨 db가 보이지 않습니다.. mysql connection 추가 버튼 눌러서 hostname을 aws에서 제공해준 ip로 바꾸면 되는거 아닌가요? 그런데 그렇게 하고 연결을 하니깐 버퍼링이 걸리면서 연결이 되지 않습니다..
node.js mysql mongodb express typescript socket.io jwt
김명재
2023-11-23T01:05:43.839Z
댓글 1
좋아요 0
조회수 640
미해결
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
안녕하세요!! 제가 지금 Next.js와 Node.js를 활용해서 중고거래 사이트를 프론트와 백 둘다 구현을 하려고 하는데 프론트(NextAuth)에서 API 를 받아와 카카오 로그인을 구현하면, 백에서는 카카오 로그인에대한 구현을 할 필요가 없는건가요? 또, 프론트 나 백 둘중 어느곳에서 카카오 로그인을 구현해야 효율적인지 궁금합니다!
node.js mysql mongodb express typescript socket.io jwt
rlaghdwns777
2023-11-22T17:52:33.805Z
댓글 1
좋아요 0
조회수 295
해결됨
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
질문할까 고민하다가 용기내어 질문드려봅니다..! 11장 통합테스트 중 나타난 에러입니다. npm test 를 입력하면 나오는 에러입니다. > nodebird@0.0.1 test > jest PASS models/user.test.js PASS services/user.test.js PASS middlewares/index.test.js FAIL routes/auth.test.js ● Test suite failed to run TypeError: model.initiate is not a function 22 | console.log(file, model.name); 23 | db[model.name] = model; > 24 | model.initiate(sequelize); | ^ 25 | }); 26 | 27 | Object.keys(db).forEach(modelName => { // associate 호출 at initiate (models/index.js:24:11) at Array.forEach (<anonymous>) at Object.forEach (models/index.js:20:4) at Object.require (routes/auth.test.js:2:23) Test Suites: 1 failed, 3 passed, 4 total Tests: 9 passed, 9 total Snapshots: 0 total Time: 0.725 s, estimated 1 s 현재 에러는 model.initiate가 함수화가 되지 않았다고 나타는거 같습니다. model.initiate가 존재하는 index.js입니다. const Sequelize = require('sequelize'); const fs = require('fs'); const path = require('path'); const env = process.env.NODE_ENV || 'development'; const config = require('../config/config')[env]; const db = {}; const sequelize = new Sequelize( config.database, config.username, config.password, config, ); db.sequelize = sequelize; const basename = path.basename(__filename); fs .readdirSync(__dirname) .filter(file => { return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); }) .forEach(file => { const model = require(path.join(__dirname, file)); console.log(file, model.name); db[model.name] = model; model.initiate(sequelize); // 오류 발생시점 }); Object.keys(db).forEach(modelName => { if (db[modelName].associate) { db[modelName].associate(db); } }); module.exports = db; 11.3 강의를 보는 중이며 auth.test.js 코드를 작성중입니다 작성중인 auth.test.js는 아래와 같습니다. const app = require('../app'); const request = require('supertest'); const { sequelize } = require('../models'); beforeAll(async () => { await sequelize.sync() }) beforEach(() => { }); describe('POST /join', () => { test('로그인 안 했으면 가입', (done) => { request(app).post('/auth/join') .send({ email: 'choibo@naver.com', nick: 'bobobo', password: 'choibo11' }) .expect('Location', '/') .expect(302, done) }) }) describe('POST /login', () =>{ test('로그인 수행', (done) => { request(app).post('/auth/login') .send({ email: 'choibo@naver.com', password: 'choibo11' }) .expect('Location', '/') .expect(302, done) }) }); afterEach(() => {}); aftereAll(() => { }); 이부분에서 에러가 발생한다고 나타나있습니다. const { sequelize } = require('../models');
node.js mysql mongodb express typescript socket.io jwt
승현
2023-11-22T12:42:47.831Z
댓글 2
좋아요 0
조회수 708
미해결
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
버킷 만들때 강의 와 달리 처음부터 저렇게 선택되어있던데 그냥 원래 선택되었던거 유지하면서 만들면 되나요?
node.js mysql mongodb express typescript socket.io jwt
김명재
2023-11-22T12:20:13.513Z
댓글 1
좋아요 0
조회수 262
미해결
재고시스템으로 알아보는 동시성이슈 해결방법
안녕하세요 강사님 강의를 보고 토이 프로젝트에서 주문 시 재고 감소 및 메뉴 주문량 증가 로직에서 낙관적락 기법을 적용해 보았는데요, 강의에서 해주신 내용 그대로 파사드 패턴 까지 적용을 해보면서 시도했는데 무한 루프가 돌았습니다. hikariCP pool을 40으로 설정해주니 그제서야 해결이 되었는데요, 강의에선 네임드락에서 커넥션풀을 지정해주었는데요 저는 낙관적락인데도 해당 설정을 해서 해결된 이유가 있을까요? @Service @RequiredArgsConstructor public class OrderService { @Transactional public Order orderWithOptimisticLock(Long memberId, LocalDateTime now) { Cart cart = cartRepository.findByMember(memberId); List<CartItem> cartItems = cart.getCartItems(); cartItems.stream() .map(CartItem::getMenu) .forEach(menu -> { decreaseStockWithOptimisticLock(menu.getId(), 1); increaseMenuOrderCountWithOptimisticLock(menu.getId(), 1); }); Money money = calculator.calculateMenus(cart.getMember(), cart.convertToMenus()); Order order = Order.createOrder(cart, money, now); return orderRepository.save(order); } public void decreaseStockWithOptimisticLock(Long menuId, int quantity) { Menu menu = menuRepository.findByIdForOptimisticLock(menuId); menu.decrease(quantity); } public void increaseMenuOrderCountWithOptimisticLock(Long menuId, int quantity) { Menu menu = menuRepository.findByIdForOptimisticLock(menuId); menu.increaseOrderCount(quantity); } } ``` @Component @RequiredArgsConstructor public class OptimisticLockStockFacade { private final OrderService orderService; public Order order(Long memberId, LocalDateTime localDateTime) throws InterruptedException { while (true) { try { return orderService.orderWithOptimisticLock(memberId, localDateTime); } catch (Exception e) { Thread.sleep(50); } } } } ``` public interface JpaMenuRepository extends JpaRepository<Menu, Long> { @NotNull @Lock(LockModeType.OPTIMISTIC) @Query("select m from Menu m where m.id = :id") Optional<Menu> findByIdForOptimisticLock(@NotNull @Param("id") Long id); }
하윤
2023-11-21T13:37:04.672Z
댓글 2
좋아요 0
조회수 647
미해결
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
const express = require("express"); const cookieParser = require("cookie-parser"); const morgan = require("morgan"); const session = require("express-session"); const router = express.Router(); const path = require("path"); const dotenv = require("dotenv"); const passport = require("passport"); const app = express(); const passportConfig = require("./passport"); const redis = require("redis"); const RedisStore = require("connect-redis").default; dotenv.config(); const redisClient = redis.createClient({ url: `redis://${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`, password: process.env.REDIS_PASSWORD, legacyMode: false, }); redisClient.connect().catch(console.error); const authRouter = require("./routes/auth"); const pageRouter = require("./routes/page"); const postRouter = require("./routes/post"); const userRouter = require("./routes/user"); const commentRouter = require("./routes/comment"); const updateRouter = require("./routes/update"); const deleteRouter = require("./routes/delete"); const helmet = require("helmet"); const hpp = require("hpp"); const { sequelize } = require("./models"); const logger = require("./logger"); passportConfig(); app.set("port", process.env.PORT || 8005); sequelize .sync({ force: false }) .then(() => { console.log("데이터베이스 연결 성공"); }) .catch((err) => { console.error(err); }); if (process.env.NODE_ENV === "production") { app.use( helmet({ contentSecurityPolicy: false, crossOriginEmbedderPolicy: false, crossOriginResourcePolicy: false, crossOriginOpenerPolicy: false, originAgentCluster: false, }) ); app.use(hpp()); app.use(morgan("combined")); } else { app.use(morgan("dev")); } app.use(express.json({ limit: "10mb" })); var cors = require("cors"); const { deepStrictEqual } = require("assert"); app.use(cors()); app.use("/img", express.static(path.join(__dirname, "uploads"))); app.use("/profileImg", express.static(path.join(__dirname, "profileImg"))); app.use(express.json()); app.use(express.urlencoded({ limit: "10mb", extended: false })); app.use(cookieParser(process.env.COOKIE_SECRET)); const sessionOption = { resave: false, saveUninitialized: false, secret: process.env.COOKIE_SECRET, cookie: { httpOnly: true, secure: false, }, store: new RedisStore({ client: redisClient }), }; if (process.env.NODE_ENV === "production") { sessionOption.proxy = true; } app.use(session(sessionOption)); app.use(passport.initialize()); app.use(passport.session()); app.use(express.static(path.join(__dirname, "prototype-client/build"))); app.get("/", (req, res) => { res.sendFile(path.join(__dirname, "prototype-client/build/index.html")); }); app.use("/page", pageRouter); app.use("/auth", authRouter); app.use("/post", postRouter); app.use("/user", userRouter); app.use("/comment", commentRouter); app.use("/update", updateRouter); app.use("/delete", deleteRouter); //react에서 react-router-dom으로 다룰 수 있게 app.get("*", function (req, res) { res.sendFile(path.join(__dirname, "/prototype-client/build/index.html")); }); //에러 처리 담당 app.use((req, res, next) => { const error = new Error(`${(req, method)} ${req.url} 라우터가 없습니다.`); error.status = 404; logger.info("hello"); logger.error(error.message); next(error); }); app.use((err, req, res, next) => { console.error(err); res.locals.message = err.message; res.locals.erorr = process.env.NODE_ENV !== "production" ? err : {}; res.status(err.status || 500); res.render("error"); }); module.exports = app; 이렇게 코드를 실행하면 sudo pm2 monit의 server log에 2가지 에러가 나옵니다. server > [Error: ENOENT: no such file or directory, stat │ ││ server > errno: -2, │ ││ server > code: 'ENOENT', │ ││ server > syscall: 'stat', │ ││ server > path: '/home/bitnami/Whats-up/prototype-client/bu │ │ ││ server > expose: false, │ ││ server > statusCode: 404, │ ││ server > status: 404 │ ││ server > } 에러 메시지를 봤을때 해당 경로에 대한 파일을 찾을 수 없다고 하는데 ls를 입력했을때 잘 있는걸 확인 할 수 있는데 왜 이런 에러가 발생하는지 모르겠습니다.. 2번쨰는 server > Error: No default engine was specified and no ││ server > at new View (/home/bitnami/Whats-up/node_module │ ││ server > at Function.render (/home/bitnami/Whats-up/node │ ││ server > at ServerResponse.render (/home/bitnami/Whats-u │ ││ server > at /home/bitnami/Whats-up/app.js:127:7 │ ││ server > at Layer.handle_error (/home/bitnami/Whats-up/n │ ││ server > at trim_prefix (/home/bitnami/Whats-up/node_mod │ ││ server > at /home/bitnami/Whats-up/node_modules/express/ ││ server > at Function.process_params (/home/bitnami/Whats 이런 에러가 발생합니다. 에러 메세지를 봤을떄는 view engine관련된 에러같은데 react랑 express연동할때는 따로 view engine 설정을 주지 않고 express.static으로 리액트 코드를 전달하면 되는거 아닌가요?
node.js mysql mongodb express typescript socket.io jwt
김명재
2023-11-21T08:31:32.346Z
댓글 2
좋아요 0
조회수 621
미해결
자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비
앞 문제에서 Collection.sort를 쓰면 문제에서 효율적이지 못하다는 댓글을 봐서 처음부터 Array.sort를 해서 정렬하는 방법을 생각을 못했는데 어떤 문제에선 사용하고 사용하지말고 구분이잘 안되는데 이럴땐 어떻게 하나요...
이주용
2023-11-21T06:45:30.606Z
댓글 1
좋아요 0
조회수 385
미해결
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
저는 지금 단순 html페이지 대신 react와 함께 nodebird 프로젝트를 하고 있는데요. 지금 aws설정도 다 마치고 pm2를 실행하고 sudo pm2 list를 해봐도 오류 없이 잘 실행됩니다. 그래서 크롬 주소창에 ip를 입력하면 사이트에 연결할 수 없다고 합니다.. 직접적으로 에러가 뜨는 것도 아니여서 어디가 문제인지 잘 모르겠습니다.. github: https://github.com/AUDWO/Whats-up/blob/main/app.js (prototype-client가 리액트로 만든 페이지 입니다)
node.js mysql mongodb express typescript socket.io jwt
김명재
2023-11-20T05:18:55.409Z
댓글 1
좋아요 0
조회수 691