공부의 기록/자바 풀 스택 : 수업내용정리

자바 풀 스택 1/14 오전 기록 037-1

파티피플지선 2025. 1. 14. 12:37

 
9:30 경 도착
 
 
<9:30 1교시>

div 상자 하나씩 누를 때 마다 글씨 div숫자를 누를 때 글씨가 clicked로 바뀔 수 있게 하는 코딩을 시도함.
내가 시도한 삽질

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .wrapper{
            display: flex;
        }
        .box{
            width:100px;
            height:100px;
            background-color: yellow;
            border:1px solid red;
            cursor:pointer;
        }

    </style>
</head>
<body>
    <div class="wrapper">
        <div class="box">div1</div>
        <div class="box">div2</div>
        <div class="box">div3</div>
        <div class="box">div4</div>
        <div class="box">div5</div>
    </div>
    <script>
        let boxes = document.querySelectorAll(".box");
        let nums= [];
        for(i=0; i<boxes.length; i++){
            let divnum= boxes[i];
            let num= divnum -"div"
            push.nums(num);
        }
        document.querySelector(".box").addEventListener("click", ()=>{
            if(num==1){
            document.querySelector(".box").insertAdjacentText("div"+num)="clicked";
            }
        });
        

    </script>
</body>
</html>

아직도 querySelectorAll 제대로 쓰는거 몰라서 처음에 querySelector로 이벤트리스너 등록하려다가 querySelectorAll 생각나서 일단 배열을 만들어놓긴 했는데 그다음에 어떻게 쓸줄 몰라서 코미디 🤣🤣🤣🤣🤣🤣🤣🤣
 
 
선생님이랑 한 코딩.
내가 하고 싶었던걸 이렇게 간단하게 할 수 있다니!
나도 할 수 있어!!!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .wrapper{
            display: flex;
        }
        .box{
            width:100px;
            height:100px;
            background-color: yellow;
            border:1px solid red;
            cursor:pointer;
        }

    </style>
</head>
<body>
    <div class="wrapper">
        <div class="box">div1</div>
        <div class="box">div2</div>
        <div class="box">div3</div>
        <div class="box">div4</div>
        <div class="box">div5</div>
    </div>
    <script>
        let boxes = document.querySelectorAll(".box");
  
        for(i=0; i<boxes.length; i++){
            boxes[i].addEventListener("click",(event)=>{
                event.target.innerText="clicked";
                event.target.style.backgroundColor="green";
            });
        }
    </script>
</body>
</html>

이벤트가 일어난 바로 그 요소만 == event.target

 

        let boxes = document.querySelectorAll(".box");
        for(i=0; i<boxes.length; i++){
            boxes[i].addEventListener("click",(event)=>{
                event.target.innerText="clicked";
                event.target.style.backgroundColor="green";
            });
        }

바로 위에서 한 코딩을 jquery로 하면 더 간단해진다

        $(".box").on("click", (event)=>{
            $(event.target).text("clicked").css("backgroudColor", "green");
        });//이렇게만 해도 배열에 반복문 돈 효과

 
이게 끝임
 
 
 
<10:30 2교시>
어노테이션은 우리가 작성한 소스코드가 컴파일될 때 그 클래스에 기는을 덧붙여 변형시켜주는 역할을 한다.
 
파일을 업로드하는 코딩에서는 서블릿 작업할 때 아래 annotation을 불러오는 작업을 해줘야 제대로 파일이 업로드 된다.
@MultipartConfig(
fileSizeThreshold = 1024*1024*5,
maxFileSize=1024*1024*50, 
maxRequestSize=1024*1024*60/
)
 
 
 
코드의 의미만 확인하기

 

 
 
 
파일의 다운로드를 위해서는 원본파일명, 저장된 파일명, 파일의 크기가 필요하다.
원래는 파일의 id만 가져가서 DB에 저장하는데, 지금 하고 있는거는 임시로 하는 거라 다운로드에 필요한 정보들을 보내주는 거
 
 
 
FileDownServlet.java의 한 부분

웹브라우저에게 네가 응답할 컨텐츠가 이런 내용이야라고 미리 언질을 주는 부분
 
 
 
<11:30 3교시>
프로파일 아이콘 눌러 이미지 올리기
 

 


 
 

 
html 부분 백틱 다시 봐야겠다.
 
 
 
uploadservlet4.java

package test.servlet;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.UUID;

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Part;
@WebServlet("/file/upload4")
@MultipartConfig(
		fileSizeThreshold = 1024*1024*5,//메모리 임계값 (메모리를 효율적으로 쓰기 위한 값, 이 값을 넘어가면 파일로 전환함)
		maxFileSize=1024*1024*50, //최대 파일 사이즈 1킬로바이트(=1024바이트)*1킬로바이트*50 =50메가 바이트
		maxRequestSize=1024*1024*60//최대 요청 사이즈 
		)
public class UploadServlet4 extends HttpServlet{
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//업로드될 실제 경로 얻어내기
		String uploadPath=getServletContext().getRealPath("/upload");
		File uploadDir=new File(uploadPath);
		//만일 upload 폴더가 존재하지 않으면
		if(!uploadDir.exists()) {
			uploadDir.mkdir();//실제로 폴더 만들기
		}
				
		//파일명이 겹치지 않게 저장하기 위한 랜덤한 문자열을 얻어내기
		String uid=UUID.randomUUID().toString();
		System.out.println(uid);
		String origFileName=null;
		String saveFileName=null;
		
		//파일 데이터 처리는 좀 다르다
		Part filePart = req.getPart("myImage");
		if(filePart !=null) {
			//파일 이름 얻어내기
			origFileName=filePart.getSubmittedFileName();
			//저장될 파일의 이름 구성하기
			saveFileName=uid+origFileName;
			//저장할 파일의 경로 구성
			String filePath=uploadPath+File.separator+ saveFileName;
			//파일 저장
			InputStream is=filePart.getInputStream();
			Files.copy(is, Paths.get(filePath));
		}
		
		
		//응답에 필요한 데이터를 request 영역에 담기
		req.setAttribute("saveFileName",saveFileName );
		
		
		//jsp 페이지로 응답을 위임하기(리다이렉트는 컨텍스트 경로가 필요하지만 포워드 이동은 필요 없다)
		RequestDispatcher rd=req.getRequestDispatcher("/file/upload4.jsp");
		rd.forward(req, resp);
	}
	
}

 
 
upload4.jsp

<%@ page language="java" contentType="application/json; charset=UTF-8"
    pageEncoding="UTF-8"%>
{
	"saveFileName":"${saveFileName}"
}

 
 
upload_form4.jsp 내가 한거 오류남(아 event뒤에 소괄호... 아..... 아.............)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
	#imaged{
	display:none;}
	#profileImage{
		width:200px;
		height:200px;
		border 1px solid #cecece;
		border-radius:50%;}
</style>
</head>
<body>
	<div class="container">
		<h3>이미지 단독 업로드 테스트</h3>
		<a href="javascript:" id="profileLink" >
			<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" fill="currentColor" class="bi bi-person-circle" viewBox="0 0 16 16">
				<path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
				<path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/>
			</svg>
		</a>
		<br />
		<input type="file" id="image" accept="image/*" />
	</div>
	<script>
		//링크를 클릭했을 때
		document.querySelector("#profileLink").addEventListener("click", ()=>{
			//input type="file"요소를 강제 클릭해서 파일 선택 창을 띄운다.
			document.querySelector("#image").click();
		});
		//새로운 이미지를 선택했을 때 input 요소에는 change 이벤트가 발생한다.
		document.querySelector("#image").addEventListener("change", (event=>{
			//여기서 event.target은 <input type="file" id="image" accept="image/*" /> 얘다
			//선택된 파일 데이터
			const fileData=event.target.files[0];
			//FormData객체에 myImage라는 키값으로 파일 데이터 담기(form으로 받아오지 않았기 때문에)
			const data=new FormData();
			data.append("myImage", fileData);
			//fetch()함수를 이용해서 업로드하고 응답받은 데이터를 이용해서 이미지 출력하기
			fetch("${pageContext.request.contextPath}/file/upload4", {
				method:"post",
				body:data
				})
			.then(res=>res.json())
			.then(data=>{
				//data.saveFileName은 업로드 된 이미지의 저장파일명
				console.log(data);
				//img 요소를 만들 문자열 구성하기
				const img =`
					<img id="prfocileImage" src="${pageContext.request.contextPath}/upload/\${data.saveFileName}">
					
				`;
				document.querySelector("#profileLink").innerHTML=img;
			});
		});		
	</script>
</body>
</html>

 
 
upload_form4.jsp 샘이 보내주신거

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/file/upload_form4.jsp</title>
<style>
	#image{
		display:none;
	}
	#profileImage{
		width: 200px;
		height: 200px;
		border: 1px solid #cecece;
		border-radius: 50%;
	}
</style>
</head>
<body>
	<div class="container">
		<h3>이미지 단독 업로드 테스트</h3>
		<a href="javascript:" id="profileLink" >
			<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" fill="currentColor" class="bi bi-person-circle" viewBox="0 0 16 16">
				<path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
				<path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/>
			</svg>
		</a>
		<br />
		<input type="file" id="image" accept="image/*" />
	</div>
	<script>
		//링크를 클릭했을때 
		document.querySelector("#profileLink").addEventListener("click", ()=>{
			// input type="file" 요소를 강제 클릭해서 파일 선택 창을 띄운다.
			document.querySelector("#image").click();
		});	
		//새로운 이미지를 선택 했을때 input 요소에는 change 이벤트가 발생한다.
		document.querySelector("#image").addEventListener("change", (event)=>{
			//여기서 event.target 은 input type="file" 요소이다.
			//선택된 파일 데이터
			const fileData=event.target.files[0];
			// FormData 객체에 myImage 라는 키값으로 파일 데이터 담기
			const data=new FormData();
			data.append("myImage", fileData);
			//fetch() 함수를 이용해서 업로드 하고 응답받은 데이터를 이용해서 이미지 출력하기 
			fetch("${pageContext.request.contextPath }/file/upload4", {
				method:"post",
				body:data
			})
			.then(res=>res.json())
			.then(data=>{
				//data.saveFileName 은 업로드된 이미지의 저장된 파일 명이다.
				console.log(data);
				//img 요소를 만들 문자열 구성하기
				const img=`
					<img id="profileImage" src="${pageContext.request.contextPath }/upload/\${data.saveFileName}">
				`;
				document.querySelector("#profileLink").innerHTML=img;
			});
		});
		
	</script>
</body>
</html>

 
 
 
선생님 공부방 페이지에서 zip 파일 다운로드 받아서 webapp에 SmartEditor 폴더 추가, webapp>web-inf에 jar 파일 두 개 추가함
 
 
 
<12:30 4교시>
전교시 마지막에 했던거는 우리 이클립스 버전이 높아서 해결방법을 찾으시는 중이라고 함.
 
 
나는 uploadform이랑 uploadservlet, downloadservelt, 백틱 손코딩하러 감
 
다운로드 서블랫 백업 안해뒀던거 같아서

package test.servlet;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/file/download")
public class FileDownServlet extends HttpServlet{
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//다운로드 작업에 필요한 3가지 정보(원본파일명, 저장된파일명, 파일의크기) 얻어오기
		// 지금은 파라미터로 전달되지만 실제로는 DB에 저장된 정보를 읽어와서 다운로드 해야 함
		String origFileName=request.getParameter("origFileName");
		String saveFileName=request.getParameter("saveFileName");
		long fileSize=Long.parseLong(request.getParameter("fileSize"));
		
		//응답 헤더 정보 설정
		response.setHeader("Content-Type", "application/octet-stream; charset=UTF-8");
		//다운로드 시켜줄 파일명 인코딩  
	   	String encodedName=URLEncoder.encode(origFileName, "utf-8");
		//파일명에 공백이있는 경우 처리 
		encodedName=encodedName.replaceAll("\\+"," ");
		
		response.setHeader("Content-Disposition", "attachment;filename="+encodedName);
		response.setHeader("Content-Transfer-Encoding", "binary");
		
		//다운로드할 파일의 크기
		response.setContentLengthLong(fileSize);
		
		//다운로드 시켜줄 파일의 실제 경로
		String path=getServletContext().getRealPath("/upload")+File.separator+saveFileName;
		
		FileInputStream fis=null;
		BufferedOutputStream bos=null;
		try {
			//파일에서 byte 을 읽어들일 객체
			fis=new FileInputStream(path);
			//클라이언트에게 출력할수 있는 스트림 객체 얻어오기
			bos=new BufferedOutputStream(response.getOutputStream());
			//한번에 최대 1M byte 씩 읽어올수 있는 버퍼
		   	byte[] buffer=new byte[1024*1024];
		   	int readedByte=0;
		   	//반복문 돌면서 출력해주기
		   	while(true) {
		   		//byte[] 객체를 이용해서 파일에서 byte 알갱이 읽어오기
		   		readedByte = fis.read(buffer);
		   		if(readedByte == -1)break; //더이상 읽을 데이터가 없다면 반복문 빠져 나오기
		   		//읽은 만큼 출력하기
		   		bos.write(buffer, 0, readedByte);
		   		bos.flush(); //출력
		   	}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			if(fis!=null)fis.close();
			if(bos!=null)bos.close();
		}	
	}
}