Learn & Record

JSP (from 폼 태그, 속성, 종류, input 태그, 속성, 종류, 회원가입 페이지, 카카오 주소 API, Java StringBuffer 이유, 코드, 유효성 검사, 쿠키, 장단점, 쿠키 동작 과정, 쿠키 값 출력) 본문

Dev/JSP

JSP (from 폼 태그, 속성, 종류, input 태그, 속성, 종류, 회원가입 페이지, 카카오 주소 API, Java StringBuffer 이유, 코드, 유효성 검사, 쿠키, 장단점, 쿠키 동작 과정, 쿠키 값 출력)

Walker_ 2024. 4. 17. 12:53

1. form 폼 태그

 - 사용자가 웹 브라우저를 통해 입력된 모든 데이터를 한 번에 보낼 수 있도록 사용하는 태그

 

 - form 태그 종류 : form, input, select, textarea

 

 - form 태그 속성 : action (전송 페이지 주소), method (폼 데이터가 전송되는 HTTP 방식), name (폼 식별 위한 이름)

 - , target(폼 처리 결과의 응답을 실행할 프레임을 설정), enctype(폼을 전송하는 콘텐츠 MME 유형 설정)

 - , accept-charset(문자 인코딩 설정)

 

 - GET 방식과 POST 방식의 차이

 - GET : URL 통해 전송, 제한적, 빠름, 보안 없음

 - POST : HTTP 헤더 속에 감춰서 전송, 제한 없음, 느림, 보안 있음

 

 - GET 방식은 지정된 리소스에서 데이터를 요청할 때, 즉 읽을 때 사용

 - POST 방식은 지정된 리소스에서 데이터를 처리할 때, 즉 C R U D를 할 때 사용

 

2. input 태그

 - 속성

 - type, name, value

 

 - 기본 외 속성

 - readonly, maxlength, size, disabled, checked

 

3. 회원가입 페이지

<%--
  Created by IntelliJ IDEA.
  User: 평일 오전 계정
  Date: 2024-04-17
  Time: 오전 9:13
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>회원가입</h3>
    <form action="form04_process.jsp" name="member" method="post">
        <p> 아이디 : <input type="text" name="id"> <input type="button" value="아이디 중복검사"></p>
        <p> 비밀번호 : <input type="password" name="passwd"></p>
        <p> 이름 : <input type="text" name="name"></p>
        <p> 연락처 : <select name="phone1">
            <option value="010">010</option>
            <option value="011">011</option>
            <option value="016">016</option>
            <option value="017">017</option>
            <option value="019">019</option>
        </select> - <input type="text" maxlength="4" size="4" name="phone2"> -
            <input type="text" maxlength="4" size="4" name="phone3"></p>
        <p> 성별 : <input type="radio" name="sex" value="남성" checked>남성
            <input type="radio" name="sex" value="여성">여성</p>
        <p> 취미 : 독서<input type="checkbox" value="독서" name="hobby" checked>
            운동<input type="checkbox" value="운동" name="hobby">
            영화<input type="checkbox" value="영화" name="hobby"></p>

        <p> 주소 : <input name="zipcode" id="zipcode" size="10" maxlength="7" readonly>
            <input type="button" value="우편번호 검색"><br />
            <input name="address01" id="address01" siez="70" maxlength="70" readonly>
            <input name="address02" id="address02" siez="70" maxlength="70"></p>

        <p> <textarea name="comment" cols="30" rows="3" placeholder="가입인사를 입력해주세요"></textarea></p>
        <p> <input type="submit" value="가입하기">
            <input type="reset" value="다시쓰기"></p>
    </form>
    <script src="https://spi.maps.daum.net/imap/map_js_init/postcode.v2.js"></script>
    <script>
        /*
    카카오 우편번호 검색 가이드 페이지 :  https://postcode.map.daum.net/guide
    getElementById() : html 에서 매개변수로 받은 id 값이 있는 요소를 반환.
    */
        function execDaumPostcode() {
            new daum.Postcode({
                oncomplete: function(data) {
                    // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

                    // 각 주소의 노출 규칙에 따라 주소를 조합한다.
                    // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
                    var fullAddr = ''; // 최종 주소 변수
                    var extraAddr = ''; // 조합형 주소 변수

                    // 사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
                    if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
                        fullAddr = data.roadAddress;
                    }
                    else { // 사용자가 지번 주소를 선택했을 경우(J)
                        fullAddr = data.jibunAddress;
                    }

                    // 사용자가 선택한 주소가 도로명 타입일때 조합한다.
                    if(data.userSelectedType === 'R'){
                        //법정동명이 있을 경우 추가한다.
                        if(data.bname !== ''){
                            extraAddr += data.bname;
                        }
                        // 건물명이 있을 경우 추가한다.
                        if(data.buildingName !== ''){
                            extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                        }
                        // 조합형주소의 유무에 따라 양쪽에 괄호를 추가하여 최종 주소를 만든다.
                        fullAddr += (extraAddr !== '' ? ' ('+ extraAddr +')' : '');
                    }

                    // 우편번호와 주소 정보를 해당 필드에 넣는다.
                    document.querySelector('input[name=zipcode]').value = data.zonecode; //5자리 새우편번호 사용
                    document.querySelector('input[name=address01]').value = fullAddr;

                    // 커서를 상세주소 필드로 이동한다.
                    document.querySelector('input[name=address02]').focus();
                }
            }).open();
        }
    </script>
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            document.querySelector('input[value="우편번호 검색"]').addEventListener('click', execDaumPostcode)
        })
    </script>
</body>
</html>

 

 

4. Java StringBuffer

String 클래스
    String을 선언하는 두 가지 방법.
    1) 생성자의 매개변수로 문자열 생성.
     String str1 = new String("abc");
     new 예약어를 사용해서 객체를 생성하는 경우는 "abc" 문자열을 위한 메모리가 할당되고 새로운 객체가 생성.


     2) 문자열 상수를 가르키는 방식.
     String str3 = "abc";
     생성자를 이용하지 않고 바로 문자열 상수를 가리키는 경우에는 기존에 만들어져 있던 문자열 상수의 메모리 값을 가르키게 됨.
     프로그램에서 사용되는 상수 값을 저장하는 공간을 상수 풀 constant pool 이라고 함.
String str1 = new String("abc"); // 생성자의 매개변수로 문자열 생성.
String str2 = new String("abc");

System.out.println(str1 == str2);    // false. 인스턴스가 매번 새로 생성되므로 str1과 str2는 주소 값이 다름.
System.out.println(str1.equals(str2)); // true. 문자열의 값은 같음.

String str3 = "abc"; // 상수 풀에 저장된 주소 값을 저장
String str4 = "abc";

System.out.println(str3 == str4);  //true. 문자열 abc는 상수 풀에 저장되어 있으므로 str3과 str4가 가르키는 주소 값이 같음.
System.out.println(str3.equals(str4)); //true.  문자열의 값도 같음.
다른 프로그래밍 언어는 문자열을 구현할 때 char[] 배열을 사용.
    자바는 String 클래스를 제공해 char[] 배열을 직접 구현하지 않아도 문자열을 사용할 수 있음.

    String 클래스의 구현 내용을 보면 private final char value[] 라고 선언된 char 배열이 있음.
    프로그램에서 String s = new String("abc")라고 쓰면 abc는 String 클래스의 value 변수에 저장이 됨.
    value 변수 final로 선언이 되어 있어서 값을 변경할 수 없음. 이를 불변 immutable 이러고 함.

    프로그램에서 두 개의 문자열을 연결하면, 둘 중 하나의 문자열이 변경되는게 아니라 두 문자열이 연결된 새로운 문자열이 생성.
     
String javaStr = new String("java");
String androidStr = new String("android");
System.out.println(javaStr); // java
System.out.println("처음 문자열 주소 값: "+ System.identityHashCode(javaStr)); // 처음 문자열 주소 값: 2003749087

javaStr = javaStr.concat(androidStr); //java 와 android 문자열의 연결

System.out.println(javaStr); // javaandroid
System.out.println("연결된 문자열 주소 값: " +System.identityHashCode(javaStr)); // 연결된 문자열 주소 값: 1480010240
//        // 문자열의 값을 변경하는 경우.
//        javaStr = "new java";
//        System.out.println(javaStr); // new java
//        System.out.println("값을 변경한 문자열 주소 값: " +System.identityHashCode(javaStr)); // 값을 변경한 문자열 주소 값: 81628611
        

 

StringBuffer 와 StringBuilder 클래스 활용
프로그램을 만들다 보면 문자열을 변경하거나 연결해야 하는 경우가 많음.
하지만 String 클래스는 한번 생성되면 그 내부의 문자열이 변경되지 않기 때문에
String 클래스를 사용하여 계속 문자열을 연결하거나 변경하는 프로그램을 작성하면 메모리가 많이 낭비.
이 문제를 해결하는 것이 StringBuffer 와 StringBuilder 클래스.

StringBuffer 와 StringBuilder 클래스는 내부에 변경가능한(final이 아닌) char[]를 변수로 가지고 있음.
두 클래스를 사용하여 문자열을 연결하면 기존에 사용하던 char[] 배열이 확장되므로 추가 메모리를 사용하지 않음.
따라서 문자열을 연결하거나 변경할 경우 두 클래스 중 하나를 사용하면 됨.

두 클래스의 차이는 여러 작업(스레드)이 동시에 문자열을 변경하려 할 때 문자열이 안전하게 변경되도록 보장해 주는가 그렇지 않은가의 차이.
StringBuffer 클래스는 문자열이 안전하게 변경되도록 보장하지만, StringBuilder 클래스는 보장되지 않음.
따로 스레드를 생성하는 멀티스레드 프로그램이 아니라면 StringBuilder를 사용하는 것이 실행 속도가 더 빠름.
 
String javaStr = new String("Java");
System.out.println("javaStr 문자열 주소 :" + System.identityHashCode(javaStr));// 2003749087. 처음 생성된 메모리 주소

StringBuilder buffer = new StringBuilder(javaStr); //String으로 부터 StringBuilder생성
System.out.println("연산 전 buffer 메모리 주소:" + System.identityHashCode(buffer));// 1480010240. buffer 메모리 주소
buffer.append(" and");                // 문자열 추가
buffer.append(" android");            // 문자열 추가
buffer.append(" programming is fun!!!"); //문자열 추가
System.out.println("연산 후 buffer 메모리 주소:" + System.identityHashCode(buffer));// 1480010240. buffer 메모리 주소

javaStr = buffer.toString(); //String 클래스로 반환
System.out.println(javaStr); // Java and android programming is fun!!!
System.out.println("새로 만들어진 javaStr 문자열 주소 :" + System.identityHashCode(javaStr)); // 81628611. 새로 생성된 메모리 주소}
 

5. 유효성 검사

 - 사용자가 폼 페이지에서 입력한 데이터 값이 서버로 전송되기 전에 특정 규칙에 맞게 입력되었는지 검증하는 것

 - 정규표현식을 이용하기도 함

<form action="validation01_process.jsp" name="member" method="post">
    <p> 아이디 : <input type="text" name="id"> <input type="button" value="아이디 중복검사"></p>
    <p> 비밀번호 : <input type="password" name="passwd"></p>
</form>
<script>
    document.addEventListener('DOMContentLoaded', function () {
        const form = document.member;
        const btn = document.querySelector('input[type=button]')

        document.querySelector('input[value="우편번호 검색"]').addEventListener('click', execDaumPostcode)

        btn.addEventListener('click', function () {
            if (form.id.value === '') {
                alert('아이디를 입력해주세요.')
                form.id.focus();
                return;
            } else if (form.passwd.value === '') {
                alert('비밀번호를 입력해주세요')
                form.passwd.focus();
                return;
            } else if (form.passwd.value.indexOf(form.id.value) !== -1) {
                alert('비밀번호는 ID를 포함 할 수 없습니다.')
                form.passwd.focus();
                return;
            }
            form.submit();
        })
    })
</script>
 

6. 쿠키 

 - 브라우저(HTTP)는 기본적으로 서버와 연결이 지속되는 것이 아니라 

 - 필요한 경우 request 주고 받는 것

 

  - 장점 : 클라이언트의 일정 폴더에 정보를 저장하기 때문에 웹 서버의 부하를 줄일 수 있음

  - 단점 : 웹브라우저가 접속했던 웹 사이트에 관한 정보와 개인 정보가 기록되기 때문에 보안에 문제가 있음

 

 - 쿠키의 동작 과정

 - 쿠키 생성 > 쿠키 저장 > 쿠키 전송

 

 - 웹 브라우저에 쿠키가 저장되면 웹 브라우저는 쿠키가 삭제되기 전까지 웹 서버에 쿠키를 전송

 

 - 1) 쿠키 생성

 - 쿠키를 사용하려면 먼저 클래스를 사용하여 쿠키를 생성해야 함

Cooke Cookie(String name, String value)

 

 - 첫번째 매개변수 name은 쿠키를 식별하기 위한 이름

 - 두번째 매개변수 value는 쿠키 값

 

 - 쿠키를 생성한 후 반드시 response 내장 객체에 addCookie() 메서드로 쿠키를 생성

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
  <form action="cookie01_process.jsp" method="post">
      <p>아 이 디 : <input type="text" name="id"></p>
      <p>비밀번호 : <input type="text" name="passwd"></p>
      <p><input type="submit" value="전송"></p>
  </form>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
  <%--
  쿠키 생성하기
  1) 전송된 아이디와 비밀번호가 일치하면, 쿠키 이름 userId, userPw에 값을 설정하도록 Cookie 객체를 생성
  --%>
<body>
  <%
    String userId = request.getParameter("id");
    String userPw = request.getParameter("passwd");

    if (userId.equals("admin") && userPw.equals("1234")) { // 로그인 정보가 맞으면
      Cookie cookidId = new Cookie("ueseId", userId); // 쿠키 생성. Cookie 클래스를 이용해서 쿠키 객체 생성
      Cookie cookiePw = new Cookie("userPw", userPw);
      response.addCookie(cookidId); // response할 때 쿠키도 같이 보낼 것
      response.addCookie(cookiePw);

      out.println("쿠키 생성이 성공했습니다<br>");
      out.println(userId + "님 환영합니다.");
    } else {
      out.println("쿠키 생성이 실패했습니다.");
    }
  %>

</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
  <%--
  쿠키 객체에 저장된 모든 쿠키 값 가져와 출력하기
  1) 쿠키 정보를 얻어오도록 request 내장 객체의 getCookies() 메서드 작성
  2) 얻어온 쿠키 정보의 개수를 출력하도록 Cookie 객체의 length를 작성
  3) 얻어온 쿠키 정보에서 쿠키 이름과 값을 하나씩 출력하도록 Cookie 객체의 getName(), getValue() 메서드 작성
  --%>
  <%
    boolean isLogin = false;
    String userId = "";
    Cookie[] cookies = request.getCookies(); // request에서 쿠키를 얻어옴
    out.println("현재 설정된 쿠키의 개수 => " + cookies.length + "<br>");
    out.println("==============================<br>");
    for (int i = 0; i < cookies.length; i++) {
      out.println("설정된 쿠키의 속성 이름 [ " + i + " ] : " + cookies[i].getName() + "<br>");
      out.println("설정된 쿠키의 속성 값 [ " + i + " ] : " + cookies[i].getValue() + "<br>");
      out.println("-------------------------------------<br>");

      if (cookies[i].getName().equals("userId") && cookies[i].getValue() != null) {
          //userId라는 쿠키 이름이 있고 value가 null이 아니면 로그인한 것으로 간주
          isLogin = true;
          userId = cookies[i].getValue();
      }
    }

    if (isLogin) {
      out.print(userId + "님이 로그인 중입니다.");
    } else {
      out.print("로그인 상태가 아닙니다.");
    }
  %>
</body>
</html>

 


공부 과정을 정리한 것이라 내용이 부족할 수 있습니다.

부족한 내용은 추가 자료들로 보충해주시면 좋을 것 같습니다.

읽어주셔서 감사합니다 :)