안녕하세요

프로그램 과정에서 막혔던 문제들에 대한 해결책 정리


페이지 목록

2011년 8월 29일 월요일

[변신인간] Map.java (GUI 부분)


package com.jay.Change;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import com.jay.Character.*;
import com.jay.Control.*;

public class Map {
        Panel에 주인공과 몬스터들을 삽입하여 제어
CPanel cPanel = new CPanel();
boolean isUp, isDown, isLeft, isRight, isA, isChange = false;
static final String bPath = "D:/자바 프로그램/변신인간/하늘2.jpg";
ImageIcon img;

Control control = new Control(cPanel);
public static void main(String[] args) {
Map map = new Map();
map.go();
}

public void go() {
JFrame frame = new JFrame();
frame.setTitle("ChangeMan");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
img = new ImageIcon(bPath);

JPanel background = new JPanel();
background.setLayout(new BorderLayout());
JLabel label = new JLabel(new ImageIcon(bPath));
label.setHorizontalAlignment(JLabel.CENTER);
background.add(label); // default center section
// background.add(cPanel);
frame.getContentPane().add(cPanel);
cPanel.addKeyListener(new ListenKey());
frame.setFocusable(true);
frame.setSize(820, 650);
frame.setVisible(true);
cPanel.requestFocus();

control.Thread();
}

class ListenKey implements KeyListener {

@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
control.setIsLeft(true);
break;
case KeyEvent.VK_RIGHT:
control.setIsRight(true);
break;
case KeyEvent.VK_UP:
control.setIsUp(true);
break;
case KeyEvent.VK_DOWN:
control.setIsDown(true);
break;
case KeyEvent.VK_A:
control.setIsA(true);
break;
}
}

@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
control.setIsLeft(false);
break;
case KeyEvent.VK_RIGHT:
control.setIsRight(false);
break;
case KeyEvent.VK_UP:
control.setIsUp(false);
break;
case KeyEvent.VK_DOWN:
control.setIsDown(false);
break;
case KeyEvent.VK_A:
control.setIsA(false);
break;
}
}

@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}

class CPanel extends JPanel {

/**
*
*/
private static final long serialVersionUID = 6652451537073754302L;

public void paintComponent(Graphics g) {
g.drawImage(img.getImage(), 0, 0, this);
control.Move(g);
}
}
}

KeyListener를 이용해서 컨트롤 제어

2011년 8월 22일 월요일

[변신인간] 간단한 게임을 만들어보자.

 시나리오
 바야흐로 2050년, 인류는 최대의 위기에 봉착해 있다. 실상이 파악 되지 않았던 UFO가 지구를 침공한 것이다. 그들은 무차별적으로 인체 실험을 하였고 말로다 할 수 없는 어마어마한 인원들이 희생되어 갔다. 그리고 마침내 그들은 지구를 식민지로 만들고 지구를 통치하기 시작하였다.  이 때, 그 들의 무자비한 실험 결과 변신인간이 탄생하게 된다. 그는 무기를 먹음으로써 무기로 변할 수 있었고 그 능력을 바탕으로 수용소를 탈출한다. 이제 그는 외계인의 우두머리를 처치하기 위해 외로운 싸움을 시작한다.

2011년 8월 15일 월요일

원할한 KeyListener 활용을 위한 Thread 도입

KeyListener를 사용하다 보면 몇 가지 불편한 점이 있다.

 그것은 여러 개의 키를 동시에 누를 경우 처리가 힘들 다는 점이다.

 이는 HashSet 등을 통해서도 해결할 수 있다. HashSet은 중복키를

 저장하지 않기에 여기에 Button Pressed 때 들어오는 Key값들을

 저장하면 된다. 그때 들어오는 키값을 저장하는 방법은

e.getKeyCode() or e.getKeyChar() 로 저장하면 된다. (이떄 e가

 KeyEvent를 뜻한다)

 저장 된 Key 값들을 Button released 때 set.remove(e.getKeyCode())

를 이용하여 삭제 하면 된다.

 저장 된 code들을 불러올 때에는

 while(set.hasNext())
{
       set.next() - 이 것을 부르면 key값이 불러진다.
}
 그러므로 여기서 불러진 값을 이용하여 자신이 원하는 Action을

 만들면 된다.

 예) set에 VM_UP , VM_DOWN 이 들어 있을 경우

while(set.hasNext())
{

  switch(set.next())
  case:VM_UP
 break;
 case : VM_DOWN
 break;

}


 를 이용하여 액션을 컨트롤 할 수 있다.

 이 경우 문제가 발생하였으니 그 문제는 바로

 오른쪽 화살표 누름 -> 오른쪽 + 위 화살표 누름 -> 위 화살표 땜

 이 때 이상하게 오른쪽 버튼은 눌러져 있는 상태이지만 더 이상

 Pressed Listener로 해당 액션이 전달되지 않았다.

 이유는 잘 알지 못하겠지만 먼저 누르고 있던 키보드 버튼 보다

 나중에 누른 키보드 버튼을 먼저 떼면 이 문제가 발생하였다.

 이를 해결하기 위한 보다 나은 방법은 바로 스레드를 도입하는 것이었다.

 Listener에서 Push 된 버튼을 boolean을 이용하여 조작할 수 있다.

 즉, Pressed 때 클릭된 버튼에 true를 주고, Released 때 false를 줌으로

 액션을 컨트롤 하는 것이다.

 그 후, 스레드를 이용해서 Button Pressed 일 때 즉, 해당 버튼에 대한

 boolean 값이 true 일 때 할 액션을 만들어 주면 성공이다.

 관련 소스)

Thread의 Runnable 소스


class CharMove implements Runnable {
public void run() {
while (true) {
Move();
}
}

public void Move() {
while (isUp == true || isDown == true || isLeft == true
|| isRight == true) {
if (isUp == true) {
cy -= 5;
cPanel.repaint();
System.out.println("UP ");
}
if (isDown == true) {
cy += 5;
cPanel.repaint();
System.out.println("Down ");
}
if (isLeft == true) {
cx -= 5;
cPanel.repaint();
System.out.println("LEFT ");
}
if (isRight == true) {
cx += 5;
cPanel.repaint();
System.out.println("Right ");
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


}
}

Thread 작동 코드

CharMove charMove = new CharMove();
Thread cThread = new Thread(charMove);

cThread.start();

KeyListener에서 조작하고자 하는 버튼을 제어하는 코드

class ListenKey implements KeyListener {

@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
isLeft = true;
break;
case KeyEvent.VK_RIGHT:
isRight = true;
break;
case KeyEvent.VK_UP:
isUp = true;
break;
case KeyEvent.VK_DOWN:
isDown = true;
break;
}
}

@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
isLeft = false;
break;
case KeyEvent.VK_RIGHT:
isRight = false;
break;
case KeyEvent.VK_UP:
isUp = false;
break;
case KeyEvent.VK_DOWN:
isDown = false;
break;
}
}

@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}




KeyEvent 와 KeyListener

KeyEvent는 자바에서 Key를 눌렀을때 발생하는 Event이다.

 Java 홈페이지를 보면 알겠지만 모든 키에 다 이름을 할당해 놓았다.

A를 누르면 VK_A B를 누르면 VK_B 등 등

 VK_* 로써 알기 쉽게 설명이 되어 있다.

 KeyListener를 통해 이 Event들을 받아서 컨트롤 할 수 있다.

cPanel.addKeyListener(new ListenKey());

 KeyLIstener를 사용하기 위해서는 이 처럼 addKeyListener() Fuction을

 사용해서 나타낸다.

 이때 넘어오는 파라미터 값은 KeyListener를 상속 받은 클래스면 된다.


class ListenKey implements KeyListener{

@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
switch(e.getKeyCode()){
case KeyEvent.VK_LEFT:
cx--;
cPanel.repaint();
break;
case KeyEvent.VK_RIGHT:
cx++;
cPanel.repaint();
break;
case KeyEvent.VK_UP:
cy--;
cPanel.repaint();
break;
case KeyEvent.VK_DOWN:
cy++;
cPanel.repaint();
break;

}
}

 보다시피 KeyListener에는 3가지 Method가 Implements 되어 있어 반드시

 추가해야 한다. 세 가지 Method는 알기 쉽다.

 이름에서도 알수 있다 시피 Key가 눌러 졌을때, Key를 땠을 때,

 Key를 쳤을 때에 각각의 Method가 호출되게 된다.

 위 코드에서는 키가 눌러졌을 때 Object를 움직이는 간단한 코드를 삽입하였다.


JPanel에 Image 넣기


String path = "path_to_image";
JPanel panel = new JPanel(new BorderLayout());
JLabel label = new JLabel(new ImageIcon(path));
label.setHorizontalAlignment(JLabel.CENTER);
panel.add(label);  // default center section


출처: http://www.java-forums.org/new-java/4477-how-add-images-jpanels.html

패널에 Layout을 설정하지 않을 시


class Pseudo extends JPanel {
    BufferedImage image;

    Pseudo(BufferedImage image) {
        this.image = image;
        // or load it in this class
        setLayout(null);
        add components...
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        int x = 
        int y = 
        g.drawImage(image, x, y, this);
    }
}

2011년 8월 14일 일요일

서버와 클라이언트

 서버 - 클라이언트로부터 요청을 받아, 요청한 것을 넘겨 줌, 사용자가 웹 브라우져를 통해 서버에 자원을 요청하면 그 요청에 맞는 자료를 넘겨주는 역할
 클라이언트 - 서버에 자료를 요청하고 요청한 자료가 도착하면 사용자에게 그 내용을 보여주는 역할
 둘 사이의 의사소통을 위해 HTML과 HTTP가 필요하다.
 HTML => 브라우져가 서버의 전달사항을 어떤 식으로 보여줘야 하는 지 알려주는 Language
 HTTP => 클라이언트와 서버간에 대화하기 위해 만들어진 규약
 보통 클라이언트가 요청하면 서버에서 응답을 보내주는 형식으로 짜여 있다.

 클라이언트에서 HTTP를 이용해 자원을 요청하면 서버는 그 요청에 맞는 자료를 HTTP에 HTML을 실어 전송한다. 그러면 Browser는 HTML을 해독하여 사용자에게 보여준다.
 HTTP 요청에는 HTTP Method가 들어 있다.
 HTTP Method 중 가장 중요하고 자주 사용 되는 것은 Get 과 Post 이다.
 Get의 경우 자료를 요청할 때 자주 쓰인다. 단순하게 자료를 받아 오는 것이기에 멱등 - 즉 같은 동작을 여러번 반복해도 문제가 생기지 않는다.
 Post의 경우 서버에 자료를 요청할 때 사용자가 몇 가지 정보를 함께 제출하여 그 정보에 따라 응답을 받을 수 있다.
 사실 Get으로도 정보를 보낼 수 있지만 그 정보가 URL 뒤에 붙어서 나오기에 보낼 수 있는 양이 한계가 있고 URL 창에 정보가 노출되어 보안상 중요한 내용을 보내기에 적합하지 못하다. 그리고 Get으로 보내는 요청은 URL 뒤에 붙어 나오기에 즐겨찾기에 추가 할 수 있다.

 HTTP 응답은 Header와 Body로 구성되어 있다.
 Header => 사용된 프로토콜, 보내준 요청이 성공했는지, 몸체에 포함 된 컨텐츠 종류가 무엇인지 등...
Body => HTML과 같은 컨텐츠

 사실 웹서버는 정적인 정보만을 제공할 수 있다. 그렇기에 웹 서버에 동적인 서비스를 제공하기 위해서는 같은 컴퓨터에 있는 다른 App들의 도움이 필요하다. 이러한 App들을 CGI라 한다.

 그리고 이러한 서블릿을 원할하게 돌아가기 위해서는 많은 도움이 필요하다. 서블릿 클래스 생성과 로드 그리고 스레드 관리 등 많은 일들을 해야 한다. 이와 같은 일을 하기 위해서 컨테이너가 생겼다. Tomcat도 이러한 컨테이너의 일종이다.

[단어장] Source - Error.java


package dictionary;

public class Error {

// A - Z 65 - 90
// a - z 97 - 122
public static boolean ECheck(String e) {
int length = e.length();
boolean t = false;
for (int i = 0; i < length; i++) {
char temp = e.charAt(i);
if (temp < 32) {
t = true;
break;
} else if (temp > 32 && temp < 65) {
t = true;
break;
} else if (temp > 90 && temp < 97) {
t = true;
break;
} else if (temp > 122) {
t = true;
break;
}
}

if (length == 0) {
t = true;
}
return t;
}
}

이 부분은 단어장에 영어단어를 입력 시 영어를 입력하는 지 아닌지

 확인하는 처리를 해준 것이다.

[단어장] Source - DTable.java


package dictionary;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.sql.Connection;
import java.sql.Statement;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

/*query = "create table Word " + "(name varchar(32), "
 + "mean varchar(200), " + "importance TINYINT , "
 + "count SMALLINT)";*/
public class DTable {
private static Connection con = null;
private static Statement stmt = null;
private static JTable table = null;
private JFrame frame = new JFrame();

private DefaultTableModel model = new DefaultTableModel();

public JFrame getFrame(){
return frame;
}

public JTable getTable(){
return table;
}
public DefaultTableModel getDModel(){
return model;
}
public void showWords() {
// Frame
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Table

table = new JTable(model);
table.getSelectionModel().addListSelectionListener(new RowListener());
D_DB.setTable(table, model);

JScrollPane scrollPane = new JScrollPane(table);
// Save
JPanel panel = new JPanel();
JButton button = new JButton("Save");
button.addActionListener(new SaveListener());
panel.add(button);

// 위치 조정
frame.getContentPane().add(panel, BorderLayout.NORTH);
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
frame.setBounds(50, 50, 300, 300);
frame.setVisible(true);

}

class SaveListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
Dictionary d = new Dictionary();
d.createAndShowGUI();
}
}

class RowListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent event) {
if (event.getValueIsAdjusting()) {
return;
}
if (table.getSelectionModel().isSelectionEmpty() == false) {
int row = table.getSelectionModel().getLeadSelectionIndex();
int col = table.getColumnModel().getSelectionModel()
.getLeadSelectionIndex();

String word = (String) table.getValueAt(row, col);
String[] data = new String[2];
D_DB.getData(data, word);

if (data[0] != null && data[1] != null) {
Dictionary d = new Dictionary(data[0], data[1]);
d.createAndShowGUI();
}
}

}
}

}

 이 부분은 단어장을 나타낸다. 즉 Dictionary Form에서 저장해 놓은 단어들을 

 보여주는 부분이다. 이를 Table에 나타내도록 하였다.

 Table 에서 해당 줄을 클릭하면 그 단어의 뜻을 보여주는 창을 띄우도록

 하였고 이를 위해서 Listener를 사용하였다.

 

[단어장] Source - Dictionary.java


package dictionary;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;

public class Dictionary {
JFrame frame;
JPanel English;
JPanel Meaning;
JPanel Save;
JLabel word;
JTextField eword = null;
JLabel mean;
JTextArea emean = null;
JButton save;
JButton ok;
JButton delete;
boolean isNew = true;

//Table
static DTable table = new DTable();
Dictionary() {
}

Dictionary(String name, String mean) {
eword = new JTextField(20);
eword.setText(name);
emean = new JTextArea(10, 20);
emean.setText(mean);
isNew = false;
}

public static void main(String[] args) {
table.showWords();
}

public void createAndShowGUI() {
// Frame
frame = new JFrame("Dictionary");
English = new JPanel();
Meaning = new JPanel();
Save = new JPanel();
word = new JLabel("영어");
if (eword == null)
eword = new JTextField(20);
mean = new JLabel(" 뜻 ");
if (emean == null)
emean = new JTextArea(10, 20);

// add Panel
English.add(word);
English.add(eword);
Meaning.add(mean);
Meaning.add(emean);

// add Button
if (isNew == true) {
save = new JButton("Save");
save.addActionListener(new SaveListener());
ok = new JButton("Cancel");
ok.addActionListener(new OkListener());
Save.add(save);
Save.add(ok);
}else
{
delete = new JButton("Delete");
delete.addActionListener(new DeleteListener());
JButton ok = new JButton("OK");
ok.addActionListener(new OkListener());
Save.add(delete);
Save.add(ok);
}
frame.getContentPane().add(BorderLayout.NORTH, English);
frame.getContentPane().add(BorderLayout.CENTER, Meaning);
frame.getContentPane().add(BorderLayout.SOUTH, Save);
frame.pack();
frame.setVisible(true);
}

class OkListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
frame.setVisible(false);
table.getTable().getSelectionModel().clearSelection();
}
}

class DeleteListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
String ew = eword.getText();
String em = emean.getText();

D_DB.DeleteWord(ew);

frame.setVisible(false);
int row = table.getTable().getSelectionModel()
.getLeadSelectionIndex();

table.getDModel().removeRow(row);
table.getTable().getSelectionModel().clearSelection();
}
}

class SaveListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
String ew = eword.getText();
String em = emean.getText();

if (Error.ECheck(ew) == false) {
D_DB.insertWord(ew, em, 1);

D_DB.showTable();

System.out.println(ew + " " + em);

frame.setVisible(false);
DefaultTableModel model = table.getDModel();
model.addRow(new Object[] { ew });
} else {
JOptionPane.showMessageDialog(null, "'영어'란에 영어만 입력하세요");
}

}
}

}

 단어장에 단어를 입력하는 폼을 만든 것이다.

 Frame 과 Panel을 이용해서 구성되어 있다. 

 createAndShowGUI() Method에서 구현하고 있다.

 frame 을 만들고 거기에 English 와 Meaning 패널을 집어 넣는다.

 English 패널에는 word JLabel과 eword JTextField를 집어 넣어서 

 영어 단어를 적게 만들었고

 Meaning 필드에는 JLabel 과 JTextAread를 이용해서 뜻을 넣도록

 하였다. 

 그리고 사실 이 동일 클래스에서 두가지 상황을 가능하게 만들었다.

 그래서 만약 입력 하는 단계라면 버튼이 Save 와 Cancel이 나오게

 함과 동시에 단어 입력을 가능하게 하였다. 반면 입력하는 단계가

 아닐 경우 (단어장에서 해당 단어를 클릭 했을 때) 그 단어의 영어
 
 와 뜻을 보여줌과 동시에 삭제 기능과 확인 기능 (Delete 와 OK) 버튼

 을 넣도록 구현 하였다. 

 Listener에서 관련 내용을 다루고 있다
 

2011년 8월 11일 목요일

[단어장] Java로 간단한 단어장을 만들어 보자.

 소스와 함께 간단하게 단어장을 만들어 보자.

 일단 단어장을 만들기 위해서 뭐가 필요할지에 대해 이야기 해 보겠다.

 1. 단어장을 만들기 위해서는 단어들을 저장할 DB가 필요하고

 2. 단어장에 넣을 단어들을 입력하기 위한 GUI 창이 필요하고

 3. 단어들을 보여줄 GUI가 필요하다.

 이 세 가지만 다룰 줄 안다면 간단하게 단어장을 만들 수 있다.

 1. DB 다루기

 MySql과 JDBC를 이용하여 자바에서 DB를 사용하도록 하자.

 MySql 과 JDBC를 저장하는 방법은 블로그 내 다른 글을 참조하도록 하자.

 그럼 이제 단어장을 만들기 위해 필요한 DB 연산 기능을 생각해 보자.

 우선 무엇보다도 저장할 공간 즉 Table이 필요하다.

 이를 위해서는 Create Table을 이용하여 DB를 만들어야 한다.

 그 후 입력한 단어들을 저장하기 위해서 Insert 문을 사용하게 된다.

 그리고 사용자가 원하는 단어를 뽑기 우해서 Select 문을 사용하고

 필요없는 단어를 지우기 위해 Delete 문을 사용하여야 한다.

 이 정도 기본적인 Sql 문들을 이용할 줄 알고 이를 Java에서 나타내기 위해

 JDBC를 잘 이용한다면 DB 구축은 쉽게 할 수 있다.

 현재 본인이 만들어 놓은 단어장에 들어 있는 DB 관련 소스이다.


package dictionary;

import java.awt.BorderLayout;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import dictionary.DTable.RowListener;

public class D_DB {

static Connection con = null;
static Statement stmt = null;

static String userid = "root", password = "root";
static String url = "jdbc:mysql://localhost:3306/test";

public static Connection getConnection() {

try {
Class.forName("org.gjt.mm.mysql.Driver"); // Class.forName("myDriver.ClassName");
// ?

} catch (java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}

try {
con = DriverManager.getConnection(url, userid, password);

} catch (SQLException ex) {
System.err.println("SQLException: " + ex.getMessage());
}

return con;
}

public static void createTables() {
Connection con = getConnection();
String query;
Statement stmt;

try {
query = "create table Word " + "(name varchar(32), "
+ "mean varchar(200), " + "importance TINYINT , "
+ "count SMALLINT)";
stmt = con.createStatement();
stmt.executeUpdate(query);
stmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}

public static void insertWord(String word, String mean, int importance) {
Connection con = getConnection();

String insert = "insert into Word values('" + word + "', '" + mean
+ "', " + importance + ", " + 1 + ")";
String select = "SELECT name, count FROM Word WHERE name = '" + word + "'";

try {

stmt = con.createStatement();
ResultSet result = stmt.executeQuery(select);
if (result.first() == false) {
stmt.executeUpdate(insert);
} else {
int count = result.getInt(2);
count++;
String update = "update Word set mean = '" + mean + "', count = " + count
+ " where name = '" + word+ "'";

stmt.executeUpdate(update);
}

stmt.close();
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public static void showTable() {
Connection con = getConnection();

String select = "SELECT * FROM Word ";

try {
stmt = con.createStatement();
ResultSet result = stmt.executeQuery(select);

while(result.next()){
String word = result.getString(1);
String mean = result.getString(2);
int imp = result.getInt(3);
int count = result.getInt(4);

System.out.println("영어 단어 " + word + " 영어 뜻 " +
mean + " 중요도" + imp + " 저장횟수 " + count);
}
stmt.close();
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public static void DeleteWord(String word) {
Connection con = getConnection();

String delete = "DELETE FROM Word where name = '" + word + "'";

try {
stmt = con.createStatement();
stmt.executeUpdate(delete);

stmt.close();
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public static void setTable(JTable table,DefaultTableModel model) {
Connection con = D_DB.getConnection();
String select = "SELECT name FROM Word";

String title = "word";

try {
stmt = con.createStatement();
ResultSet result = stmt.executeQuery(select);

model.addColumn(title);
while (result.next()) {
String word = result.getString(1);

model.addRow(new Object[] { word });

}
stmt.close();
con.close();

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public static void getData(String[] data, String word){
Connection con = getConnection();

String select = "SELECT name,mean FROM Word where name = '" +
word + "'";

try {
stmt = con.createStatement();
ResultSet result = stmt.executeQuery(select);

while(result.next()){
data[0] = result.getString(1);
data[1] = result.getString(2);
}
stmt.close();
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


 이 Code를 D_DB.java 라는 클래스를 새로 만든 후 붙여 넣으면 된다.

 질문 사항이 있으면 댓글을 달아주시기 바랍니다.

 다음 번에는 단어장을 만들 때 필요한 GUI를 만드는 방법을 알려드리겠

 습니다.

2011년 8월 3일 수요일

Servlet EL 함수

 1. 정적인 공용 메소드를 제공하는 클래스를 먼저 작성
 일반적인 자바 클래스 but Method는 반드시 public static 으로
 인자는 있어도 무방 but 리턴 타입이 void면 곤란
 작성 후 /WEB-INF/classes 디렉토리에 .class 파일을 옮길 것
 2. 태그 라이브러리 서술자 파일
  TLD( Tag Library Descriptor) 란 파일로 함수를 정의한 자바 클래스와 이를 호출할 JSP 매핑
 3. JSP에 taglib 지시자를 코딩
  지금 JSP에서 이 TLD를 쓸 건데 다른 것하고 헛갈릴 수 있으니 앞첨자 (prefix)를 붙이고 싶네
 4. 함수를 호출하는 EL 작성
 ${prefix:name()}

 EL 연산자들
 더하기: + // 뺴기 : - // 곱하기 * // 나누기 / 와 div // 나머지 % 와 mod
 논리 연산자 :
 AND : && 와 and // OR || 와 or // NOT : ! 와 not
 관계 연산자 :
 등호 == 와 eq // 부등호 != 와 ne // ~보다 작다 < 와 lt // ~보다 크다 > 와 gt // ~ 보다 작거나 같다 : <= 와 le // ~보다 크거나 같다 >= 와 ge

 EL은 널(null)을 아주 자연스럽게 처리
 산술 연산에서 EL은 널을 "0"으로
 논리연산에서 EL은 널을 "거짓 (false)"로 처리

Servlet Action(서블릿 액션)

 표준 액션  <jsp:include page = "wickedFooter.jsp"/>
 기타 액션: <c:set var = "rate" value "32" />

 스크립트가 없는 JSP
 빈 관련 표준 액션
 <jsp:useBean> 실제 객체를 선언하고 초기화하는 태크
 <jsp:useBean id="person" class = "foo.Person" scope = "request"/>
 id = 빈 객체 식별자 선언
 class = 클래스 타입 선언
 scope = 빈 객체 속성 생존 범위
 <jsp:getProperty name = "person" property = "name" />
 name = 빈객체 이름
 property = 프로퍼티 이름을 적음

 <jsp:useBean>은 객체 생성도 함
 <jsp:setProperty name = "person" property = "name" value = "Fred"/>
 <jsp:useBean id = "person" type = "foo.Person" class = "foo.Employee" scope = "page">
 class 없이 type만 쓸 경우, 빈이 먼저 존재해야 함
 type 이 있든 없든 관계없이 class가 있을 경우 이 클래스는 추상 객체여서는 안되며 반드시 인자가 없는 public 생성자가 있어야 함
 scope 속성의 default 값은 "page"

 서블릿을 거치지 않고 JSP로 바로 요청을 날리면,
 <%person.setName(request.getParaeter("userName"));%>
 표준 액션 안에 스크립팅
 <jsp:setProperty name = "person" property = "name" value = "<%= request.getParameter("userName") %>%>
 param 속성으로 요청 파라미터 값을 빈 프로퍼티에 곧바로 설정가능

 여기서 value 대신 param = "userName" 을 쓸 수도 있다.

 이 보다 더 나은 방식으로는 폼 입력 필드 이름이 빈 프로퍼티 이름과 같으면 param 속성이 없어도 동작한다.

 빈의 모든 프로퍼티 이름과 요청 파라미터 이름이 같을 때
 예) Param 빈에 두개의 프로퍼티 (name, empID) 가 있을때
 <jsp:setProperty name = "person" property = "*" />
 빈 태그는 기본 타입 프로퍼티를 자동으로 변환
 프로퍼티가 String 기본형도 아닌 경우
 EL을 사용
 ${person.dog.name}
 [] 연산자는 도트 연산자 보다 막강
 ${person["name"]} = ${param.name}

 []연산자는 맵, 빈, 리스트, 배열 사용가능
 오른쪽에 있는 값이 인덱스 값 즉 숫자가 될 수 있으며, 자바 명명 규칙을 따르지 않는 것도 올 수 있음
 예) 문자열과 도트를 가지는 다음과 같은 값 "coo.foo.trouble" 도 맵의 키가 될 수 있다.
 [] 연산자 안의 값이 문자열(따옴표로 묶여 있다면) 이라면, 이것은 맵키가 될 수 있고, 빈 프로퍼티 또는 리스트나 배열 인덱스가 될 수 있다.

 배열에 [] 연산자 사용하기
EL의 [] 연산자는 그냥 [] 연산자일 뿐 자바와 상관관계가 없다.
 문자열(String)이아니면, 이게 뭘까 하고 실행(평가)
 맵 키 값이면 맵의 값을 가져 옴
 request.setAttribute("Genre", "Ambient");
 Music is ${musicMap[Genre]} => Music is ${musicMap["Ambient"]}
 
 [] 안에 내장 표현식을 쓸 수 있다.
 ${musicMap[MusicType[0]]}
 ${musicMap["Ambient"]}

 EL에서 요청 파라미터
 ${param.name}
 ${param.empID}
 ${paramValues.food[0]}

Request에서 파라미터 이상의 정보를 원할 때
 "host" 헤더 정보 읽기
 Host is : ${header["host"]} = ${header.host}

 requestScope은 request 정보 (property)가 아닌 request 속성을 가져 오기 위해 사용. request 정보 pageContext를 통해서 접근
 ${pageContext.request.method}
 생존 범위 관련 내장 객체가 도움이 될 때

 한 군데 이상 똑같은 이름으로 몰려 있을지도 모르는 경우
${requestScope.person.name}
 속성 이름이 문자열인 경우
 request.setAttribute("foo.person",p);
 -> ${requestScope["foo.person"].name}

2011년 8월 2일 화요일

PageContext로 속성 접근하기

 pageContext는 자신이 설정되어 있는 page 범위 속성 뿐만 아니라 어떤 다른 생존 범위 속성도 접근할 수 있을 정도로 매우 막강
 pageContext를 이용하여 속성을 읽고, 설정하는 예제

  •  page 생존 범위의 속성 세팅하기

 <%Float one = new Float(42.5);%>
 <% pageContext.setAttribute("foo",one);%>

  •  page 생존 범위의 속성 읽기

 <%= pageContext.getAttribute("foo")%>

  •  pageContext를 이용하여 session 생존 범위 속성 세팅하기

 <%Float two = new Float(22.4);%>
 <%pageContext.setAttribute("foo",two, PageContext.SESSION_SCOPE);%>

  • pageContext를 이용하여 session 생존 범위 속성 읽기

 <%=pageContext.getAttribute("foo", PageContext.SESSION_SCOPE)%>

  •  pageContext를 이용하여 application 생존 범위 속성 읽기

 <%= pageContext.getAttribute("mail",PageContext.APPLICATION_SCOPE)%>
 = <%= application.getAttribute("mail")%>


  •  pageContext를 이용하여 어떤 생존범위인지 모르는 속성 찾기 

<%= pageContext.findAttribute("foo")%>

 3가지 지시자
 1. page 지시자
 <%@page import = "foo.*" session = "false" %>
 2. taglib 지시자
 <%@taglib tagdir = "/WEB-INF/tags/cool" prefix = "cool"%>
 3. include 지시자
<%@ include file = "wickedHeader.html" %>

JSP 사용

 JSP 도 Servlet으로 변환된다.
 JSP 안에서 자바 코드를 <%.... %> 태그 안에 스크립틀릿으로 작성
 <%@ page import = "foo.*" %>

JSP 초기화 하기
 서블릿 초기화 파라미터 설정하기
 jspInit() 재정의하기
jspInit() 메소드를 JSP 파일에 코딩 => 컨테이너가 서블릿 인생 시작 시에 이 메소드를 호출

Servlet 세션 관리

 대화 상태 유지 하기
 Session에 정보 저장 => 클라이언트 구별을 위해 유일한 세션 ID가 필요
 세션 ID 쿠키 사용 => 컨테이너가 알아서 관리
 쿠키 사용을 못할 시 => URL 재작성
 response의 URL 인코딩 => response.encodeURL("/BeerTest.do");
 사용자로부터 들어 온 요청을 다른 서블릿이나 JSP로 보내고 싶은데 세션은 계속해서 유지하고 싶을 떄
 response.encodeRedirectURL("/BeerTest.do")
 세션 제거 하기
HttpSession 메소드
세션 타임 아웃 설정하기

  •   시간이 다 되어서
  •   개발자가 세션 객체에 invalidate() 메소드 실행
  •   App 다운
 쿠키 사용의 또 다른 방법 => 쿠키는 서버와 클라이언트 간에 교환하는 조그마한 데이터 
 서블릿 API로 쿠키 사용하기
 
 세션 이동
 오직 HttpSession 객체와 그 속성 만이 하나의 VM에서 다른 VM으로 옮겨 감
 HttpSession은 웹 애플리캐이션 당 하나의 세션 ID당 하나 밖에 없음 얼마나 많은 VM이 분산환경에서 돌아가든지 상관 없음

실제 세션 이동 HttpSession만 이동한다
 HttpSessionActivationListener 는 속성을 옮김

Servlet 속성(Attribute)란?

 ServletContext, HttpServletRequest, HttpSession 객체 중 하나에 설정해 놓는 객체
 Context, Request, Session
 Context 생존 범위는 스레드-안전 하지 못하다
 세션 속성 역시 스레드 - 안전 하지 못하다.

 가능한 방법은 ServletContext나 httpSession 등에 Synchronized를 거는 방법이 있다.

Servlet Listener( 서블렛 리스너)

 ServletContextListener => ServletContext 초기화와 소멸에 귀를 기울임
 Context 초기화(App 배포)를 알아차림
 ServletContext로부터 Context 초기화 파라미터를 읽음
 데이터 베이스 연결을 위해 초기화 파라미터 검색명 사용
 데이터베이스 Connection 객체를 속성에 저장

 HttpSessionBindingListener -> 속성 자신이 세션에 속성으로 추가, 제거 되는 지
 HttpSessionAttributeListener -> 세션에 어떤 속성이라도 속성이 추가, 제거, 수정 되는 이벤트가 발생하는지

ServletConfig() Method

 컨테이너가 서블릿을 초기화 할 때, 서블릿 마다 하나씩 ServletConfig 생성
 Container는 DD에서 서블릿 초기화 파라미터를 읽어, 이 정보를 ServletConfig로 넘겨줌. 그 다음 ServletConfig를 서블릿의 init() method에 제공 컨테이너가 서블릿을 만들 때 DD를 읽어 이름/값의 쌍으로 ServletConfig를 생성

 ServletConfig -> init-param
 JSP에서 서블릿 초기화 파라미터 접근 하는 법은?
 <context-param>
 ServletContext로 할 수 있는 일은?
 컨텍스트 파라미터에는 String 밖에 저장이 안 됨
 초기화 파라미터로 데이터베이스 dataSource 객체를 저장하고 싶을 경우 => Data source 검색명(look up name)을 저장 => 그 후 String 검색명을 실제 DataSource 객체로 바꾸면 됨

Servlet Request & Response (서블릿 요청 응답)

 service()의 인자이자 가장 중요한 것
 Request => 쿠키, 헤더, 세션 등 HTTP에 관련된 것들을 서비스, HTTP 프로토콜에 관련 된 Method 추가, 서블릿이 클라이언트, 브라우져와 대화하기 위한 것
 Response => HTTP에 관련 된 오류, 쿠키, 헤더 정보에 대한 메소드
 HttpServlet Request와 HttpServletResponse는 Container가 구축

 Http 요청 메소드는 doGet() or doPost() 결정

Servlet 로딩과 초기화 (Servlet loading & initailize)

 컨테이너가 서블릿 파일을 찾아서 로딩 시 시작 => 컨테이너 시작 시(톰캣) 이루어 진다.
 생성자의 실행 성성자 : '존재하지 않음' -> '초기화 됨'
 객체를 만드는 것이지 서블릿을 만드는 것이 아니다.

 1. ServletConfig 객체
 서블릿 당 하나
 서블릿 배포시 설정 된 정보를 서블릿으로 넘겨주기 위해
 ServletContext 접근
 파라미터값은 배포서술자에서 설정 가능

 2. ServletContext
 Application 당 하나
 웹 App의 파라미터 정보를 읽음 (DD 안에 설정 된 정보들)
 App용 게시판
 서버 정보 파악
 Servlet 의 임무 => 요청 핸들링

JSP Fragment

 JSP Code를 나타내는 객체, 스크립팅 사용 불가
 객체 => 다른 도우미 객체로 넘길수 있고 JSpFragment의 메소드 (getJspContent()) 를 호출해서 필요한 정보를 읽을 수 있음 => 이를 통해 속성 정보 및 다른 객체 정보에 접근 가능
 JSP Fragment가 하는 작업 => 응답에 태그 몸체 내용 출력
 getContents()나 getBody() 같은 메소드는 없다.

 몸체
 invoke() method는 인자로 java.io.write를 받는다.

태그 파일

 include 처럼 행동하지만 좀 더 개선된 방식
 <myTags: Header/> => 태그 이름이 바로 파일 이름
 태그 파일에서는 요청 파라미터를 사용하지 않고 태그 속성으로 정보를 넘김
 속성으로 넘겨야 할 값이 많을 경우
 한문장 정도 크기 일 때
 태그 파일에 쓸 body-content 정의 =-> tag 지시자 사용
 <body-content>=> TLD 파일 <tag>의 하위 항목 필수
태그 파일 => 정의하지 않으면 디폴트인 scriptless가 설정

 태그 파일에서는 스크립팅이 가능하지만 태그 파일을 호출하는 JSP에서 태그 몸체에 스크립팅 사용 불가
 커스텀 태그 핸들러 : classic, simple

 자바 코드를 출력하기 위해

 몸체가 있는 심플 태그
 body를 사용하기 위해 => getJspBody().invoke(null);

Servlet 오류 페이지

<%@ page isErrorPage = "true"%>
<%@ page errorPage = "errorPage.jsp"%>

DD <error-page> tag
 <exception-type> 이나 또는 HTTP 상태 <error-page>

 defalut error page
 <error-page>
 <exception-type>java.lang.Throwable</exception-type>
 <location> /errorPage.jsp</location>
 </error-pgage>

 특정 예외 사항에 대한 오류 페이지
 <error-page>
 <exception-type> java.lang.ArithmeticException</exception-type>
 <location>/arithmeticError.jsp</location>
 </error-page>

 <c:catch>

 예외 사항이 실제 발생시 Exception 객체에 접근하는 방법은?
 실제 오류 페이지도 아니고 일반 JSP 라서 내장 객체인 exception을 쓸 수도 없다.

 Exception을 속성으로 만든다.

 <c:catch> 문 뒤에 Exception 객체를 다루고 싶으면 옵션 속성인 var를 사용

 <c:catch var = "myException">

 <c:catch> 자바의 catch 문이 아닌 try 문처럼 행동

2011년 8월 1일 월요일

JSTL 사용하기

 막강한 커스텀 태그
 태그 라이브러리로 JSP 구축하기
 taglib 지시자 문법과 의미 설명 : 표준 tag library, tag library file 커스텀 태그 만드는 방법

 <c:out>
 <c:out value = '${user}' default = 'guest' />

 <c:forEach>

 <c:if> <c:choose> <c:when> <c:otherwise>

 <jsp:setProperty> => <c:set>

 <c:set var = "userLevel" scope = "sesssion" value = "cowboy"/>

 빈과 맵에 <c:set> tag 사용하기

 <c:set> 핵심 정리

 var과 target을 동시에 사용할 수 없다.
 scope는 option 없으면 page
 value가 null var에 있는 속성 제거
var 이름으로 속성이 없으면 자동생성 value가 null이 아닐 경우
 target 표현식이 널이면, ㅋㄴ테이너는 예외사항을 던짐
 target에는 실제 객체를 표현하는 표현식이 들어가야 함
 target 표현식이 빈이나 맵이 아니면 컨테이너는 예외사항을 던짐
 target 표현식이 빈이고, 해당 빈에 property에 명기된 이름으로 된 property가 없다면 컨테이너는 예외사항을 던짐 EL 표현식 ${bean.notAproperty} 또한 예외 사항을 던짐

 <c:remove>
 <c:import> JSTL tag
 <c:import url = ...... />

 포함할 컨텐츠 요리하기
 <c:param>
 <c:param name = "subtitle" value = "...../>

 <c:url>

 <c:url value = ' /inputAcomments.jsp'/>

 커스텀 라이브러리를 사용하려면 TLD를 읽을 줄 알아라
 태그 이름과 문법
 라이브러리 URI

2011년 7월 25일 월요일

JAVA JFrame X button 클릭 시 이벤트 헨들

public void setDefaultCloseOperation(int operation)
Sets the operation that will happen by default when the user initiates a "close" on this frame. You must specify one of the following choices:
  • DO_NOTHING_ON_CLOSE (defined in WindowConstants): Don't do anything; require the program to handle the operation in the windowClosing method of a registered WindowListener object.
  • HIDE_ON_CLOSE (defined in WindowConstants): Automatically hide the frame after invoking any registeredWindowListener objects.
  • DISPOSE_ON_CLOSE (defined in WindowConstants): Automatically hide and dispose the frame after invoking any registered WindowListener objects.
  • EXIT_ON_CLOSE (defined in JFrame): Exit the application using the System exit method. Use this only in applications.
The value is set to HIDE_ON_CLOSE by default. DO_NOTHING_ON_CLOSE => 아무 것도 안한다. HIDE_ON_CLOSE => 프레임을 감춘다. DISPOSE_ON_CLOSE => 프레임을 감추고 버린다. (그 프레임만 종료) EXIT_ON_CLOSE => 프로그램 자체를 끈다 (모든 프레임을 종료) 이 상수를 쓸 시에는 JFrame. 을 앞에 붙여야 한다. JFrame의 상수이기 때문이다.

JTable 값 가져 오는 방법

getValueAt

public Object getValueAt(int row,
                         int column)
Returns the cell value at row and column.Note: The column is specified in the table view's display order, and not in the TableModel's column order. This is an important distinction because as the user rearranges the columns in the table, the column at a given index in the view will change. Meanwhile the user's actions never affect the model's column ordering.

Parameters:
row - the row whose value is to be queried
column - the column whose value is to be queried
Returns:
the Object at the specified cell

Container에 Table 삽입 방법

Adding a Table to a Container

Here is typical code for creating a scroll pane that serves as a container for a table:
JScrollPane scrollPane = new JScrollPane(table);
table.setFillsViewportHeight(true);
// ScrollPane에 테이블을 넣는 방법
The two lines in this snippet do the following:
  • The JScrollPane constructor is invoked with an argument that refers to the table object. This creates a scroll pane as a container for the table; the table is automatically added to the container.
  • JTable.setFillsViewportHeight is invoked to set the fillsViewportHeight property. When this property is true the table uses the entire height of the container, even if the table doesn't have enough rows to use the whole vertical space. This makes it easier to use the table as a drag-and-drop target.
The scroll pane automatically places the table header at the top of the viewport. The column names remain visible at the top of the viewing area when the table data is scrolled.
If you are using a table without a scroll pane, then you must get the table header component and place it yourself. For example:
container.setLayout(new BorderLayout());
container.add(table.getTableHeader(), BorderLayout.PAGE_START);
container.add(table, BorderLayout.CENTER);
//Container에 직접 table을 삽입하는 방법
출처: http://download.oracle.com/javase/tutorial/uiswing/components/table.html#data

JTable 열과 행 삽입 방법


DefaultTableModel model = new DefaultTableModel();
JTable table = new JTable(model);

// Create a couple of columns
model.addColumn("Col1");
model.addColumn("Col2");

// Append a row
model.addRow(new Object[]{"v1", "v2"});
// there are now 2 rows with 2 columns

// Append a row with fewer values than columns.
// The left-most fields in the new row are populated
// with the supplied values (left-to-right) and fields
// without values are set to null.
model.addRow(new Object[]{"v1"});
// there are now 3 rows with 2 columns

// Append a row with more values than columns.
// The extra values are ignored.
model.addRow(new Object[]{"v1", "v2", "v3"});
// there are now 4 rows with 2 columns
출처: http://www.exampledepot.com/egs/javax.swing.table/AppendRow.html

2011년 7월 22일 금요일

세션 제거하기

 시간을 체크한다.

 세션 종료의 세가지 이유
 1) 시간이 다 되어서 (타임 아웃)
 2) 개발자가 세션 객체에 Invalidate() 메소드를 실행
 3) App이 다운되는 경우( 문제가 생겨 다운되거나, 언디플로이(undeploy) 되는 경우)

쿠키(Cookie)

 쿠키는 Header 중 하나이다.
 Container에서 거의 모든 Cookie 관련 작업을 수행한다.

 Response 객체에 세션 Cookie 보내는 방법
 HttpSession session = request.getSession();

 Request 객체로부터 세션 ID 가져오기
 HttpSession session = request.getSession();

session.isNew() - 세션이 새로 만들어졌는지 아닌지 확인

 URL 재작성 => response.encodeURL( " blur blur ");

 쿠키 => URL 재작성

 정적인 페이지는 URL 재작성이 불가 하다.

컨테이너에서 클라이언트를 구분 하는 방법

 Client는 유일한 Session ID가 필요하다. 그리고 쿠키를 사용해서 Client와 Container는 이 Session ID를 공유한다.

속성(Attribute)란?

 3개의 Servlet API 객체 (ServletContext, HttpServletRequest 또는
ServletRequest),HttpSession 객체 중 하나에 설정해 놓는 객체(Binding)

ServletContext를 리턴 받는 두 가지 방법

 1) getServletConfig().getServletContext().getInitParameter();
 2) this.getServletContext().getInitParamete()
 1) 번의 경우 HTTPServlet 이나 GenericServlet을 상속 받지 않는다.

ServletConfig

 ServletConfig의 역할 => 초기화 Parameter에 접금
 ServletContext 리턴하는 메소드 제공 -> Context 정보 (Servlet 설
정 정보)를 가짐
 웹 App의 다른 Component 와 공유할 경우 => Request 객체를 통
해 보냄. -> 그리 좋은 방법은 아니다.

 

Get 과 Post

 HTTP 요청 Method는 doGet()을 실행할 지 doPost()를 실행할 지
결정
 Get과 Post의 차이점
 Post는 몸체가 있다!!!!!
 Get을 사용하면 브라우져의 주소 입력 창에 Parameter data가 노출
 (보안 문제)
 Get은 즐겨 찾기 추가 가능(Post 불가)
 사용 용도 => Get (뭔가를 가져올 때)
                     Post (처리할 data를 보낼 때 - Update)

 Idempotent => 동일 작업을 부작용 없이 계속 할 수 있는 것
 Get = Idempotent(멱등)  Post = Idempotent 가 아니다.
 Post 는 defalut 값이 아님

Servlet의 일생

 Container가 Servlet file을 찾아서 loading 할 때 -> Container가 시
작 할 때 이루어짐
 1) 클래스 찾기  2) 클래스 로딩
 이 두 작업은 Container 마다 차이가 있다.

 Servlet 초기화
생성자 - 객체 생성 Init() - Servlet 생성

 1) ServletConfig 객체
  Servlet 당 하나
  Servlet 배포시 설정 된 정보를 서블릿으로 넘겨주기 위하여
 (예) Database or EJB 참조
 ServletContext에 접근하기 위해서 이 객체 사용
 Parameter 값은 배포 서술자에서 설정가능
 2) ServletContext 객체
 웹 어플리케이션 당 하나의 ServletContext (이름 - AppContext)
 웹 어플리케이션의 파라미터 정보를 읽어 오기 위해 (Parameter
 정보는 DD 안에 있음)
 어플리케이션 용 게시판 => 여기에 메세지(Attribute)를 적어 놓으
 면 Application의 다른 녀석들이 읽을 수 있음
 서버 정보 파악 => Container 이름 및 Version 지원하는 API ver
 sion

ServletConfig = Servlet 당 하나
ServletContext = Web App 당 하나

Servlet 함수

init()
 호출 시점 => Servlet instance 생성 후
 목적 => Client 요청 처리 전에 Servlet 초기화
 재 정의 가능

service()
 호출 시점 => 최초 Client 요청을 받았을 때, Container는 새로운 스
                   레드 생성 or 스레드 풀에서 하나를 가지고 와서 서블
                   릿의 service 메소드 호출
 목적 => Client의 HTTP Method(Get, Post 등)를 참조하여 doGet(),
            doPost(), 또는 다른 메소드 호출을 판단
 재정의 불가

 doGet()
 or
 doPost()

 호출 시점 => service() 메소드가 Client의 HTTP Method(Get,Post)
       를 참조하여 doGet() or doPost() 호출
 목적 => 코딩을 하는 장소
 재정의 - 둘 중 하나는 반드시

Servlet 개발 5단계

 1) 사용자가 제일 먼저 볼 HTML 폼을 생성 => Test
 2) Controller servlet v1을 만듬
    v1 => HTML 폼이 Servlet을 호출하면 Parameter 값 출력
 3) Model class를 위한 Test Class를 만듬
 4) Servlet v2 => BeerExpert에게 맥주에 대한 조언을 구할 수
    있게 만듬
 5) JSP를 만들고 Servlet V3 => JSP에 요청 전달

MVC 패턴 (MVC Design Pattern)

 Model, View, Controller의 줄임말 (MVC)

 Model => 일반적인 자바 Class
                Business Data (장바구니 정보) , Business Method (장바
               구니 정보에 대한 조작 및 추출)
Controller => Request 객체에서 사용자가 입력한 정보를 뽑아내어,
                   Model에 대하여 어떤 작업을 해야 하는지 알아 냄.
                  (Model 정보 수정, 뷰(JSP)에게 넘겨줄 새로운 Model
                  형성)

View => JSP (실질적으로 브라우져에 띄워질 페이지)

Servlet 과 JSP의 차이점

 Servlet => 자바 안에 HTML을 넣는다.
 JSP => HTML 안에 자바 코드를 넣는다.

두 객체가 같다

 1) 두 레퍼런스가 똑같은 객체를 가리킴 (Reference Equality)
 2) 제목이 똑같은 서로 다른 객체 (Object Equality)

JAVA GUI Layout Manager(레이아웃 메니져)

1) Border Layout => North, South, West, East, Center 다섯 구역에 컴포넌트를 올릴 수 있다.
 Frame의 기본 Layout
2) Flow Layout => 워드 프로세스와 비슷한 방식을 사용한다. 크기는 요구대로 만들 수 있고, 순서대로 '왼쪽 맞춤' 형태로 제공된다. -> 수평 방향으로 들어가지 않을 시에 다음 '행'에 배치 된다.
 Panel 의 기본 Layout
3) Box Layout => 요청 크기대로 만들고 추가된 순서대로 배치한다. 주로 수직 방향으로 쌓을 시에 사용한다. (수평 방향도 가능하지만 잘 사용하지 않음)

JAVA GUI에 뭔가를 넣는 방법

 1) 프레임에 위젯 넣기
 2) 위젯에 2D 그래픽 그리기 => 그래픽 객체를 이용
 3) 그림 넣기

 위 3가지 방법이 있다.

JAVA GUI 중 클릭에 대하여

클릭 시 반응을 얻기 위해서 필요한 두가지

 1) 사용자 클릭시 호출 할 메소드(버튼 클릭 시 행동)
 2) 버튼 클릭을 알 수 있는 방법

 이 두 가지가 필요하다.

 Call Back Method => 이벤트가 일어 났을 때 호출 하는 메소드를 뜻하고 이 메소드가 이벤트 리스너에 그 이벤트가 일어났음을 알린다.
 Event Source => 사용자의 행동을 이벤트로 바꿔주는 객체이다.

2011년 7월 20일 수요일

JDBC select Example(JDBC select 예제)

/*
Database Programming with JDBC and Java, Second Edition
By George Reese
ISBN: 1-56592-616-1

Publisher: O'Reilly
*/

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

/**
 * Example 3.1.
 */
public class Select {
  public static void main(String args[]) {
    String url = "jdbc:msql://carthage.imaginary.com/ora";
    Connection con = null;

    try {
      String driver = "com.imaginary.sql.msql.MsqlDriver";

      Class.forName(driver).newInstance();
    catch (Exception e) {
      System.out.println("Failed to load mSQL driver.");
      return;
    }
    try {
      con = DriverManager.getConnection(url, "borg""");
      Statement select = con.createStatement();
      ResultSet result = select
          .executeQuery("SELECT test_id, test_val FROM test");

      System.out.println("Got results:");
      while (result.next()) { // process results one row at a time
        int key = result.getInt(1);
        String val = result.getString(2);

        System.out.println("key = " + key);
        System.out.println("val = " + val);
      }
    catch (Exception e) {
      e.printStackTrace();
    finally {
      if (con != null) {
        try {
          con.close();
        catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
  }
}


출처: http://www.java2s.com/Code/Java/Database-SQL-JDBC/JDBCselect.htm