1. 소켓 (Socket)

- TCP 프로토콜을 사용하여 통신을 하는데 쓰임(TCP의 기본 : IP / Port 번호가 필요)

- 네트워크 상에서 서버, 클라이언트 두 개의 프로그램이 특정 포트를 통해 양방향 통신이 간으하도록 만들어주는 소프트웨어 장치.

- java.net에서 ServerSocket 클래스(서버측)와 Socket 클래스(서버측 + 클라이언트측)를 이용하여 서버와 클라이언트 간의 통신을 가능하게 만듦.

- 자바 채팅 프로그램의 기초는 서버 - 클라이언트 간의 연결이 가능해야 하는데, 소켓 프로그래밍으로 가능함(하나의 서버에 여러 개의 클라이언트가 접속하는 멀티 클라이언트 채팅 프로그램도 가능).

 

* IP : 컴퓨터마다 가지고 있는 고유의 주소

  port : 통신을 위한 연결 라인

 

 

2. 자바 소켓 프로그래밍 (TCP)

- 소켓 프로그래밍 중의 하나. 스트림 통신 프로토콜.

- 연결 지향 프로토콜 : 양 쪽의 소켓이 연결된 상태여야 함.

- 송신 > 수신시 차례대로, 연결된 순서대로 데이터를 교환해야 함(신뢰성이 높음).

- java.net.ServerSocket : 서버측에서 클라이언트의 접속에 대기하기 위해 필요한 클래스.

- java.net.Socket : 서버 - 클라이언트 간 통신하기 위해 필요한 클래스.

 

 

3. 자바 소켓 프로그래밍 실행 순서

 

 

4. 자바 소켓 프로그래밍 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package lesson01.exam02.server;
 
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
 
//간단한 소켓 서버 프로그램. 소켓 연결이 되면 현재 시간을 출력하고 연결된 소켓을 닫음
public class SimpleSockterServer {
    static final int PORT = 8888;
    
    public static void main(String[] args) {
        
        try{
//          ServerSockter 생성 (포트 번호를 사용하는 서버 소켓)
//          서버용 소켓. 통신은 불가능하고 클라이언트의 연결만을 기다림
//          ServerSocket 소켓변수명 = new ServerSocket(포트번호);
            ServerSocket serverSocket = new ServerSocket(PORT);
            
            System.out.println("console> 서버 : 클라이언트의 접속을 기다립니다.");
            
//          소켓 서버가 종료될 때까지 무한루프
            while(true) {
//              클라이언트와 연결이 되면 실제로 통신을 하기 위해 만들어야 하는 소켓
//              서버소켓.accept();
//              클라이언트 소켓에서 요청을 할 때까지 소켓 서버가 대기 상태가 됨
//              클라이언트 소켓 수가 많아질 시 요청 횟수가 증가하면서 스레드가 늘어나면 
//              서버 자원을 많이 소모함
//              => 스레드풀(Thread Pool)이 등장하게 됨 : 다중 접속 처리가 원활해짐
                Socket socket = serverSocket.accept();
                
                System.out.println("console> 서버 " + socket.getInetAddress() + " 클라이언트와 " +
                                    socket.getLocalPort() + " 포트로 연결되었습니다.");
                
                try {
//                  응답을 통해 스트림을 얻어옴(서버에서 클라이언트의 입력을 받아들임)
                    OutputStream stream = socket.getOutputStream();
//                  현재 날짜를 받아와 출력함
                    stream.write(new Date().toString().getBytes());
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
//                  소켓은 반드시 닫아야 함
                    socket.close();
                }
            }

//        예외처리

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package lesson01.exam02.server;
 
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
 
//소켓 클라이언트 프로그램. 소켓 서버에 접속하여 결과 출력하고 프로그램을 종료함
//서버 소켓은 필요 없고, InputStream을 OutputStream으로, InputStreamReader를 OutputStreamWriter로 바꾸면 됨
//서버 소켓에서 생성한 서버의 IP, port번호를 알고 있어야 함
public class SimpleSocketClient {
    static final int PORT = 8888;
    
    public static void main(String[] args) {
        try {
//          소켓 생성
            Socket socket = new Socket("localhost", PORT);
            
            System.out.println("console> PORT(" + PORT + ") 로 접속을 시도합니다.");
            
//          스트림을 얻어옴
            InputStream stream = socket.getInputStream();
//          스트림을 래핑함(클라이언트에서 서버로부터 수신 받은 메세지 받아들임)
            BufferedReader br = new BufferedReader(new InputStreamReader(stream));
            
//          결과를 읽음(서버로부터 온 메세지 수신)
            String response = br.readLine();
            
            System.out.println("console> 수신 response : " + response);
            
//          소켓 닫음
            socket.close();
            
//          프로그램 종료
            System.exit(0);

//        예외처리 

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
cs

 

 클래스명

 설명

 특징

 InputStream

 byte 단위로 입력 받는 최상위 클래스

 객체화가 불가능한 추상 클래스.

 (상속 받아 사용해야 함)

 OutputStream

 byte 단위로 출력 받는 최상위 클래스

 Reader

 문자 단위 입력 스트림

 Writer

 문자 단위 출력 스트림

 BufferReader

 Buffer에 있는 IO 클래스. 읽는 클래스

 

 BufferedWriter

 Buffer에 있는 IO 클래스. 쓰는 클래스

 

 

1. 업캐스팅 (Upcasting)

서브클래스가 슈퍼클래스의 타입으로 형 변환되는 것

객체 내의 모든 멤버(변수, 메소드)에 접근할 수 없고, 슈퍼클래스의 멤버(변수, 메소드)에만 접근이 가능함

자식 클래스의 타입으로 업캐스팅을 했을 시, 상속에 의해 자식 클래스 + 부모 클래스 둘 다 호출이 가능함

자동적 형변환

 

 

a. 변수를 업캐스팅

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package kr.or.example.A;
 
public class Casting_Main {
    public static void main(String[] args) {
//      변수 선언, 초기화
        int a = 10;
        double b;
        
        System.out.println("console> before a : " + a);
        
//      상위 형인 double 형으로 변수 업캐스팅
        b = (double) a;
        
        System.out.println("console> after a : " + a);
        System.out.println("console> b : " + b);
    }
}
cs

 

 

 

b. 클래스를 업캐스팅

1
2
3
4
5
6
7
8
9
10
11
package kr.or.example.A;
 
public class Person {
    String name;
    String id;
    
//  생성자에서 name 변수 초기화
    public Person(String name) {
        this.name = name;
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package kr.or.example.A;
 
//Person 클래스를 상속받는 Student 클래스
public class Student extends Person {
    String grade;
    String department;
 
//  생성자 호출시 super 키워드를 이용하여 부모 클래스의 동명 메소드 호출
    public Student(String name) {
        super(name);
        
        System.out.println("console> name : " + name);
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package kr.or.example.A;
 
public class Person_Main {
    public static void main(String[] args) {
//      부모 클래스 객체 생성
        Person person;
//      자식 클래스 객체를 생성하고 인자를 넣어줌
        Student student = new Student("미니");
        
//      자식 클래스 객체 인스턴스를 부모 클래스 객체 인스턴스로 형을 변환함(업캐스팅)
        person = student;
        
//      Person 클래스 생성자에서 부모 클래스의 메소드를 호출했지만
//      자식 > 부모가 아닌 자식 = 부모가 되었기 때문에 출력 시
//      자식 클래스의 내용 먼저 출력된다(콘솔 창에서 출력 가능).
        System.out.println(person.name);
    }
}
cs

 

 

 

 

* instanceof 연산자

업캐스팅을 한 경우 레퍼런스가 가리키는 실제 객체가 어떤 클래스 타입인지 구분이 어려워지기 때문에 사용

 

 

2. 다운캐스팅 (Downcasting)

업캐스팅 되었던 슈퍼클래스가 다시 본래의 서브클래스 형으로 돌아오는 것)

명시적으로 타입을 지정해야 캐스팅이 됨

1. final

ㄱ. 변수에 붙이는 경우 : 변수 선언시 마지막 값이 되도록(상수) 만들어준다. 처음 선언시의 초기화만 가능하고, 보통 상수로 사용할 때에는 static을 붙여 같이 사용한다. => 상수명은 전부 대문자로만 이루어져야 함

 

ㄴ. 메소드에 붙이는 경우 : 메소드에 final을 선언하면 그 메소드가 포함된 클래스를 상속받은 클래스에서 오버라이딩을 통해 재정의할 수없는 메소드가 된다.(final 메소드에 오버라이딩 시도시 에러 발생)

1
2
3
4
5
6
7
8
9
10
package kr.or.ksmart.A;
 
public class FinalTest {
    String str = "홍길동";
        
//    String형 str 변수를 리턴하는 name 메소드 선언
    public final String name() {
        return str;
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
package kr.or.ksmart.A;
 
public class FinalTest_Extend extends FinalTest {
//    FinaltTest 클래스를 상속받는 FinalTest_Extend 클래스
//    name 메소드를 오버라이딩 하지 못한다(컴파일 에러가 남)
//    => final로 정의해줬기 때문에
    public String name() {
        return "강감찬";
    }
}
cs

 

 

(실제로 이클립스 상에서 final을 수정하거나 삭제하라는 오류가 뜬다)

 

ㄷ. 클래스에 붙이는 경우 : final + 접근제한자 + 클래스명

abstract와 함께 사용 불가 - final은 상속 불가인데 abstract는 추상 클래스 생성시 사용하는 내용이므로 공존할 수 없음(컴파일 에러)

 

 

 

2. static

클래스나 인스턴스 생성시 각 인스턴스들은 독립적이기 때문에 서로 다른 값을 유지하는 경우에 따라 각각의 인스턴스들이 공통적으로 같은 값을 유지해야 하는 경우에 사용.

static이 붙은 변수는 클래스가 메모리에 올라갈 때 인스턴스가 자동적으로 생성되기 때문에 인스턴스를 생성할 필요가 없음.

static 메소드는 인스턴스 생성 없이 호출이 가능하나, 보통은 인스턴스 변수를 생성해야만 호출이 가능하므로 static 메소드 내에서는 인스턴스 변수를 허용함(인스턴스 변수가 존재한다 > static 변수가 이미 메모리에 있기 때문에)

먼저 클래스 멤버 변수중 모든 인스턴스에 공통된 값을 유지해야 하는 것이 있는지 살펴보고 static을 붙임(작성한 메소드 중 인스턴스 변수를 사용하지 않는 메소드에 대해 static을 붙임)

보통 클래스 변수와 관련된 작업을 하는 메소드나 변수에 static을 붙임.

 

 

3. final과 static의 차이

final은 절대 변하지 않는 상수이나 static은 어느 클래스 & 메소드에서나 사용 가능한 공용일 뿐 변수이기 때문에 언제든지 바뀔 수 있는 가변성을 가지고 있다.

1. 홈페이지 접속

 

- https://www.oracle.com/ 접속 > Downloads > Java SE 클릭

 

 

2. 다운로드

 

- JDK를 다운받는다.

 

* JDK > JRE : JRE는 기본으로 컴퓨터에 깔려있기 때문에 JDK를 설치해야 한다.

   실수로 컴퓨터 내의 JRE를 삭제했을 시에는 오라클 홈페이지에서 JRE만 따로 다운로드 가능.

 

 

3. 다운 받은 exe 파일 실행

- 분할한 파티션을 용이하게 사용하기 위해 C 드라이브가 아닌 D 드라이브에 Java8 이라는 폴더를 새로 만들고 JDK를 다운받았다.

- 다운 받은 Java8 폴더를 살펴보면 JDK만을 설치했을 때에도 자동으로 JDK 폴더 안에 JRE가 생성되어 있는 것을 확인할 수 있다. (JDK > JRE)

 

- JRE는 JDK 폴더 내의 JRE 폴더에 덮어쓰기 해줬다.

 

- 이러한 창이 뜨면 Close를 눌러준다.

 

 

4. 자바가 설치되었는지 cmd로 확인

- cmd를 열고 가장 상위 폴더인 C드라이브로 올라가 컴퓨터의 자바 버전을 확인한다. (1.8.0_102)

 

- 명령어를 확인하여 자바를 컴파일하는 javac(자바 컴파일러)가 존재하는지, 자바 컴파일러 버전이 자바 버전과 일치하는지 확인한다.(일치해야 함)

자바 클래스에서 PrintWriter 객체를 선언한 후,

해당 객체의 인스턴스를 통해 println 메소드를 이용하여 response 범위로 alert을 선언했는데

인코딩이 되지 않았다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
protected void doPost(HttpServletRequest request, HttpServletResponse response)
                                        throws ServletException, IOException {
    String url = "";
    
    //PrintWrtier에서 한글 인코딩이 깨지는 경우 셋팅
    //반드시 PrintWriter 객체 선언하기 전에 셋팅해줘야 함
    response.setCharacterEncoding("utf-8");
    response.setContentType("text/html; charset=UTF-8");
                
    //alert 띄우고 리스트로 돌아가서 리스트 새로고침
    PrintWriter out = response.getWriter();
                
    url = "GetAllBookInfo";
                
    out.println("<script>");
    out.println("alert('도서를 삭제했습니다.')");
    out.println("location.href='" + url + "';");
    out.println("</script>");
    out.flush();
}
cs

 

PrintWriter 객체를 선언한 후 CharacterEncoding, ContentType을 setter로 초기화 했었는데도 전혀 되지 않았다.

반드시 PrintWriter 객체를 선언하기 에 response 객체 메소드들을 설정해줘야 인코딩이 깨지지 않는다.

1. 서블릿으로 파라미터를 보내는 form.html 페이지

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Form.html</title>
</head>
<body>
 
<!-- 필터는 post 방식으로 받을 때에만 적용됨. -->
<!-- form.do라는 서블릿으로 파라미터들을 보냄. -->
<form action="form.do" method="post" name="textform"> 
    Name : <input type="text" name="name"><br⁄> 
    <input type="submit" value="전송" name="submitbtn"> 
</form> 
 
</body>
</html>
cs

 

2. WEB-INF/web.xml 파일에 필터 매핑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns:web="http://xmlns.jcp.org/xml/ns/javaee" 
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
                             http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name>Archetype Created Web Application</display-name>
  
  <!-- 서블릿을 매핑하듯 필터도 같은 방식으로 WEB-INF/web.xml 파일에 매핑함. -->
  <!-- filter-name : 필터 클래스 파일 이름. -->
  <!-- filter-class : 필터 클래스 경로(애플리케이션 내에서의 절대 경로). -->
  <!-- init-param : 필터 클래스에서 사용하려는 파라미터의 이름, 값을 web.xml에서 미리 지정할 수 있음. -->
  <filter>
      <filter-name>HangulEncodingFilter</filter-name>
      <filter-class>com.filter.HangulEncodingFilter</filter-class>
      <init-param>
          <param-name>encoding</param-name>
          <param-value>UTF-8</param-value>
      </init-param>      
  </filter>
  
  <!-- url-pattern : 해당 애플리케이션 내에서 필터를 적용시키고자 하는 범위. -->
  <!--                 /* - 애플리케이션 내 모든 post 방식에서 적용(servlet, jsp 구분 없이). -->
  <!--                 /*.do - 애플리케이션 내 *.do로 이름을 지은 서블릿 post 메소드만 적용. -->
  <!-- servlet-name : 애플리케이션 내 특정 서블릿에만 적용할 때 씀.-->
  <filter-mapping>
      <filter-name>HangulEncodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>
cs

 

3. form.do 서블릿이 실행되기 전에 실행되는 filter 클래스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.filter;
 
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
 
/**
 * Servlet Filter implementation class ExampleBFilter
 */
public class HangulEncodingFilter implements Filter {
 
    //인코딩을 수행할 인코딩 캐릭터 셋 지정
    String encoding;
    
    //필터 설정 관리자
    FilterConfig filterConfig;
    
    /**
     * Default constructor. 
     */
    public HangulEncodingFilter() {
        // TODO Auto-generated constructor stub
    }
 
    /**
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig fConfig) throws ServletException {
        //초기화
        //getInitParameter() : web.xml에 초기화해서 지정한 파라미터 값을 불러오는 메소드. 
        this.filterConfig = fConfig;
        this.encoding = fConfig.getInitParameter("encoding");
        
//        System.out.println("debug > init %%%%%%%%%");
    }    
    
    /**
     * @see Filter#destroy()
     */
    //destroy : 웹 애플리케이션이 끝날 때 같이 끝남
    public void destroy() {
        
        this.encoding = null;
        this.filterConfig = null;
        
//        System.out.println("debug > destroy %%%%%%%%%%%");
    }
 
    /**
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
                throws IOException, ServletException {
 
        //request.setCharacterEncoding("utf-8");
        
//        System.out.println("characterEncoding : " + request.getCharacterEncoding());
        
        if (request.getCharacterEncoding() == null) {
            if (encoding != null
                request.setCharacterEncoding(encoding);
        }
        
        chain.doFilter(request, response);
    }
}
cs

 

4. form.do 서블릿

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import java.io.IOException;
 
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
@WebServlet("/form.do")
public class MyServlet extends HttpServlet {
    
    public MyServlet() {
        super();
    }
       
//    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
//                throws ServletException, IOException {
//        // TODO Auto-generated method stub
//    }
 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
                throws ServletException, IOException {
        
        // 한글깨짐방지
        // 한글 필터를 쓰면 아래것은 쓸모없다
        // request.setCharacterEncoding("utf-8");
 
        // 아래 2줄 넣으면 한글 무조건 깨진다.
        // PrintWriter out = response.getWriter();
        // out.println("name : " + name);        
        String name = request.getParameter("name");
        
//        System.out.println("Debug> name : " + name);
        
        request.setAttribute("name", name);
        
        RequestDispatcher rd = request.getRequestDispatcher("result.jsp");    
        rd.forward(request, response);
    }
}
cs

 

5. 서블릿에서 파라미터를 받아 출력하는 jsp 페이지

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 
<%@ page isELIgnored="false" %>
    
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>화면 결과 출력 예제</title>
</head>
<body>
    name : ${name}
</body>
</html>
cs

1. 정의

여과기 역할을 하는 프로그램.

서블릿 클래스가 실행되기 전/후에 어떤 데이터를 미리 실행시키거나, 아예 가로채서 서블릿이 실행되지 못하도록 한다.

자바 클래스 형태로 구현해야 한다.

http 요청, 응답을 변경 가능하고 재사용이 가능한 코드. 객체 형태를 띈다.

request와 최종 자원(jsp / servlet) 사이에 위치한다.


* 보통은 클라이언트 - 자원 사이에 필터가 1개가 존재는게 일반적이나, 다수도 가능하다.



2. 구조

1) 단일 필터 구조




2) 다중 필터 구조



3. 인터페이스

- Filter : 클라이언트와 최종 자원 사이의 객체 인터페이스

- ServletRequestWrapper : 필터가 요청을 변경하거나, 응답을 변경한 결과를 저장할 래퍼 클래스

- ServletResponseWrapper : 필터가 요청을 변경하거나, 응답을 변경한 결과를 저장할 래퍼 클래스



4. 용도

- 데이터 인코딩 : 서블릿 doPost 메소드에서 한글 인코딩을 대신 하는 역할

- 세션 데이터 인증 : 로그인 세션 체크

- 이벤트, 공지 등 팝업 추가



5. 예제


* 순서 : html -> filter 클래스 -> servlet 클래스 -> view jsp 페이지


1) 시작이 되는 html 페이지

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>필터 적용 예제</title>
</head>
<body>
<form method="post" action="ExampleS.do">
    이름 : <input type="text" name="name">
    <input type="submit" value="확인">
</form> 
</body>
</html>
cs


2) filter 클래스 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.filter;
 
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
 
/**
 * Servlet Filter implementation class ExampleBFilter
 */
//@WebFilter("/ExampleBFilter")
public class ExampleBFilter implements Filter {
 
    /**
     * Default constructor. 
     */
    public ExampleBFilter() {
        // TODO Auto-generated constructor stub
    }
 
    /**
     * @see Filter#destroy()
     */
    public void destroy() {
        // TODO Auto-generated method stub
    }
 
    /**
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    // doFilter 메소드에서 한글 인코딩을 해줬다.
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
        
        request.setCharacterEncoding("utf-8");
        
        chain.doFilter(request, response);
    }
 
    /**
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig fConfig) throws ServletException {
        // TODO Auto-generated method stub
    }
}
cs


3) web.xml 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
 <filter>
    <filter-name>ExampleBFilter</filter-name>
     <filter-class>com.filter.ExampleBFilter</filter-class>
 </filter>
  
 <filter-mapping>
    <filter-name>ExampleBFilter</filter-name>
    <!-- url-pattern : 같은 웹 애플리케이션 디렉터리 내 웹 컴포넌트에 적용할 때 -->
    <!--                 (ex. /* : 모든 웹 컴포넌트, *.jsp : 디렉터리 내의 jsp페이지에만 적용-->
    <!-- servlet-name : 특정 서블릿에만 적용할 때-->
    <url-pattern>/*</url-pattern>
 </filter-mapping>
cs


4) servlet 클래스 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.servlet;
 
import java.io.IOException;
 
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/**
 * Servlet implementation class ExampleSServlet
 */
@WebServlet("/ExampleS.do")
public class ExampleSServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ExampleSServlet() {
        super();
        // TODO Auto-generated constructor stub
    }
 
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
                    throws ServletException, IOException {
//        System.out.println("############");
        
        String name = request.getParameter("name");
        
//        System.out.println("name : " + name);
        
        request.setAttribute("name", name);
        
//        System.out.println("after name : " + request.getAttribute("name"));
        
        RequestDispatcher rd = request.getRequestDispatcher("result.jsp");
        
        rd.forward(request, response);
    }
}
cs


5) view 용 jsp 페이지 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>화면 결과 출력 예제</title>
</head>
<body>
    name : ${name}
</body>
</html>
cs


'BackEnd > Java' 카테고리의 다른 글

Java :: PrintWriter 객체 인코딩 오류시  (0) 2016.08.04
Servlet :: 필터로 한글 인코딩 설정하기  (0) 2016.06.18
Java :: Random 함수  (0) 2016.06.05
Jsp :: jsp 내장객체  (0) 2016.06.03
Java :: JDBC DAO 소스  (0) 2016.04.26

1. java.util.Random

new Randon() 을 사용하여 객체 생성

다양한 메소드를 사용하여 원하는 타입의 random 값을 사용 가능

주사위를 던지거나 카드를 섞는 난수를 사용할 때 주로 사용

 

 

종류 

 nextBoolean()

 nextDouble()

 nextBytes(byte[] bytes)

 nextFloat()

 nextGaussian()

 nextInt()

 nextInt(int n)

 nextLong()

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.random;
 
import java.util.Random;
 
public class ExampleA_Main {
    public static void main(String[] args) {
    
        Random random = new Random();
        
        // nextBoolean() : true와 false중 랜덤 출력
        System.out.println("nextBoolean() : " + random.nextBoolean());
        System.out.println("nextFloat() : " + random.nextFloat());
        System.out.println("nextInt() : " + random.nextInt());
        // nextInt(int n) : n 이내의 정수를 랜덤으로 출력
        System.out.println("nextInt(10) : " + random.nextInt(10));
        System.out.println("nextDouble() : " + random.nextDouble());
        System.out.println("nextLong() : " + random.nextLong());
    }
}
cs

 

 

2. java.util.Math

double 타입으로 리턴하기 때문에 int로 형을 변환하여 사용 가능

주로 최소값과 최대값을 구할 때 사용,

((int) Math.random() * (최대값 - 최소값 + 1) 수식을 사용하여 최소값 ~ 최대값 범위를 지정

'BackEnd > Java' 카테고리의 다른 글

Servlet :: 필터로 한글 인코딩 설정하기  (0) 2016.06.18
Servlet :: 필터 (Filter)  (1) 2016.06.10
Jsp :: jsp 내장객체  (0) 2016.06.03
Java :: JDBC DAO 소스  (0) 2016.04.26
Java :: 패키지 이름 명명 규칙  (0) 2016.04.02

1. 정의

모든 jsp는 서블릿 컨테이너에 의해서 서블릿으로 변환된다.

서블릿은 자바 프로그램이기 때문에 객체를 선언하여 인스턴스 변수를 개발자 마음대로 정의하여 사용할 수 있으나,

jsp는 서블릿이 상속받는 HttpServletRequest, HttpServletResponse 클래스에 선언된 객체들을 사용해야 한다.

(모든 jsp 파일들은 결국 서블릿으로 변환되기 때문에 = 서블릿이기 때문에)

 

서블릿에서는 직접 인스턴스 변수명을 마음대로 정의 가능하나 jsp는 서블릿으로 이루어져 있기 때문에(하위 단계라고 생각하는게 이해가 빠름) 서블릿에서 상속받은 HttpServletRequest, HttpServletResponse 클래스 안의 객체들을 사용할 수밖에 없다. (인스턴스 변수명이 이미 서블릿 안에서 지정되어 있다는 이야기)

 

별도의 import 없이 자유롭게 사용이 가능하고 스크립트릿 내에서 변수 이름으로 사용해서는 안 된다.

 

 

2. 속성

 범위

선언부

설명

 Page

pageContext

현재 페이지 내

해당 페이지가 클라이언트에 서비스를 제공하는 동안만 유효

 Request

request

클라이언트로부터 요청을 받아 처리하는 동안

( forward, include 이용시 여러 페이지에서 요청 정보가 유지되므로 request 영역의 속성을 여러 페이지에서 공유 가능 )

 Response

response 

클라이언트로 요청을 보내는 동안

request 객체와 반대의 속성

헤더 정보 설정, 오류 발생, 쿠키 추가 등에도 쓰임

 Session

session

한 브라우저 내 세션이 유지되는 동안

1 브라우저당 1 세션이 생성되므로 같은 웹 브라우저 내에서 실행되는 페이지들이 속성을 공유 가능

 Application

application

해당 웹 애플리케이션이 start -> stop 될 때까지

가장 범위가 큼

 

 

- removeAttribute(key) : 해당 정보 제거. key 값으로 등록된 속성을 제거

'BackEnd > Java' 카테고리의 다른 글

Servlet :: 필터 (Filter)  (1) 2016.06.10
Java :: Random 함수  (0) 2016.06.05
Java :: JDBC DAO 소스  (0) 2016.04.26
Java :: 패키지 이름 명명 규칙  (0) 2016.04.02
Servlet :: Servlet(서블릿) 이란?  (0) 2016.04.01

Servlet + jstl + JDBC 를 이용한 게시판 소스 중 JDBC DAO 파일 소스 전문 JDBC를 공부하다가, 

Mybatis로 발전해서 게시판 프로젝트 공부를 했었는데

다시 JDBC를 이용하여 혼자 힘으로 해보려니 조금 어려운 면이 있기도 했다.

 

확실히 Mybatis가 편하다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
package com.dao;
 
import java.sql.*;
import java.util.*;
 
import com.vo.Person;
 
public class PersonDAO implements PersonDAOImpl {
 
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    
    String url = "jdbc:mysql://localhost:3306/basicjsp?useUnicode=true&amp;characterEncoding=utf8&amp;zeroDateTimeBehavior=convertToNull";
    String id = "jspid";
    String pass = "jsppass";
    
    String sql = "";
        
    public void connectDB() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            
            conn = DriverManager.getConnection(url, id, pass);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public List<HashMap<String, Object>> selectAll() {
        List<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
    
        try {
            
            sql = "SELECT id, name, sex, age, DATE_FORMAT(date, '%Y-%m-%d') AS date, rcount FROM persons";
            
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            
            while (rs.next()) {    
                connectDB();
                
                HashMap<String, Object> params = new HashMap<String, Object>();
                
                params.put("id", rs.getInt("id"));
                params.put("name", rs.getString("name"));
                params.put("sex", rs.getString("sex"));
                params.put("age", rs.getInt("age"));
                params.put("date", rs.getShort("date"));
                params.put("rcount", rs.getInt("rcount"));
                
                params.put("column""id");
                params.put("sort""ASC");
                
                list.add(params);
            }
            
            conn.close();
            pstmt.close();
            rs.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        
        return list;
    }
 
    @Override
    public List<HashMap<String, Object>> selectAllLimit(int offset, int recordsPerPage,
            String sortItem, String sortMethod) {
        List<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
         
        try {
            connectDB();
            
            sql = "SELECT id, name, sex, age, DATE_FORMAT(date, '%Y-%m-%d') AS date, rcount FROM persons ";
            
            if (sortItem != null && sortItem.equals("id")) {
                sql += "ORDER BY id ";
            }
            else if (sortItem != null && sortItem.equals("name")) {
                sql += "ORDER BY name ";
            }
            else
                sql += "ORDER BY age ";
            
            if (sortMethod != null && sortMethod.equals("ASC")) {
                sql += "ASC ";
            }
            else {
                sql += "DESC ";
            }
            
            sql += "LIMIT " + offset + ", " + recordsPerPage;
            
            pstmt = conn.prepareStatement(sql);
 
            rs = pstmt.executeQuery();
            
            while (rs.next()) {
                HashMap<String, Object> params = new HashMap<String, Object>();
                
                params.put("id", rs.getInt("id"));
                params.put("name", rs.getString("name"));
                params.put("sex", rs.getString("sex"));
                params.put("age", rs.getInt("age"));
                params.put("date", rs.getString("date"));
                params.put("rcount", rs.getInt("rcount"));
                
                params.put("offset", offset);
                params.put("recordsPerPage", recordsPerPage);
                params.put("sortItem", sortItem);
                params.put("sortMethod", sortMethod);
                
                list.add(params);
            }
            
            conn.close();
            pstmt.close();
            rs.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        
        return list;
    } 
    
    @Override
    public Person selectById(int id) {
        Person person = new Person();
        
        try {
            connectDB();
            
            sql = "SELECT * FROM persons WHERE id = ?";
            
            pstmt = conn.prepareStatement(sql);
            
            pstmt.setLong(1, id);
            
            rs = pstmt.executeQuery();
            
            while (rs.next()) {
                person.setId(rs.getInt(1));
                person.setName(rs.getString(2));
                person.setSex(rs.getString(3));
                person.setAge(rs.getInt(4));
                person.setDate(rs.getString(5));
                person.setrCount(rs.getInt(6));
            }
            
            conn.close();
            pstmt.close();
            rs.close();
            
        } catch (Exception e) { }
        
        return person;
    }
 
    @Override
    public int selectCount() {
        int n = 0;
        
        try {
            connectDB();
            
            String sql = "SELECT COUNT(*) FROM persons";
            
            pstmt = conn.prepareStatement(sql);
            
            rs = pstmt.executeQuery();
            
            rs.next();
            
            n = rs.getInt(1);
            
            pstmt.close();
            rs.close();
            
        } catch (Exception e) { }
        
        return n;
    }
 
    @Override
    public int insert(Person person) {
        int id = -1;
        
        sql = "INSERT INTO persons (name, sex, age, rcount) VALUES (?, ?, ?, 0)";
        
        try {
            connectDB();
            
            pstmt = conn.prepareStatement(sql);
            
            pstmt.setString(1, person.getName());
            pstmt.setString(2, person.getSex());
            pstmt.setInt(3, person.getAge());
            
            pstmt.executeUpdate();
            
            pstmt.close();
            conn.close();
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
        
        return id;
    }
 
    @Override
    public void update(Person person) {    
        sql = "UPDATE persons SET name = ? , sex = ?, age = ? WHERE id = ?";
        
        try {
            connectDB();
            
            pstmt = conn.prepareStatement(sql);
            
            pstmt.setString(1, person.getName());
            pstmt.setString(2, person.getSex());
            pstmt.setInt(3, person.getAge());
            pstmt.setInt(4, person.getId());
            
            pstmt.executeUpdate();
            
            pstmt.close();
            conn.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    @Override
    public void updateCount(int id) {    
        sql = "UPDATE persons SET rcount = rcount + 1 WHERE id = ?";
        
        try {
            connectDB();
            
            pstmt = conn.prepareStatement(sql);
            
            pstmt.setInt(1, id);
            
            pstmt.executeUpdate();
            
            pstmt.close();
            conn.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    @Override
    public void delete(int id) {
        sql = "DELETE FROM persons WHERE id = ?";
        
        try {
            connectDB();
            
            pstmt = conn.prepareStatement(sql);
            
            pstmt.setInt(1, id);
            
            pstmt.executeUpdate();
            
            pstmt.close();
            conn.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }    
    }
}
cs

 

 

- selectAll : 리스트 전체 출력 메소드

- selectAllLimit : 정렬 방식에 따라 변경되는 리스트 출력 메소드

if문과 LIMIT 를 이용한 쿼리를 구현하는데에서 시행착오가 조금 있었다.

- selectById : 특정 게시글을 선택했을 때 해당 글 하나의 정보만을 출력하는 메소드

- selectCount : 전체 리스트 수를 출력하는 메소드

- insert : 게시글 삽입 메소드

- update : 게시글 수정 메소드

- updateCount : 게시글 조회수 증가 메소드

- delete : 게시글 삭제 메소드

'BackEnd > Java' 카테고리의 다른 글

Java :: Random 함수  (0) 2016.06.05
Jsp :: jsp 내장객체  (0) 2016.06.03
Java :: 패키지 이름 명명 규칙  (0) 2016.04.02
Servlet :: Servlet(서블릿) 이란?  (0) 2016.04.01
Java :: 다형성  (1) 2016.03.23

+ Recent posts