2015년 8월 30일 일요일

협업도구?팀프로젝트관리?1. 트렐로 사용방법

1. 트렐로란?
  1) 의미
    협업 도구이다.(이게 정확한 용어일지는 모르겠지만)
      2명 이상 같은 일을 같이 해나갈때
      정보를 교환하기 위한 방법의 하나로 프로그램에 의지
      하는데 그 툴중에 하나가 트렐로임.
https://trello.com/

  2) 특징
    (1) 요즘 스타트업에서는 핫하게 사용되는 협업도구.
       사용방법도 여러군데서 설명하겠다고 정리하고 있다.
       (아래는 이글 작성시 참고한 블로그들)
http://spoqa.github.io/2012/01/02/trello.html
http://clien.net/cs2/bbs/board.php?bo_table=useful&wr_id=245053
....
       (아래는 사용방법을 설명한 pt)
http://www.slideshare.net/soymilkvegemil/140109-43340824

    (2) 구성이 간단해서 사용이 편리하다. (프로젝트의, 주제의, 할일)

    (3) 사용이 편리해서 단순할 것 같지만 쓸만한 기능이 있다.
        (할일 안에서 첨부기능이 있는데 이 곳에서는 직접 첨부하거나
         구글, bropbox, onedrive 등과 연동해서(선택시 본인 아이디로
         연동된 폴더로 이동함) 링크를 거는게 가능하다.


    (4) 폰에서도 접속, 작성 가능하다. 그리고 앱도 만들어져 있다.
         앱을 설치하면 작업할때마다 팀원들에게도 소식이 가기 때문에
         괴롭힐 수 있다. 당신이 팀장이고 트렐로를 쓴다면 반드시
         깔게 하는게 좋을듯.
https://play.google.com/store/apps/details?id=com.trello&hl=ko

    (5)무료

  3) 주로 사용하는 곳
    스타트업
    내 일기장
    학교에서
    규모가 작은 회사
    새로운걸 잘 시도해보는 회사
    빠르게 변화하지만 팀원들과 정보는 꼭 공유해야 하는곳.

  4) 이용방법
    사이트에서 관리하기 때문에 깔거나 하지 않고 아래 링크로 접속
      하여서 가입하면 된다.
https://trello.com/


2. 사용해보기(이용하는 방법)
  우선 가입은 알아서 하자 간단하다.

1) 회사 만들기(조직 만들기)
    (1) 가운데 트렐로 마크를 누르고

    (2) 조직 추가를 누른다.


    (3) 입력하라고 하는 제목과 설명을 입력후 create누르면

    (4) 이렇게 조직이 하나 만들어졌다.
상단 중앙의 Trello를 다시 누르면 아래처럼
  조직이 추가된 걸 볼수 있다.(조직 추가 완료)

  2) 조직원 추가하기
    (1) 1)-(4)에서 boards, members, settings 중에멤버를 누른다.

    (2) add Members 버튼을 누른다.

    (3) email을 눌러서(팀원 email은 알아놔야 한다 소식이 일루간다.)
         이때 모르는 사용자의 경우 이렇게 나오면서 Send 버튼이 뜨고
         Send를 누르면 초대 메일이 가게된다.

         이때 한번이라도 다른 Trello프로젝트  참여자는 바로 추가가능하다.
     
         이렇게 조직에 조직원을 끌어들일 수 있다.
           모르는 이를 넣게되면 해당 사용자도 remove가 가능하므로
           미리 이야기가 된 상태에서 진행해야 된다.

  3) 프로젝트(Board) 만들기
    (1) 1)-(4) 항목 그림에서 2) 항목에서 만든 조직 란 안에
         있는 버튼 Create New Board.. 을 누른다.

    (2) Title 항목을 작성한 후 하단 Create버튼을 누른다.
         조직은 그대로 둔다.

    (3) 정상적으로 Board(프로젝트) 가 생성되었다면
         아래처럼 화면이 뜬다.


  4) 프로젝트에 멤버 추가하기(조직에 멤버추가하기와 다름)
      우측에 <<Show Menu 라는 항목을 클릭하면
      프로젝트 상세 메뉴를 볼 수 있다.
   
      근데 아직 멤버에는 나밖에 없는걸 볼 수 있다.
        조직에는 추가되어 있지만 해당 프로젝트를 새로 생성 할 경우
        프로젝트(board)에도 멤버를 추가시켜야 한다.

    (1) Add Members... 를 누르면 조직에 있는 인원의 경우 추가하기
       쉽게 보이는걸 알 수 있다. 그 외에 직접 입력해서 추가하는것도
       마찬가지로 가능하다. 여기서는 조직에 있는 인원을 추가한다.

    (2) 그럼 멤버가 한명 더 추가된걸 확인할 수 있다.


  5) 일거리 만들기(큰주제)
    (1) 가운데 Add a list... 를 누른다.


    (2) 그러면 창이 하나 열리는데 주제를 입력하고
         엔터를 누르면 아래처럼 하나의 주제가 생성된다.


  6) 일 만들고 할당하기
    (1) Add a card... 버튼을 누르면 흰색으로 Title을 추가할 수 있는데
        여기에 일을 적을 수 있다.
        아래와 같이 적고 엔터를 누른다.
         그러면 다른 일을 하나 더 생성해버리는데 아무것도 적지
         않으면 그 일은 생기지 않는다. 그렇게 한다.


    (2) 여기서는 그냥 1이라고만 적었는데 그 1을 클릭하면 아래와
        같이 일에 대한 세부 내용이 뜬다.
        세부내용에 대한 설명은 아래와 같다.

    (3) 제목, 세부정보, 코멘트는 작성후 엔터 혹은
       Comment 버튼을 누른다. 이 세가지는 몇번이고 고칠 수 있다.
       코멘트의 경우 작성한 이가 수정 가능하다.

    (4) Member 버튼을 통해서 일을 할 사람을 추가하거나 삭제
         가능하다. 여기서는 조직, 프로젝트에 추가한 인원을 추가한다.


    (5) 라벨은 필수는 아니지만 해당 일이 중요하거나,
         회의를 포함하거나 하는 팀내 약속을 정하거나
         (텍스를 넣어서) 뺄 수 있다. 색을 추가할 수있고, 연필
         버튼으로 텍스트를 넣을 수 있다. 프로젝트별로
        색으로 팀 약속을 만들어보자(안해도된다)

    (6) 체크 리스트는 팀원들이 읽었을 경우 체크를 하게하는
         용도로 쓰이지만 비추다 추가하고 멤버를 넣으면
         해당 인원이 체크하도록 자동 설정된다.
        해당 인원이 체크할 수도 있고 다른 인원이 할 수도 있으므로
         사용은 제한될 것 같지만 결정할 사항이 있을때 물어볼
         수 있을 것이다. 체크한 중간과정이 다 로그에 남는다.

    (7) 날자를 입력해서 해당 일의 만료일을 정할 수 있다.

    (8) 필요한 첨부 파일을 첨부하기 위해 Attachment 버튼을 이용한다.
         직접 첨부 이외에 구글 드라이브나 DropBox 등을
         연동할 수 있다.

         여기서는 MSG 사진을 하나 넣어서 아래처럼 반영되었다.

  7) 사용자가 일 넘기기 또는 완료하기
      다른 사용자도 일을 만들거나 하는건 6)항목으로 진행 가능하다.
   (1) 완료하기
        Archive 버튼을 클릭시 해당 일은 완료된다. 그걸 누른다고 바로
        화면이 닫히는건 아니지만, 뒤에 프로젝트 안에 해당 일은 없어진
        상태로 보인다.
        다시 되돌리려면 바로 Send to Board 로 돌리거나
       메뉴의 Archive list에서 해당 일을 찾아서 돌리거나 
         가능하다. Archive 상태에서 Delete를 해버리면 되돌릴수 없다.


   (2) 다른 업무로 넘기기
      코멘트를 달아서(왜냐면 그래야 다른 사람도 왜 넘겼는지 알수 
        있으니깐) Move 명령으로 보내면 된다.
      담당자가 달라지는게 아니고 (담당자는 담당자 변경으로 진행)(
        해당 일의 성격이 주제에 벗어나는 경우 쓰거나 팀 약속에 의해서
        정한대로 쓸 수 있을 것이다.
      Move 버튼을 누르면 조직, 프로젝트(board), 주제가 뜨고 이를 
        하나씩 눌러서 다른걸로 선택 가능하다.


  8) 해당 프로젝트에서 완료된 사항 확인하기
   (1) 7)-(1) 항목에서 완료시 more menu - more - Archived Item
        항목을 통해서 지금까지 완료했던 일 항목들을 모두 확인가능하다.
       다만 여기서는 분류가 안된채로 나온다.
       팀원들이 체크는 했는데 안하거나 안하고 체크도 안하면
         갈구자.



3. 결론
  협업 이라는 개념이 없다면 이해가 안될수 도 있지만
      다른 툴에 비해서는 사용하기 쉬운 편으로 생각된다.
  뭔가 소통에 한계점에 부딪친 상황이라면 뭘 해도 안되겠지만
      뭔가 시도해보는건 안해보는것 보다 낳다고 생각된다.
   최소한 소통이 안되는구나 라는 사실을 알 수 있으니깐.


2015년 8월 27일 목요일

클래스 디자인 패턴 5. SingleTone Pattern_

1. 개념
  1) 정말 많이 쓰이고 있음, 애플리케이션 내에서 하나만 존재해야 하는
       객체에 적용함. (전역변수 설정, DB 컨넥션 풀)
     어느정도 개발했다면 이미 접했음
     싱글톤은 인스턴스를 하나만 만들고 이 만들어진 인스턴스를
       어디서든지 접근할 수 있도록 하기위한 패턴임.

     인스턴스가 1개만 존재하는 것을 보증하는 패턴

2. 소스
 
  1) 고전적인 싱글톤 패턴 구현 방법
    (1) 클래스는 public, 생성자는 private 로 설정하면 
          다른데서 new 키워드를 쓸 수 없다.
          (다른 클래스에서 인스턴스(객체) 생성이 불가능하다)

    (2) public getInstance() 를 부여하고 해당 메서드 안에
          new 키워드로 인스턴스를 생성한다면 
          모든 다른 클래스에서 getInstance() 를 통해서 생성자에
          접근 가능하다.

    (3) getInstance()안에 인스턴스 유무를 체크해서 없는 경우에만
          객체를 생성한다면 기존 인스턴스가 있는 경우 추가로
          인스턴스를 만들지 않는다.

    (4) 만들었던 기존에 있던 해당 인스턴스를 리턴함으로서
          한개의 인스턴스를 운용하게 됨
 
public class Singleton {
 private static Singleton uniqueInstance;
 
 private Singleton(){}
 
 public static Singleton getInstance(){
  if(uniqueInstance == null){
   uniqueInstance = new Singleton();
  }
  return uniqueInstance;
 }
}


  2) 싱글톤 패턴 개선방법1 (Thread상에서 Sync 기능 추가)
      멀티 스레드에서도 의도한 결과를 얻기 위해서
        쓰레드의 Synchronized 를 이용하면 될듯
      다른 소스는 똑같고 getInstance() 앞에 synchronized 키워드만
        추가한다.
 
 public static synchronized Singleton getInstance(){
  if(uniqueInstance == null){
   uniqueInstance = new Singleton();
  }


  3) 싱글톤 멀티스레드 동기화 개선방법
       이러면 처음 호출시 바로 인스턴스는 생성되고 다른데서 호출하는
       getInstance() 에서는 인스턴스만 리턴한다.
 
public class Singleton {
 private static Singleton uniqueInstance = new Singleton();
 
 private Singleton(){}
 
 public static synchronized Singleton getInstance(){
  return uniqueInstance;
 }
}


  4) 싱글톤 멀티스레드 동기화 개선방법2
       3)와 같으나 다른점은 DCL(Double-Checking Locking) 기능을 써서
       getInstance() 에서 동기화되는 부분을 줄이게 된다.
       소스가 좀 방어적으로 작성되었지만
     이중 volatile 키워드는 멀티스레드에서 동기화를 해주는 키워드임

 
public class Singleton {
 private volatile static Singleton uniqueInstance = new Singleton();
 
 private Singleton(){}
 
 public static synchronized Singleton getInstance(){
  if(uniqueInstance ==null){
   synchronized (Singleton.class) {
    if(uniqueInstance == null){
     uniqueInstance = new Singleton();
    }
   }
  }
  return uniqueInstance;
 }
}


3. 다이어그램
    생략


4. 관련 패턴
  1) Abstract Factory 패턴
  2) Builder 패턴
  3) Facade 패턴
  4) Prototype 패턴

클래스 디자인 패턴 4. Factory Pattern_

1. 개념
  1) 발생 원인 :
     사용클래스 에서 뭔가 객체를 만들어 사용하려는데 기본적인 방법은
       new로 인스턴트를 만들어 사용하는 방법이다.
     근데 원본 클래스(기능구현 클래스)가 늘어나고 때에 따라 구현체
       선택이 자주 바뀐다면 음 고민되는 상태임
     물론 인터페이스 생성을 통해서 생성하고 있지만 조건에 따라
       수정이 필요한 부분도 있고, 어떤 구현체를 쓸지 분기를 따야
       될 수도 있음.
     수정이 커지면 해당 인스턴스 구현부에 관계된 부분에 소스가
       추가되고, 복잡해지고, 관계 없는것도 섞이고 실제 구현체도
       수정하는데 갖다 쓰는데도 수정해야되? 그리고 갖다 쓰는데가
       한 두군데로 끝나지 않을 수도 있지 않아?
      줄임 : 어떻게 해야 애플리케이션에서 구상 클래스의 인스턴스를
        만드는 부분만을 떼어내고, 캡슐화시킬 수 있을까?
  
   
  2) 정리
      그러면 구현시 사용 클래스를 상속하는 하단 클래스에서
        어떤 클래스인지 해당 클래스에서 작업해야 되는걸 분리
        할 수 있다면 수정이 이루어져도 사용하는 여러 작업이
        포함된 클래스를 건들지 않고 클래스는 좀더 늘었지만
      해당 작업에 좀더 관계된 클래스만 수정하여 원하는 효과를 
        얻을 수 있지 않을까? 라고 생각했다.

2. 소스
1> 간단한 형태의 구현
  1) 우선 Pizza랑 그 구현체 class에 대해서는 나중에 구현하고
       (Pizza는 interface일꺼고, 메서드4개는 최소한 정의되어 있을거고,
       구현체 피자들은 Pizza를 implements 했겠지)

      main 만 보자 여기에서는 orderPizza를 호출하는데 
        이때 타입 변수를 할당한다. 근데 이게 그때 그때
        뭘 호출할지 다른데

      막상 orderPizza 에 가보니 if 구문으로 문자열에
        따라 할당되어 있고, 그 밑에 공통함수도 같이 존재
        하고 있는 상태임.
 
public class PizzaStore {

  public static void main(String[] args) {
  orderPizza("cheese");
 }
 
 static Pizza orderPizza (String type){
  Pizza pizza=null;
  
  if(type.equals("cheese")){
   pizza = new CheesePizza();
  }else if(type.equals("pepperoni")){
   pizza = new PepperoniPizza(); 
  }else if(type.equals("clam")){
   pizza = new ClamPizza(); 
  }else if(type.equals("veggie")){
   pizza = new VeggiePizza(); 
  }
  
  pizza.prepare();
  pizza.bake();
  pizza.cut();
  pizza.box();
  
  return pizza;
 }
}


  2) orderPizza() 에서 if 구문만 빼서 따로 클래스를 생성한다.
        클래스 이름은 SimplePizzaFactory 라고 하고 
        안에 createPizza(type) 함수를 명시하자.
       if구문 하나있는거 떼어놓았는데 뭐가 틀리냐고?
        실 구동 클래스 main에 if가 하나만 있을리가 없다가 아닐까?
       각각의 결정이 필요한 분기문들이 하나의 클래스로 생성되고
        작성되면 당연하게 복잡도가 감소한다.
 
public class SimplePizzaFactory {
 static Pizza createPizza (String type){
  Pizza pizza=null;
  
  if(type.equals("cheese")){
   pizza = new CheesePizza();
  }else if(type.equals("pepperoni")){
   pizza = new PepperoniPizza(); 
  }else if(type.equals("clam")){
   pizza = new ClamPizza(); 
  }else if(type.equals("veggie")){
   pizza = new VeggiePizza(); 
  }
  
  return pizza;
 }
}


  3) 그럼 원본 클래스도 바뀐다. 이렇게 멤버변수로 
       생성자에 포함시켜 쓸수 있지만 상황에 따라 작성하면 될거고
       이제는 피자 종류가 늘어나도 PizzaStore를 고칠 필요없이
       SimplePizzaFactory 만 수정하면 원하는 목적을 이룰 수 있게 됨.
     다만 밑에 실행되는 함수는 해당 피자가 가지고 있는 함수랑
       동일하기 때문에(여기서는) 함수가 달라지면 역시 수정은
       필요하게 된다.
 
public class PizzaStore {
 SimplePizzaFactory factory;
 
// public PizzaStore(SimplePizzaFactory factory){
//  this.factory=factory;
// }
 
 public static void main(String[] args) {
  orderPizza("cheese");
 }
 
 static Pizza orderPizza (String type){
  Pizza pizza= SimplePizzaFactory.createPizza("cheese");
  
  pizza.prepare();
  pizza.bake();
  pizza.cut();
  pizza.box();
  
  return pizza;
 }
}


2> java Design 예제
  1) interface 를 각각 작성
 
public abstract class Product {
 public abstract void use();
}

 
public abstract class Factory {
 
 public final Product create(String owner){
   Product p = createProduct(owner);
   registerProduct(p);
   return p;
 }
 
 protected abstract Product createProduct(String owner);
 protected abstract void registerProduct(Product product);
}


  2) Product 를 상속받은 IDCard 클래스를 작성
 
public class IDCard extends Product {
 private String owner;
 
 IDCard(String owner){
  System.out.println(owner+"'s making card");
  this.owner = owner;
 }

 @Override
 public void use() {
  System.out.println(owner +"'s use card");
 }
 
 public String getOwner(){
  return owner;
 }
}


  3) Factory 를 상속하고 IDCard를 사용하는 IDCardFactory
      클래스를 작성
 
import java.util.Vector;

public class IDCardFactory extends Factory {
 private Vector owners = new Vector();
 
 @Override
 protected Product createProduct(String owner) {
  return new IDCard(owner);
 }

 @Override
 protected void registerProduct(Product product) {
  owners.add(((IDCard)product).getOwner());
 }

 public Vector getWoners(){
  return owners;
 }
}


  4) 테스트 코드를 작성
 
public class MainTest {

 public static void main(String[] args) {
  Factory factory = new IDCardFactory();
  Product card1 = factory.create("hong");
  Product card2 = factory.create("kim");
  Product card3 = factory.create("kang");
  
  card1.use();
  card2.use();
  card3.use();
 }
}


실행 : 
hong's making card
kim's making card
kang's making card
hong's use card
kim's use card
kang's use card


3. 다이어그램
    이번엔 소스먼저 확인했는데 이제 PizzaStore 에서는
      new는 SimplePizzaFactory 만 쓰고, 구현체 원본인 Pizza와
      그 밑의 잡다한 상세피자는 간접적으로만 관계를 맺게 되었다.

4. 관련있는 패턴
  1) Template Method 패턴
     Factory Pattern은 해당 패턴을 응용한 형태입니다.

  2) Singleton 패턴
     Create 를 이용하는 방식이 같습니다. 여기서는 Singleton이
      아니지만 쉽게 Sigleton으로 변경이 가능합니다.

  3) Composite 패턴
     Product 역할에 변화를 줘서 Composite 패턴을 적용 가능합니다.

  4) Iterator 패턴
     Iterator 패턴에서 iterator 메서드가 Iterator 인스턴스 작성시
      Factory Method패턴이 사용되는 경우가 있습니다.

신입SW인력을 위한 실전 JSP 동영상과정 - 제22강 파일 업로드

이 게시물은
http://www.wiz.center/209

의 동영상 강의를 시청하고 작성한 글입니다.
새로 시작하는 경우라면 위 링크의 동영상 강의를
들어보세요


1. 간단한 파일 업로드 기능을 구현한다.
    어차피 library 파일을 등록하고 이를 활용하는것이기 때문에
    어떤 library를 쓰느냐에 따라서 다른 기능을 하거나
    하는 운용이 가능하다.

  1) 우선 web application 프로젝트를 생성후
      강의 내용대로 cos.jar 파일을 lib 폴더 밑에 복사한다.
    http://www.servlets.com 접속 후
      좌측 메뉴 3번째 com.oreilly.servlet 클릭
      화면 전환되면 맨 밑에 cos-26Dec2008.zip 파일 다운로드
       압축파일 풀면  lib 폴더 밑에 cos.jar 파일이 생긴다.

  2) WebContent 폴더 밑에 fileFolder 폴더를 생성한다.

  3) fileinputForm.jsp 파일을 생성하고 아래와 같이 작성한다.
      여기서 중요한점은 form 생성시 enctype 을 주고
      enctype="multipart/form-data"> 를 추가해주는 것이다.
      이 옵션이 들어가야 파일을 정상적으로 전송 가능하다.
      input type="file" 은 지켜야되고 name은 임의 부여 가능하다.

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!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=EUC-KR">
<title>Insert title here</title>
</head>
<body>

<form action="fileFormOk.jsp" method="post" enctype="multipart/form-data">
파일 : <input type="file" name="file"><br />
<input type="submit" value="File Upload">
</form>

</body>
</html>

  4) fileFormOk.jsp 라는 jsp 파일을 생성하고 아래와 같이 작성한다.
      여기서 중요한건
      MultipartRequest(request객체 , 저장폴더명, 저장가능한 max사이즈,
                  "언어옵션 EUC-KR, UTF-8 등등",
                    new DefaultFileRenamePolicy() <-- 이걸 주면 같은 파일
                     이름이 이미 있을경우 뒤에 숫자를 붙여줘서 중복을
                     방지해준다.)
      그 밑에는 저장 후 객체에 파일이름, 기존 파일이름 을 가지고 오는데
          이에 대한 처리를 진행 할 수 있게 해놨다.
      해당 클래스에 대한 정보는 아래에서 확인

해당 클래스 설명API
http://www.servlets.com/cos/javadoc/com/oreilly/servlet/MultipartRequest.html

관련 예제(해당 문서와 중복되는 부분 있음)
http://egloos.zum.com/kamsi76/v/361961

<%@page import="java.util.Enumeration"%>
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%
String path = request.getRealPath("fileFolder");

int size = 1024 * 1024 * 10; //10M
String file = "";
String oriFile = "";

try{
MultipartRequest multi = new MultipartRequest(request, path, size, "EUC-KR", new DefaultFileRenamePolicy());

Enumeration files = multi.getFileNames();
String str = (String)files.nextElement();

file = multi.getFilesystemName(str);
oriFile = multi.getOriginalFileName(str);

} catch (Exception e) {
e.printStackTrace();
}
%>
<!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=EUC-KR">
<title>Insert title here</title>
</head>
<body>
  file upload success!
</body>
</html>

  5) 실행 결과 확인
      당연히 eclipse 에 표현된 폴더에는 안보인다.
        파일을 올려도 안보이는게 맞음.
        이를 확인하려면 tomcat 밑에 webcontent 밑에 해당
        프로젝트 밑에 파일이 들어가 있는지 확인하면 된다.
C:\apache-tomcat-7.0.63\서버에 등록한 폴더명\프로젝트명\fileFolder




신입SW인력을 위한 실전 JSP 동영상과정 - 제17~20강 데이터베이스, 컨텍션 풀

이 게시물은
http://www.wiz.center/204
http://www.wiz.center/205
http://www.wiz.center/206
http://www.wiz.center/207

의 동영상 강의를 시청하고 작성한 글입니다.
새로 시작하는 경우라면 위 링크의 동영상 강의를
들어보세요


1. JDBC - mysql
    JAVA API로 SQL문을 실행하여 데이터를 관리하기 위한 목적으로 제작됨
     DB 연결을 위한 별도 작업 없이 해당 라이브러리를 추가함으로서
     JAVA에서 쿼리문을 실행 가능하게끔 함.
   강의에서는 Oracel JDBC를 설명하나 여기서는 좀 가볍고 테스트 쉬운
     Mysql로 작업을 진행하도록 함.
   JDBC jar 드라이버는 아래 링크를 참고
http://ggoreb.tistory.com/121
http://hyeonstorage.tistory.com/112
 

2. 설정 방법
  1) mysql-connector-java-x.x.xx.jar (버전마다 상이함) 다운로드
      다운로드는 상단 JDBC 소계 링크에서 확인하여 구한다.

  2) library 등록
      그림과 같이 라이브러리를 WEB-INF/lib 밑에 드래그 해서
      등록한다.


  3) jsp 파일에서 db 연결 설정
      아래 그림을 참고한다.
        Driver가 정상적으로 로드되고, 실행순서가 일치하다면 쿼리가
        정상적으로 진행되고 결과를 ResultSet으로 받아 낼 수 있다.
   

  4) 사용
     resultSet 객체가 제공하는 함수를 이용해서 select 문에서
      받아낸 인자를 뽑아낼 수 있다.
     해당 클래스 관련 정보는 아래를 참고
http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html

여긴 한글 설명
http://noritersand.tistory.com/96

  5) 예제
------------------------------------
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.Connection"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%!
Connection connection;
Statement statement;
ResultSet resultSet;

// String driver = "oracle.jdbc.driver.OracleDriver";
// String url = "jdbc:oracle:thin:@localhost:1521:xe";
// String uid = "root";
// String upw = "tiger";
// String query = "select * from member";

String driver =  "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3336/jspex";
String uid = "root";
String upw = "";
String query = "select * from jspex.member";

//table이 없는 경우 아래 쿼리로 table 생성 및 자료를 입력한다.
// create table member (
// id varchar(20) primary key,
// pw varchar(20),
// name varchar(20),
// phone varchar(20));

//insert into member(id, pw,name,phone) values('abc','123','김수필','010-2222-3333');
// *insert를 4번 정도 입력하세요 다른 정보로

%>
<!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=EUC-KR">
<title>Insert title here</title>
</head>
<body>
<h1>start</h1>

<%
out.println(driver);
out.println(url);
out.println(uid);
out.println(upw);
try{

Class.forName(driver); //oracle.jdbc.driver.OracleDriver
connection = DriverManager.getConnection(url, uid, upw); //jdbc:oracle:thin:@localhost:1521:xe
statement = connection.createStatement();
resultSet = statement.executeQuery(query); //select * from member

while(resultSet.next()){
String id = resultSet.getString("id");
String pw = resultSet.getString("pw");
String name = resultSet.getString("name");
String phone = resultSet.getString("phone");

out.println("id : " + id + ", pass : " + pw + ", name : " + name + ", phone : " + phone + "<br />");
}

} catch(Exception e) {
e.printStackTrace();
} finally {
try{
if(resultSet != null) resultSet.close();
if(statement != null) statement.close();
if(connection != null) connection.close();
} catch(Exception e){}
}
%>

</body>
</html>
-----------------------------------
결과 :


3. 컨넥션 풀이란?
    1항목 JDBC를 사용할 경우 1개의 트랜젝션에
      여러 쿼리를 써야 할 경우 한번의 쿼리 실행시마다 db와 연결을
      요청하고 해제하는 작업이 필요하다
    연결에 대한 증명 정보를 서버에 저장하면 트랜젝션 시작~끝내
      1번의 연결을 유지할 수 있는 이점이 있어서 이걸 쓴다.
    그외에 따로 모듈을 빼서 연결하거나 하는 등의 방식도 있지만
     여기서는 컨넥션풀만 다룬다.


4. 설정 방법
  1) library 추가
     먼저 eclipse 에 tomcat-dbcp가 있는지 확인한다. 없는 경우
      설치된 tomcat/lib 폴더밑에 해당 jar 파일을 복사해서 lib밑에
      넣어주면 된다.
     본인 같은 경우 tomcat을 eclipse 상에 연동했기 때문에
      해당 폴더 밑 lib 의 jar 파일들이 다 로드 되어 있는 상태임
     만약에 위와 같이 library가 없는 또는 누락된 경우 tomcat/lib
       폴더에서 해당 tomcat-dbcp.jar 파일을 찾아서
       lib폴더 밑에 붙여준다.


  2) server- context.xml 의 Resource 부분 수정




  3) jsp에서 소스 변경하기
      상단 소스 부분에서 변경하고자 한다면
    (1) import Statement 를 변경
<%@page import="java.sql.Statement"%>
        를
<%@page import="java.sql.PreparedStatement"%>
        로 변경

    (2) statement 객체생성시 클래스 변경
      statement -> PrepareStatement

    (3) statement 객체에 connection 함수 변경
        기존
// statement = connection.createStatement();
        를
statement = connection.prepareStatement(query);
        로 변경

  3) 결과는 동일하게 출력된다. (그러면 성공)
      그러나 강제로 소스로 insert 를 다중으로 진행해야 하는 경우라면
      select 로 확인 후 insert를 하거나 update를 타야되는 경우라면
      트랜젝션이 2개 이상 쿼리로 구성되는 경우
     뿐만 아니라 사용자가 많으면 많을수록 웹서버에서
      db정보를 관리하는게 컴파일된 jsp servlet 까지 찾아서
      db연결하는것보다 낳다고 본다

      결론 : 우리 회사가 어느 부분으로 구현되어 있던지
               합당한 이유는 있으니 사용할 수 있도록 준비.

2015년 8월 26일 수요일

신입SW인력을 위한 실전 JSP 동영상과정 - 제16강 자바 빈 등록

이 게시물은
http://www.wiz.center/203

의 동영상 강의를 시청하고 작성한 글입니다.
새로 시작하는 경우라면 위 링크의 동영상 강의를
들어보세요


1. 자바빈 이란
    JSP 에서 java 객체를 쓸 수 있게 하는 방법
     (get, set을 포함하는 제한적인 방법이지만)
    그리고 객체 하나를 이용해서 게시판 리스트 등 큰 데이터를
     주거나 받는게 가능함.


2. 설정 방법
  1) Java 클래스 작성
 
package com.javalex.ex;
public class Student {
private String name;
private int age;
private int grade;
private int studentNum;
  public Student() {

    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public int getGrade() {
        return grade;
    }
    public void setGrade(int grade) {
       this.grade = grade;
    }
    public int getStudentNum() {
       return studentNum;
    }
    public void setStudentNum(int studentNum) {
       this.studentNum = studentNum;
    }
}


  2) bean 등록
     사용하고자 하는 jsp 파일에 아래 내용을 명시한다.
     양식은 xml 설정과 비슷하다. id, class위치, scope를 명시




  3) bean 설정 및 사용
      setProperty 와 getProperty를 사용해서 각 get, set 함수에
       접근 가능하다.
      이때 상단에 선언한 bean객체 id와 사용하고자하는 멤버의 
       name 값이 같아야 된다. property 를 key로 삼고, 
       value 값을 set 하거나 




      get 함수로 해당 value를 얻을 수 있다.



2015년 8월 25일 화요일

신입SW인력을 위한 실전 JSP 동영상과정 - 제13~15강강 쿠키 및 세션, 예외처리

이 게시물은
http://www.wiz.center/200
http://www.wiz.center/201
http://www.wiz.center/202

의 동영상 강의를 시청하고 작성한 글입니다.
새로 시작하는 경우라면 위 링크의 동영상 강의를
들어보세요


1. 쿠키(Cookie)
  1) 관련 설명은 하단 위키미디어 링크 참고 위키는 HttpCookie여서
      내부적으로는 틀린점이 있을 수 있으나 생성자나 사용하는
      메서드는 같았음.
https://ko.wikipedia.org/wiki/HTTP_%EC%BF%A0%ED%82%A4

  2) 쿠키 작성시 Javax.servlet 밑의 Cookie 클래스
     Object를 상속받음 클래스 생성시 생성자에
       네임, 밸류를 넣게끔 강제함.
https://docs.oracle.com/javaee/6/api/javax/servlet/http/Cookie.html


2. JSP 에서 쿠키 사용 방법
  1) 사용방법
     (1) Cookie 생성자로 name, value 셋팅하고
          필요시 set 함수로 옵션 설정
     Cookie cookie = new Cookie("cookieN", "cookieV");

     (2) HttpResponse 객체인 response.addCookie(객체명)
           하면 response에 cookie가 리스트로 저장된다.

     (3) 확인하고자 하는 페이지에서는 request.getCookie()를
           Cookie[] 쿠키 리스트로 받아서
           for문으로 걸러서 처리한다.
 
...
Cookie[] cookies = request.getCookies();
for(int i=0; i");
 out.println("cookies[" + i + "] name : " + cookies[i].getName() + "
");
 out.println("cookies[" + i + "] value : " + cookies[i].getValue() + "
");
 out.println("=====================
");
}
...
 

  2) 자주 쓰이는 메서드
     위의 HttpCookie 설명 구문에는 사용할 수 있는 메서드가
       많아 보이지만 실제로는 String 으로 활용하는 메서드 몇개가
       사용되는 함수 대부분이다.
     (1) 생성할때 꼭 넣어야 되는 쿠키이름을 얻는 메서드
        이건 set이 없음
        getName() : 쿠키 이름을 얻습니다.


     (2) 스트링으로 받을 수 있는 값, 유효기간, 유효디렉터리, 버전
         값의 get, set 하는 메서드가 잘 쓰이는 함수들임
        setMaxAge() : 쿠키 유효기간을 설정 합니다.
        getMaxAge() : 쿠키 유효기간 정보를 얻습니다.
        setpath() : 쿠키사용의 유효 렉토리를 설정 합니다.
        getPath() : 쿠키사용의 유효 디렉토리 정보를 얻습니다.
        setValue() : 쿠키의 값을 설정 합니다.
        getValue() : 쿠키의 값을 얻습니다.
        setVersion() : 쿠키 버전을 설정 합니다.
        getVersion() : 쿠키 버전을 얻습니다.



  2) 사용시 유의점
     (1) 객체 생성은 request 객체로
     (2) set, get은 cookie 나 cookie[] 객체에서
     (3) set을 한 이력이 있는 cookie객체는 response에 꼭 넣어줘야
          해당 변경 내용이 이후에 유효하게 설정된다.



3. 세션
  1) 관련 설명은 하단 위키미디어 링크 참고
      세션 요청은 브라우저가 하고, 내용저장은 서버에 한다.
      세션 유효시간은 서버 설정파일에 저장한다.
      세션 id를 브라우저엔진별로 부여받는데 그걸 암호로
       session 리스트에 접근할 수 있다.
http://mohwaproject.tistory.com/176

  2) 쿠키 작성시 Object 밑에 있고, Final 클래스로 작성함.
      해당 클래스는 javax.mail. 패키지 밑에 넣어
      사용자(브라우저) 요청시 자동 생성되도록 설정함.
https://docs.oracle.com/javaee/6/api/javax/mail/Session.html

4. JSP 에서 세션 사용 방법
  1) 사용방법
     (1) Session은 cookie와 달리 session 객체가 생성되어 있음.
          해당 객체의 메서드를 활용해서 add하면 저장된다.

 
...
session.setAttribute("mySessionName", "mySessionData");
session.setAttribute("myNum", 12345);
...


     (2) 가져올때는 getAttribute(name) 으로 가져오는데 결과는
          Object 로서 형변환 하여 사용한다.

 
String obj1 = (String)session.getAttribute("mySessionName");


     (3) 가져올게 확실히 있는지 모를 경우, 전체 처리가 필요한 경우
          Names 값을 한번에 가져올 수 있다.
         Enumeration 클래스는 객체 집합 Vector 의 존재 유무를 확인
          가능한 클래스다. while문과 함께 객체 순차처리를 위해
          사용한다.
http://hyeonstorage.tistory.com/210

 
//         Names 값으로 Value 까지 구해서 처리 구현 가능하다.
Enumeration enumeration = session.getAttributeNames();
while(enumeration.hasMoreElements()){
 sName = enumeration.nextElement().toString();
 sValue = session.getAttribute(sName).toString();
 out.println("sName : " + sName + "
");
 out.println("sValue : " + sValue + "
");
}


     (4) 세션 삭제시 부분 삭제

 
session.removeAttribute("mySessionName(name");


          와 세션 전체 삭제인

 
session.invalidate();

          두가지 메서드를 제공한다.


  2) 자주 쓰이는 메서드
     설명 구문에는 사용할 수 있는 메서드가 많아 보이지만
      실제로는 String 으로 활용하는 메서드 몇개가
      사용되는 함수 대부분이다
      설명은 위에 1) 항목을 참고바란다.


  3) 사용시 유의점 서버 설정에 세션 유지 시간이 길 경우
      서버 허용 용량을 초과하거나 느려지는 등의 모습이 보이기도 한다.

5. JSP 에서 예외처리 방법
  1)  jsp 파일에서 설정하는 바업ㅂ
    (1) 사용하는 jsp 페이지에서 지시자를 이용해서
        사용자가 지정한 에러 페이지를 설정한다.
        (물론 해당 페이지는 작성되어 있어야 한다.)
    <%@ page errorPage= "errorPage.jsp"%>

    (2) 진행시 에러가 발생하면 해당 에러 페이지로 넘긴다.
       int i = 40/0

    (3) errorPage.jsp 라는 에러 페이지에서는 먼저
        지시자를 이용해서 해당 페이지 속성이 에러 페이지임을
        명 (default = false 임)
    <%@ page iserrorPage= "true" %>

    (4) 해당 페이지 status를 정상범위인 200으로 설정
        response 상태코드에 대해서는 아래 글 참고
     <% response.setStatus(200); %>

위키
https://ko.wikipedia.org/wiki/HTTP_%EC%83%81%ED%83%9C_%EC%BD%94%EB%93%9C

java Response.Status 명세
http://docs.oracle.com/javaee/7/api/javax/ws/rs/core/Response.Status.html

    (5) (3) 항목과 같이 iserrorPage 속성을 true 로 설정시
         jsp 에서  exception 객체와 해당 함수를 사용 가능함.
        <%= exception.getMessage() %>

관련 클래스에서 쓸수 있는 함수는 아래 링크 참고
http://hyeonstorage.tistory.com/87

http://www.tutorialspoint.com/jsp/jsp_exception_handling.htm

  2) web.xml 설정
     jsp 나 servlet 에서 설정하는 것보다 간단하게 설정 할 수 있다.
     status 상태값에 따라 아래처럼 페이지를 지정하여 처리 가능함
    (여기서도 각각 jsp 페이지는 준비되어 있어야 함)

  
   404
   /error404.jsp
  
  
   500
   /error500.jsp
  
  


2015년 8월 15일 토요일

리눅스 서버 알아보기_09. Mysql서버

1. 설치
  1) mysql 설치, 압축풀기
>tar xvfz mysql~~.tar.gz

  2) configure
 >./configure \
   --prefix=/apm/mysql \
   --with-charset=euc_kr \ -->한글정렬사용 옵션
   --localstatedir=/apm/mysql/data -->물리 자료 저장 위치

  3) make
>make;make install    <--2개 명령어 같이 진행

mysql의 경우
>/bin/mysql_install_db
      <--이걸 실행해야 최초 실행준비 상태가 됨

mysql 실행파일
>safe_mysqld &   <--프로세서(백그라운드)로 실행한다.
    근데 실행해도 프로세서가 뜨는게 안보임
    이유
    실행계정이 mysql, mysql
    다른 서버의 경우 : nobody, nobody
  첫번재 계정문제를 해결해야 함. + 권한은 시스템 계정 권한
>useradd mysql
>groupadd mysql

 두번째 소유권 문제 mysql 은 master 권한이 필요함

>chown -R root /mysql
>chown -R mysql /mysql/data
>chgrp -R mysql /mysql
   : chown 소유권 변경
   : chgrp 그룹 소유권 변경

>ls 하면 소유권은 root 이나 그룹 은 mysql로 변경됨

> ./safe_mysqld &
엔터
>ps -ef|grep mysqld
~~~~ 뜨면 성공

2. 실행(쿼리 분석기 실행)
>./mysql
~~~~
mysql>show databases;
~~~db 목록 보여줌
mysql>use db목록중 하나 선택;
mysql>show tables;
~~~해당 db밑의 table 목록을 보여준다.

mysql> select user(); <--누구로 접속했는지 확인
mysql>exit  <--쿼리 분석기 종료


>vi /etc/rc.d/rc.local <-- 자동 시작 추가
~~~~
rdate -s time.bora.net
/apa/apache/bin/apachectl start
/mysql/bin/safe_mysqld &

중지
killall mysqld

프로세스 확인
ps -ef|grep mysqld

3. 권한관리(mysql 접속 pass설정)
>vi member.sql
create table member2
(
    unum    int auto_insrement primary key,
    uname   varchar(20) not null,
    uage     tinyint default 0
);

>mysql mydb <member.sql
  -> 이런식으로 실행 가능 mysql db명 <(쿼리작성 파일명)

  1) mysql 에 패스워드 붙이기
      mysql 최고 계정은 root@
    해당 정보는 mysql db에 user 테이블안에 보유

mysql>use mysql
mysql>show tables
~~~~~~
user

**** 컬럼이 많아서 그냥 보기엔 좀 힘드니 보통 3개정도가
      가장 중요한 정보로 많이 보게된다.
mysql>select host, user, password from user;

password를 업데이트문을 사용해 변경 하고 이를 msyql
       daemon에 반드시 알려줘야 되는데 이를
       아래 명령을 통해서 하고 있다.
mysql>flush privileges

이후 로그인 진행시(pass가 있어서 root만 적으면 접근이 제한)
mysql -u root -p 엔터
   password입력 후 msyql 컨텐츠를 즐기세요

4. 백업 및 복구
  1) 백업
mysqldump [db명] > [백업명] -u root -p 112121 -h localhost(로컬호스트는 생략가능)

  2) 복구
mysql < [백업명] -r root -p1


  3) mysql 쵝고 계정을 분실시
    mysql daemon kill

    mysql 시작시 mysqlDB user 테이블 정보 인식하지 않고 시작
    ==> 계정 몰라도 시작 할 수 있음(root 계정만 가능)

또는
safe_mysqld -skip-grant-tables &
--> 해당 명령어도 마찬가지로 root만 조작 가능


2015년 8월 14일 금요일

리눅스 서버 알아보기_08. Apache서버

1. apache 설치
    이전 설치는 진행 (해당 내용의 압축및 묶음 부분 참고)
    혹은 해당 설치 메뉴얼 참고

  1) 압축 풀기
듣고 있는 강의에서는 apache_1.3.34.tar.gz 파일로 진행
>tar xvfz apache_1.3.34.tar.gz
.....(압축 풀림)

  2) 설치 준비 (원하는 폴더에 설치하도록 준비)
>ls
....
Makefile.tmpl
......

>vi Makefile.tmpl
~~~~
69line   prefix = @prefix@
~~~~
***prefix가 설치 path 임 여기서는 변수명으로 셋팅되어
  있는데 사용자가 옵션을 줘서 설치 경로를
  지정 할 수 있다.

***apache 옵션값 설정은 configure 라는 실행파일을
    실행함으로서 설정 가능하고 명령어 끝에 \ 표시시
    다음줄에 옵션 부여 가능 이때 위에서 확인한 prefix 라는
    옵션값을 부여하면 해당 옵션이 적용된다.

>./ configure \
--prefix=/apm/apache
~~~~(설치준비 상태)

>vi Makefile.tmpl
~~~~~
69line prefix     = /apm/apache
~~~~~
****변경되어 있는걸 확인하면 ok

  3) 컴파일 진행 (설치)
>make
~~~~~ 컴파일을 진행한다.

  4) 컴파일된 파일을 옵션 설정된 폴더에 설치 진행한다.
>make install
~~~~~설치중
/apa/apache/conf/httpd.conf (메인 설정파일)

/apa/apache/bin/apachectl start (실행 파일)
~~~~~위 메시지를 확인할 수 있다.

  5) 이전 설치 내용 확인 및 프로세스 실행
>rpm -qa|grep httpd
****아직 설치된 내용이 뜨지 않음
     혹시 다른게 떠있으면 삭제 필요
>rpm -e httpd* --nodeps
    (의존성 무시하고 삭제 * 대신
      들어가는 문자를 일치해서 삭제 할 것)

apa/apache/bin>./apachectl start
>ps -ef|grep httpd
~~~근데 꽤 많음... 접속 사용자마다 프로세스가 할당되기
      때문에 몇개 미리 띄워둔것
      옵션 파일 설정을 통해서 프로세스 갯수를 조정 가능함

웹 브라우저에서 자신 ip접속시 사이트가 하나 뜨면 끝


2. 실행관련 정보
>./apachectl start
>./apachectl stop

****프로세스가 안떨어질 경우
>ps -ef|grep httpd
>killall httpd (여러 같은이름 프로세스를 같이 날리기

****패스를 잡아주고 어느 위치에서든
     명령어만으로 실행 가능

  1) 실행파일 패스 등록하기
>vi .bach_profile
~~~~
PATH=$PATH:$HOME/bin:/apm/apache/bin:경로추가1:경로추가2
~~~~~
:wq
****windows 는 ; 로 구분하는데 여기는 : 로 구분하는것만
     다르고 같음, 리눅스는 로그인, 아웃 한번 해서
     해당 파일을 한번 읽게끔 해야 적용 가능함

  2) 실행파일 자동 시작 등록하기
      :ntsysv에서 체크한 데몬만 자동시작함

[/etc/rc.d/rc.local]
**** 사용자가 정의하는 배치파일이 등록되어 있음
여기에 /apa/apache/apachectl start 를 등록하려고 함
>cd /etc/rc.d
>ls
~~~
rc.local
~~~~

>vi rc.local
~~~~
touch /var/lock/subsys/local
/apm/apache/bin/apachectl start

:wq

>reboot
~~~~~
>ps -ef|grep httpd
~~~~ 뜨면 됨

이런 절차를 ntsysv에서 자동 설정가능
   실행 후 프로세스를 체크하면 됨


ps. 폴더 권한 이해
-rwxrwxrwx (파일 r(읽기), w(쓰기, 수정, 삭제), x(실행))
drwxrwxrwx(디렉토리 r(ls 가능여부),
                            w(디렉토리 안에 파일 생성, 삭제, 수정),
                            x(접근 가능 여부))

**** 디렉토리에서 r 과 x 의 차이점
>cd home/babo    ****일반 사용자 계정홈 디렉토리
>mkdir test
>ls
drwxr-xr-x 2 root    root   ~~
****root 만 접근되고 다른데서는 ls, 접근만 가능
      test 폴더안에 폴더나 파일 생성은 불가

>chmod 700 test
>ls
drwx------ 2 root    root   ~~~
**** 아예 들어가지 못하는 상태

>mkdir test2
>chmod 701 test2

>cd test
>cat >aaa.txt
>cd /home/babo/test2
>cat >aaa.txt

ls
~~~~
-rw-r--r-- 1 root   root    ~~~
**** 파일은 읽은수는 있음

**** 일반 계정으로 접근하여 test 폴더 접근
>ls -al|grep test
>cd test
-----접근 불가

>cat test/aaa.txt
-----파일에도 접근 불가함

**** test2 접근
>ls -al |grep test2
~~~~
drwx-----x ~~~~
~~~~

>cd test2    (폴더 접근은 가능해짐)
>ls
---- 접근불가(r원한 없으므로 접근은 되나 ls명령은 안됨)

>cat test2/aaa.txt
hello

-----ls은 안되는데 안의 aaa.txt는 접근 가능함!!!


3. 주요 구성 파일 [conf/httpd.conf] 살펴보기
>vi /apm/apache/conf/httpd.conf
:se nu
****거의 1000라인 정도 됨

****/apm/apache/conf/httpd.conf.default <-- 백업파일


  1) 전역 환경 구간 : 41line section1
      .....
52line  
     ServerType standalone    
  ****자주 쓰는 서버라서 항상 대기하고 있는 타입

63line
     ServerRoot "/apm/apache"
  ****기본 폴더

80line
     PidFile  /apm/apache/logs.httpd.pid
  ****프로세서가 생성되는 기본 파일명

99line
     ResourceConfig /apm/apache/conf/srm.conf
     AccessConfig    /apm/apache/conf/access.conf
  ****현재는 설정파일이 한개이지만 이전에는
       3개의 설정파일이 있었음 현재는 주석처리되어 있음

105line
     Timeout 300
  ****유저 세션 유지 유효시간

139line  **** 자주 손대는 부분 
     MinSpareServers 5
     MaxSpareServers 10
  ****daemon을 5~10개 유지하겠음 (서버 부하에 따라서)
     StartServers 5
  ****최초 시간 프로세스 갯수

155line
     MaxClients 150
  ****동시접속자

171line
    MaxrequestsPerChild_0
  ****아파치웹서버가 요청에 대해 세션 처리하는
        프로세스 갯수를 설정 현재 무한대

178line
     Listen 3000
  ****처리포트 지정 현재 주석처리되어 있음


  2) 메인서버구성구간 213Line Section2
236line
     Port 80
  ****서버 가동 포트

250line
     User nobody
     Group nobody
  ****daemon 프로세서 등록시 사용하는 계정

258line
     ServerAdmin ~~
  ****Admin 이메일 계정

283line
     DocumentRoot "~~"
  ****웹 요청에 대해서 어느 폴더로 안내할 것인가

293line
     <Directory />
             Options FollowSymLinks
             AllowOverride None
     </Directory >
  ****FollowSymLinks 
         심볼링 링크를 허가+기본 폴더 이외 폴더까지 포함
>cd /
>cat > aaa.txt
~~~It's station root by aaa.html
>cd /apm/apache/htdocs
>ln -s /aaa.html a.html
웹사이트 접속 : ip/a.html <-- 접속 가능
    옵션 삭제후 재시작시 a.html 접속 불가
  ****AllowOverride None
         사용자 계정을 물어보지 않고 요청에 진행
         웹서버 특성상 사용자 체크 하지 않음

317line
     <Directory />
      ~~~~
             Options Indexes FollowSymLinks MultiViews
      ~~~~
     </Directory >
  **** Indexes
          디렉토리 보여주기 기능을 포함할지 안할지 여부

317line
     <Directory />
      ~~~~
             Options Indexes FollowSymLinks MultiViews
      ~~~~
     </Directory >
  **** Indexes 
          디렉토리 보여주기 기능을 포함할지 안할지 여부
          요청 파일이 디렉토리에 없는 경우
          (디렉토리는 있는 경우)디렉토리를 보여줌
  **** MultiViews
          언어별 대응 옵션.. 거의 사용하지 않음

324line
     <Directory />
      ~~~~
             AllowOverride None
      ~~~~
     </Directory >
  **** AllowOverride 사용자가 누구인지 물어보지 않는다.

329line
     <Directory />
      ~~~~
             Order allow, deny
             Allow from all
             Deny from ip
      ~~~~
     </Directory >
  ****  Allow or Deny
          tcp/ip 레벨에서 사용자 ip에 따라 막는지 여부를 체크

339line
     <IfModule mod_userdir.c />
             UserDir public_html
     </IfModule mod_userdir.c >
  **** mod_userdir.c
>httpd -l
****apache에 설치된 모듈을 보여준다.
      이중 mod_userdir.c 라는 내용이 있는 경우
      public_html로 안내하도록 하는 기능
      이 옵션을 통해서 호스팅 서비스가 가능하다.

    여기서 아래처럼 변경한다.
     <IfModule mod_userdir.c />
             UserDir www
     </IfModule mod_userdir.c >
+
346line
     <Directory /home/*/www
     </Directory>
  **** 사용자 디렉토리 mod_userdir.c 설정시
      directory 부분 주석을 풀어준다.
그리고 사용자 babo에 대해서
>mkdir /home/babao/www
> cd /home/babo/www
>catch aaa.html
~~~~here aaa by babo
그리고 웹 브라우저로 접속
http://ip/~babo
안들어가지면 익명 사용자 권한 확인 할 것
   (babo 폴더, 안의 html문서 )

346line
     <Directory /home/*/www
     </Directory>
  ****

483line
     CustomLog /apm/apache/logs/access_log common
  **** 사용자 접속시 남기는 로그 정보의 저장
        맨 뒹 common은 type
        agent
        refrear
        common
        combined
    (471라인부터 각 옵션에 대해 뭘 저장할 건지 설정 가능하다.)

  3) 가상 호스트


4. 사용자별 홈 디렉토리 접근하기
기본 설정
    위 설명중 339line, 346line 확인할 것

추가
www.hostion.co.kr ->/apm/apache/htdocs/index.html
www.john.co.kr -> /home/john/index.html
www.mark.co.kr -> /home/mark/index.html


첫번째 DNS 구성
>vi /etc/named.conf
   ~~~~
 zone "hosting.co.kr" IN{
         type master;
         file "hosting.zone";
};
 zone "john.co.kr" IN{
         type master;
         file "john.zone";
}; zone "mark.co.kr" IN{
         type master;
         file "mark.zone";
};
:wq

>cd /var/named
>cp localhost.zone hosting.zone   (정방향 샘플 복사)
>vi hosting.zone
~~~~
$TTL  86400
$ORIGIN hosting.co.kr
@                    1D IN SOA       @ ns.hosting.co.kr. (
                                  423 ; serial (d. adams)
                                  3H ;  refresh
                                  15M ; retry
                                  1W ; expiry
                                  1D ) ; minimun
                    1D IN NS        ns.hosting.co.kr
                    1D IN A        본인 ip
ns                      IN A        본인 ip
www                  IN A        본인 ip
:wq

>cp hosting.zone mark.zone
>cp hosting.zone john.zone
   두 파일은 위의 진한 부분만 mark, john 으로 교체
   네임 서비스 재시작 (안죽으면 킬로 날린 후 재시작)
확인 >nslookup 으로 확인


두번째 사용자가 없는 경우 만들어 둔다.

>useradd john
>passwd john
    pssword  입력
>useradd mark
>passwd mark
    password 입력

>cd /home
>ls => john, mark 폴더 있는지 확인
>cd /home/mark
>cat > index.html
   www.mark.co.kr site
ctrl+z

>cd /home/john
>cat > index.html
   www.john.co.kr site
ctrl+z


세번째 웹서버 구성(옵션 설정)


>vi /apm/apache/conf/httpd.conf
Section3 부분으로 이동 - 1아이피 여러사이트 만들시 사용

930line
   NameVirtualHost 본인ip 혹은 *:80
  **** 어느아이피의 어느포트를 가상호스트로 사용할 것인가
        ip가 하나면 ip를 여러개 다 적용할 거면 * 를 기입

938line
#<VirtualHost *:80
#     ServerAdin webmaster@dummy-host.example.com
#     DocumentRoot /www/docs/dummy-host.example.com
#     ServerNAme dummy-host.example.com
#     ErrorLog logs/dummy-host.example.com-error_log
#     CustomLog logs/dummy-host.example.com-access_log common
#</VirtualHost>
  **** 샘플 파일인데 이를 똑같이 복사해서 작성
          관리가 이메일
          안내 폴더
          사용자가 접속해야되는 문자열(사이트명)
          로그, 접속 정보 쌓는 파일명
      위의 3가지 중요하고 밑의 두가지는 부가적임

<VirtualHost *:80
     ServerAdin admin@john.co.kr
     DocumentRoot /home/john
     ServerName www.john.co.kr
     ServerAlias  john.co.kr
     ErrorLog /home/john/error_log
     CustomLog /home/john/access_log common
</VirtualHost>

>/apm/apache/bin/httpd -t   (httpd 문법 에러 체크)

ServerAlias 는 별칭을 붙이는거  www안붙여도 접속되게끔
   설정 가능하게 한것.
네번째 권한 확인(폴더 및 확인용 index파일)
   디렉토리 최소한 701 이상 부여

다섯번재 테스트(데몬재시작 및 접속하기)
dns 서버를 잡아주고 브라우저 띄워서 접속 진행
mark도 똑같이 진행

5. 인증 사이트 서비스 제공하기

http://ip/member/~
   


>/apm/apache/conf/cp httpd.comf.default httpd.conf

>vi /apm/apache/conf/httpd.conf
370line
AccessFileName .htaccess
<Directory /apm/apache/htdocs/member>
          AllowOverride Authconfig
          AuthName "Input your id and password":
          AuthType Basic
          AuthUserFile /apm/apache/htdocs/member/.htpasswd
          <Limit POST  GET>
                 require valid-user //인증된 사용자만 허락 여부 옵션
          </Limit>
          Order allow, deny
          Allow from all 
     </Directory>

  **** .htaccess 에 있는 사용자고
        .htpasswd 에 암호가 일치한 사용자만
        접근하게끔 작성 <Limit옵션>
>/apm/apache/bin/httpd -t

>mkdir /apm/apache/member
>cat > /apm/apache/member/index.html
~here your zone your our member

>apachectl restart

>/apm/apache/bin/htpasswd -c /apm/apache/htdocs/member/.htpasswd babo
password 물어봄

>cat /apm/htdocs/member/htpasswd
babo 유저에대한 암호가된 비번이 작성되어 있음

웹 브라우저에서 접속
 http://ip/member
    계정을 물어봄 여기에 id, pass를 입력시 들어가짐

6. 각 사이트별 포트를 다르게 설정하기
    (가상 호스트를 이용한다.)
    본인ip:80
    본인ip:2000
폴더 및 문서 작성
htdocs\2000\index.html
htdocs\3000\index.html

>cp httpd.conf.default httpd.conf
>vi httpd.conf

178line
     Listen 80
     Listen 2000
     Listen 3000
  ****포트를 추가함

섹션3 - 네임기반이아니기 때문에
          이전 예제처럼 NameVirtualHost는 설정할 필요 없음
<VirtualHost 본인ip:3000>
     DocumentRoot /apm/apache/htdocs/2000
    # ServerName    www.john.co.kr 
    #않넣어도 ip로 접근가능
    # serverName 지정시 도메인명으로 접근 가능
</Virtualhost>
<VirtualHost 본인ip:2000>
~~~이전 단락의 내용을 본인거에 맞게 작성
</Virtualhost>

웹으로 접근 http://본인ip:2000