본문 바로가기
수업내용

20230601 수업내용🫡🫡🫡

by titlejjk 2023. 6. 1.

오늘도 수업의 시작은 비쥬얼 스튜디오..

Javascript정규식을 만드는 방법에 대해서 배워보겠다.

    <script>
        //생성하는 방법1
        const reg1 =  /a/; // "/"안에서 작성한 문자열이 정규표현식이다.
        
        //생성하는 방법2
        const reg2 = new RegExp("a"); //따옴표 안에작성한 문자열이 정규표현식이다.
    </script>

같은 값이 나왔다.

정규표현식은 .test()메소드와 .exec()라는 메소드를 많이 쓴다.

예를 들어 사용법은 이렇다.

//정규표현식으로 검증할 문자열
        const str = "abcabcabc";

을 만들어주고 콘솔창에서 찍어보면

test메소드는 설정해둔 str에있는 문자가 있는지 true false로 반환한다. 찾아지면 true 없으면 false

exec메소드는 매칭된 문자열을 찾아내는 것 이다. exec는 찾은 문자열을 추출하는 기능까지 있다.

앞에거 하나를 추출할 수도 있고 전체에서 찾아서 추출할 수도 있다.

 

정규표현식은 대소문자를 구별한다.

눈에 보이지 않는 space(띄어쓰기),tab, new line(개행기호)도 정확히 일치해야한다.

^ 는 시작을 의미👉 /^who/ 는 who를 찾는게 아니라 who로 시작하는지 검증을 하는 것이다.

$는 끝을 의미👉 /who$/는 who로 끝나는 문자열을 찾는 것이다.

만약에 특별한 의미를 가지고 있는 문자열의 literal값이 필요하다면 역슬레시 " \ "를 앞에 붙여주면 된다.

/^$/ 👉는 빈문자열을 찾는 정규표현식

/\$/👉는 $를 찾겠다는 정규표현식

/^\$/ 👉$로 시작하겠다는 문자열을 찾겠다는 것

/\$$/ 👉$로 끝나는 것을 찾는 것

/\\/👉 \\를 찾는 것

.(점)은 아무거나 한글자를 의미한다. 그리고 점을 찾을 때 역시도 " \ "를 사용하면 된다.(공백도 포함)

/./아무거나 한글자를 찾는다. 만약 점이 6개면 6문자를 찾는 거고 all matches에서는 6글자씩 끊어서 찾아준다.

/\..\./👉양쪽에 점이 있고 가운데는 아무거나 한글자가 있는 문자를 찾는 것

[abc] 👉 abc 중에 한글자

[a-z] 👉 a부터 z범위 내에서 한글자

[가-힁] 👉 가 에서부터 힁 까지중에 한글자

[0-9] 👉 숫자중에 한글

[a-zA-Z0-9] 👉 영문자 대소문자와 숫자만 이것을 제외하고는 다 특수문자/한글 이다

/[dH]./ 👉 [ ] 전체를 하나로 봐서 한글자 " . "도 한글자해서 두글자를 찾는 것이다.

[^abc] 👉 대괄호 안에서에 ^는 not을 의미한다. 해석하자면 한글자긴 한데 abc가 아닌 한글자를 찾는 것이다.

( )소괄호 👉 문자열을 교차 매칭 시키려면 소괄호 안에 | 로 구분해서 나열하면 된다.

/(on|use|rida)/ 👉 on ues rida를 찾는다는 것

/(Mon|Tues|Fri)day/ 👉 뒤에 day라는 문자열을 반드시 포함시킨 상태에서 찾기

/..(id|esd|nd)ay/ 👉앞에 두글자는 아무거나 뒤에는 ay 가운데는 id, esd, nd를 찾는 구문

* 👉 문자가 0번이상 올수 있는지 정의(없어도 되고 여러개가 있어도 된다.) 

+  👉 문자가 1번이상 올수 있는지 정의(반드시 있어야 하며 여러개가 있어도 된다.)

? 👉 문자가 0번 또는 1번 올수 있는지 정의(없어도 되고 오직 한개만 허용)

/a*b/ 👉 b앞에 a가 있어도되고 없어도 되고

/a+b/ 👉 b앞에 a가 반드시 있으면서 여러개 있어도된다.

/a?b/ 👉 b앞에 a가 한개만 있어야한다.

/.*/ 👉아무거나 한글자가 0번이상

/-A*-/ 👉 A가 없어도 된다

/-@+-/👉양쪽에-가 있고 @가 한번이상

/[^ ]+/ 👉한글자긴 한데 공백이 아닌 한글자가 한번이상 와야한다. 긴 문자열에서 공백을 제외한 모든 문자열을

               찾을수 있다.

{ } 👉 정확한 문자의 반복횟수를 정의한다.

/.{5}/ 👉 아무거나 한글자가 5번 반복된다. " . "이 5개 반복된다는 의미

/[els]{1.3}/ 👉e,l,s 중에 한글자가 최소 1번 최대 3번까지 올수있다는 의미

/[a-z]{3,}}/ 👉소문자가 최소 3번은 와야한다는 의미 

* 는 {0,} 

+ 는 {1,}

? 는 {0,1}과 같다. 왜케 어렵냐

[0-9] 숫자중의 한글자 는 [\d]와 같다

[a-zA-Z0-9] == [\w]

[^0-9] == [^\d] == [\D]

[^a-zA-Z0-9] == [^\w] == [\W] 

소문자와 대문자는 반대의 개념이다. ^가 포함되면 ^를 없애고 대문자로 넣어주면된다.

/[a-z].{4}/ 👉 첫글자는 영문자 소문자, 총 5글자를 찾는다.

정규표현식은 form에서 들어온 정보를 검증할 때 많이 사용한다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Step02_Form3.html</title>
    <link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>
    <div class="container">
        <h1>회원가입폼</h1>
        <form action="">
            <div class = "mb-2">
                <label class = "form-label" for="id">아이디</label>
                <input class = "form-control" type="text" id="id" name="id" placeholder = "아이디">
                <div class = "invalid-feedback">
                    영문자 소문자로 시작하고 4글자 이상 10글자 이하로 작성해 주세요
                </div>
                <div class = "valid-feedback">
                    Looks good!
                </div>
            </div>
            <div class = "mb-2">
                <label class = "form-label" for="email">이메일</label>
                <input class = "form-control" type = "text" id= "email" name = "email">
                <div class = "invalid-feedback">
                    이메일 형식에 맞게 입력해 주세요!
                </div>
                <div class = "valid-feedback">
                    Look good!
                </div>
            </div>
            <button class = "btn btn-primary" type = "submit" disabled = "disabled">가입</button>
        </form>
    </div>
    <script>
        //페이지 로딩 시점에 상태값을 관리할 변수를 만들고 초기값을 부여한다.
        let isFormValid = false;
        let isIdValid = false;
        let isEmailValid = false;
        //아이디 입력란에 입력을 할때마다 호출되는 콜백함수 등록하기
        document.querySelector("#id").addEventListener("input",(e)=>{
            //1. 입력한 아이디를 읽어온다.
            const inputId = e.target.value;
            //const inputId2 = document.querySelector("#id").value;
            //2.아이디가 영문자 소문자로 시작하고 4글자 이상 10글자 이하인지 판별하기
            const reg = /^[a-zA-Z].{3,9}$/; //아이디를 검증할 정규표현식 객체
            //정규표현식 객체의 test() 함수를 호출하면서 입력한 문자열을 전달하면 매칭여부가 리턴된다.
            isIdValid = reg.test(inputId);
            //3. 만일 유효하면 is-valid를 추가하고 is-invalid는 제거한다.
            //   만일 5글자 미만이면 is-invalid를 추가하고 is-valid는 제거한다.
            if(isIdValid){
                e.target.classList.add("is-valid");
                e.target.classList.remove("is-invalid");
            }else{
                e.target.classList.add("is-invalid");
                e.target.classList.remove("is-valid");
            }
            buttonChange();
        });

        document.querySelector("#email").addEventListener("input",(e)=>{
            //1.입력한 이메일 주소를 읽어온다.
            const inputEmail = e.target.value;
            //2.이메일을 검증할 정규표현식 객채 생성
            let regex = new RegExp('[a-z0-9]+@[a-z]+\.[a-z]{2,3}');
            //3.이메일 형식에 부합하는지 확인
            isEmailValid = regex.test(inputEmail);
            //4.부합하는지 여부에 따라서 is-valid와 is-invalid 클래스를 추가 혹은 제거 하기
            if(isEmailValid){
                e.target.classList.add("is-valid");
                e.target.classList.remove("is-invalid");
            }else{
                e.target.classList.add("is-invalid");
                e.target.classList.remove("is-valid");
            }
           buttonChange();
        });

        //버튼의 상태를 바꾸는 함수
        function buttonChange(){
            //폼 전체가 유효한지 여부
            isFormValid = isIdValid && isEmailValid;
            if(isFormValid){
                document.querySelector("button[type=submit]").removeAttribute("disabled");
            }else{
                document.querySelector("button[type=submit]").setAttribute("disabled", "disabled");
            }
        }
    </script>
</body>
</html>

공백이 아닌 한글자가 1번이상 반복되는 문자열을 모두 찾아낼수 있는 정규표현식 객체를 만들어보겠다.

const reg = /[^ ]+/g;

뒤에 붙은 g는 global의 약자이며 전역(global)에서 찾겠다는 의미로 쓰인다.

이해는 하겠는데 직접쓰려니 몬하겠다..

 

다시 이클립스를 켜고..

우리가 뭔가 로그인을 안한 상태로 무언가를 구매하려다가 구매를하는 순간에 로그인 페이지로 간다 그런다음 로그인을 하게 되면 그 구매했던 페이지 그대로 유지가 되어있는데 오늘 수업은 이것을 구현해 보겠다.

         /*
          *  로그인 페이지로 강제 리다일렉트 됬다면 
          *  로그인 성공후에 원래 가려던 목적지로 다시 보내야 하고
          *  GET 방식 전송 파라미터가 있다면 파라미터 정보도 같이 가지고 갈수 있도록 해야한다.
          */
         //원래 가려던 url 정보 읽어오기
         String url=req.getRequestURI();
         //GET 방식 전송 파라미터를 query 문자열로 읽어오기 ( a=xxx&b=xxx&c=xxx )
         String query=req.getQueryString();
         //특수 문자는 인코딩을 해야한다.
         String encodedUrl=null;
         if(query==null) {//전송 파라미터가 없다면 
            encodedUrl=URLEncoder.encode(url);
         }else {
            // 원래 목적지가 /test/xxx.jsp 라고 가정하면 아래와 같은 형식의 문자열을 만든다.
            // "/test/xxx.jsp?a=xxx&b=xxx ..."
            encodedUrl=URLEncoder.encode(url+"?"+query);
         }

원래 가려던 url정보를 읽어오고 GET 방식 전송파라미터를 query문자열로 읽어온다.

폼에 입력한 정보외에 추가로 같이 전송할 값이 있으면 input type = "hidden"을 활용한다.

 

file을 업로드하고 다운로드 할수있는 자료실을 만들어 볼 것이다.

 

먼저 자료실을 만들기 위해

num, writer, title, orgFileName, saveFileName, fileSize, regdate를 컬럼으로 board_file 이라는 table을 오라클에 생성해준 후에 FileDto/Dao를 만들어주었다.

package test.file.dto;

public class FileDto {
	private int num;
	private String writer;
	private String title;
	private String orgFileName;
	private String saveFileName;
	private long fileSize; //파일의 크기는 byte단위로 큰 정수를 쓰기 때문에 long int를 사용한다.
	private String regdate;
	
	//생성자
	public FileDto() {}

	public FileDto(int num, String writer, String title, String orgFileName, String saveFileName, long fileSize,
			String regdate) {
		super();
		this.num = num;
		this.writer = writer;
		this.title = title;
		this.orgFileName = orgFileName;
		this.saveFileName = saveFileName;
		this.fileSize = fileSize;
		this.regdate = regdate;
	}

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public String getWriter() {
		return writer;
	}

	public void setWriter(String writer) {
		this.writer = writer;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getOrgFileName() {
		return orgFileName;
	}

	public void setOrgFileName(String orgFileName) {
		this.orgFileName = orgFileName;
	}

	public String getSaveFileName() {
		return saveFileName;
	}

	public void setSaveFileName(String saveFileName) {
		this.saveFileName = saveFileName;
	}

	public long getFileSize() {
		return fileSize;
	}

	public void setFileSize(long fileSize) {
		this.fileSize = fileSize;
	}

	public String getRegdate() {
		return regdate;
	}

	public void setRegdate(String regdate) {
		this.regdate = regdate;
	}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/file/private/upload_form.jsp</title>
</head>
<body>
	<div class = "container">
		<h3>파일 업로드 폼 입니다.</h3>
		<!-- 
			파일 업로드 폼 작성법
			1. method = "post"
			2. enctype = "multipart/form-data"
			3. <input type = "file"/>
			-enctype = "multipart/form-data"가 설정된 폼을 전송하면
			 폼전송된 내용을 추출할 때 HttpServletRequest 객체로 추출을 할 수 없다.
			 MultipartRequest 객체를 이용해서 추출해야 한다.
		 -->
		 <form action="upload.jsp" method = "post" enctype = "multipart/form-data">
		 	<div>
		 		<label for="title">제목</label>
		 		<input type="text" name = "title" id = "title"/>
		 	</div>
		 	<div>
		 		<label for="myFile">첨부파일</label>
		 		<input type="file" name = "myFile" id = "myFile"/>
		 	</div>
		 	<button type = "submit">업로드</button>
		 </form>
	</div>
</body>
</html>

파일 업로드 할때는 파일명을 두개로 따로 관리해야한다. 원본파일명과 서버에 실제로 저장된 파일명 이렇게 따로 관리해야한다.

이번 자료실을 만들때에는 라이브러리를 사용해 보겠다.

다운받으려고 했는데 403떠서 servlets.com에서 받겠다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//파일 시스템 상에서 webapll 의 upload 폴더 까지의 절대경로를 얻어낸다.
	String realPath = application.getRealPath("/upload");
	//해당 경로를 access할 수 있는 파일 객체 생성
	File f = new File(realPath);
	if(!f.exists()){ //만일 폴더가 존재하지 않으면
		f.mkdir(); //upload 폴더 만들기
	}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/file/private/upload.jsp</title>
</head>
<body>

</body>
</html>

어떤 플랫폼인지(맥인지 리눅스인지 윈도우인지)  파일 시스템 상에서 webapp의 upload폴더 까지의 절대경로를 얻어낸다.

 

댓글