2013. 7. 29. 16:04

.

하지만 자바 리플렉션도 같은 기능을 제공한다고 생각할 수도 있다. 결국 이 모든 정보에 대한 코드를 검사할 수 있다. 표면적으로 볼 때 그럴 듯 하지만 실제로 그렇지 않다. 

많은 경우 메소드는 인풋으로서 받아들이거나 아웃풋으로 리턴한다. 이는 메소드가 원하는 것이 아니다. 예를 들어, 매개변수 유형이 Object이지만 메소드는 Integer를 사용해서만 작동한다. 

 

이는 메소드가 겹쳐 쓰기된 곳에서 쉽게 발생할 수 있다. 그리고 슈퍼클래스가 메소드를 일반 매개변수로 선언하던가 많은 직렬화가 진행되는 시스템에서도 쉽게 발생한다. 두 경우 모두 메타데이터는 코드 분석 툴을 지정할 수 있다. 매개변수 유형이 Object이더라도 정말로 원하는 것은 Integer라는 것을 나타낼 수 있다. 이러한 종류의 분석은 상당히 유용하며 그 가치는 상당하다. 

 

보다 복잡한 경우 코드 분석 툴은 모든 종류의 추가 태스크들을 수행할 수 있다. 그 예 중 하나가 Enterprise JavaBean (EJB) 컴포넌트이다. 심지어 간단한 EJB 시스템으로의 의존성과 복잡함은 상당하다. 

로컬 인터페이스와 로컬 홈 인터페이스의 가능성과 함께 홈 인터페이스와 원격 인터페이스를 얻는다. 이 모든 클래스들을 연동시키는 것은 진정한 고통이다. 하지만 메타데이터는 이 문제에 대한 솔루션을 제공한다. 좋은 툴은(예를 들어, XDoclet)은 이 모든 의존성을 관리하면서 "코드-레벨" 연결이 없지만 "로컬-레벨" 관계를 가진 클래스들이 연동될 수 있도록 한다. 이것이 바로 메타 테이터의 진정한 가치이다. 

 

2. Annotation의 종류

 1) Mark Annotation

   변수가 없다. 이 어노테이션은 이름으로 구분되며 추가 데이터 없이 나타난다. 예를 들어, 

 

@MarkerAnnotation은 marker 어노테이션이다. 데이터가 없으며 단지 어노테이션 이름만 있을 뿐이다.

   예) @Stateless

 


2) Single-value Annotation

   marker와 비슷하지만 데이터를 제공한다. 싱글 비트 데이트를 제공하기 때문에 간단한 신택스를 사용할 수 있다. (단, 어노테이션 유형이 이 문법을 수용해야 함)

 

@SingleValueAnnotation("my data")이는 @표시만 제외하고는 일반적인 자바 메소드 호출과 비슷하다.

   예) @Resource("mappedName=PERSON")

 


 3) Full Annotation(Multi value Annotation)

   다중 데이터 멤버를 갖고 있다. 결과적으로 전체 신택스를 사용해야 한다. (그리고 어노테이션은 일반 자바 메소드와 더 이상 비슷하지 않다) 

 

@FullAnnotation(var1="data value 1", 

var2="data value 2", var3="data value 3") 

 


 4) 커스텀 annotation 구현 : 개발자가 직접 annotation을 구현


public @interface TODO {      // Single-Value Annotation
            String value();       // value가 아닌 다른 이름을 사용하면 사용시 메소드 이름을 써준다
    }
 
    // @TODO("Something todo")
 
    public @interface TODO{      // Single-Value Annotation
            String msg();        // value가아닌다른이름을사용한경우
    }
    // @TODO(msg="Something todo")



3. Annotation을 구분하는 또 다른 기준

 1) Simple Annotation

    메소드나 변수 위에 붙이는 일반적인 Annotation

 

 2) Meta Annotation

    Annotation의 Annotation(다른 Annotation 위에다가 설정)

 

 

4. Meta Annotation

 1) @Target annotation

    작성한 annotation이 어디에서 사용하게 될지를 결정


@Target(
{
                ElementType.TYPE,              // 클래스,인터페이스,enum
                ElementType.METHOD,            // 생성자를 제외한 모든 메소드
                ElementType.CONSTRUCTOR,       // 생성자
                ElementType.ANNOTATION_TYPE    // 메타 annotation
         }
)


2) @Retention annotation([속성값])

   작성한 annotation의 지속성을 설정

 

   - RetentionPolicy.SOURCE : 컴파일러가 컴파일시 삭제하여 클래스 파일에 저장되지 않는다

   - RetentionPolicy.CLASS : 클래스 파일에 저장되지만 JVM은 무시

   - RetentionPolicy.RUNTIME : 클래스 파일에 저장하고 JVM

 

 

5. 내장 Annotation

 1) @Override

   슈퍼클래스의 메소드를 오버라이드


public class OverrideTester {
    public OverrideTester() { }
 
    @Override
    public String toString() {
      return super.toString() + " [Override Tester Implementation]";
    }
 
    @Override
    public int hasCode() {
      return toString().hashCode();
    }
  }
 


 2) @Deprecated

    Override와 마찬가지로 Deprecated는 marker 어노테이션이다. Deprecated를 사용하여 더 이상 사용되지 말아야 하는 메소드에 주석을 단다. Override와 다른 점은, Deprecated는 더 이상 사용되지 말아야 하는(depreciated) 메소드와 같은 라인상에 놓여져야 한다.


public class DeprecatedClass {
    @Deprecated public void doSomething() {
      // some code
    }
 
    public void doSomethingElse() {
      // This method presumably does what doSomething() does, but better
    }
  }


 3) @SuppressWarnings

   번거로운 경고를 제거한다.

   Override와 Deprecated와는 다르게 SupressWarnings는 변수를 갖고 있다. 따라서 이를 작동하게 하려면 싱글-어노테이션 유형을 사용한다. 값 어레이로서 변수를 제공할 수 있다. 각각 삭제할(Suppress) 특정 유형의 경고를 나타낸다.


@SuppressWarnings(value={"unchecked"})
  public void nonGenericsMethod() {
    List wordList = new ArrayList();
    wordList.add("foo");
  }



'Framework > Spring' 카테고리의 다른 글

Spring Framework/ DI / IOC 컨테이너 / POJO  (0) 2013.07.30
Annotation_Spring_MVC_2  (0) 2013.07.29
Annotation_Spring_MVC_1  (0) 2013.07.29
Posted by 1+1은?
2013. 7. 29. 15:50

AbstractController을 이용한 스프링 컨트롤러 작성

설명


MultiActionController을 이용한 스프링 컨트롤러 작성

예제

설명


'JSP > JspServlet' 카테고리의 다른 글

tag : core  (0) 2013.08.16
서버 도메인 확인  (0) 2013.08.16
MVC 관련 핸들러 매핑 및 컨트롤러  (0) 2013.07.29
액션 태그와 커스텀 태그  (0) 2013.07.29
파입업로드/다운로드  (0) 2013.07.29
Posted by 1+1은?
2013. 7. 29. 15:40




■ Spring MVC의 주요 구성 요소

 

 

- DispatcherServlet

클라이언트의 요청을 전달받는다. Controller에게 클라이언트의 요청을 전달하고, Controller가 리턴 한 결과 값을 View에 전달하여 알맞은 응답을 생성하도록 한다.

 

- HandlerMapping

클라이언트의 요청 URL을 어떤 Controller가 처리할지를 결정한다.

 

- Controller

클라이언트의 요청을 처리한 뒤, 그 결과를 DispatcherServlet에 알려준다. 스트럿츠의 Action과 동일한 역할을 수행한다.

 

- ViewResolver

Commander의 처리 결과를 보여줄 View를 결정한다.

 

- View

Commander의 처리 결과를 보여줄 응답을 생성한다.

 

 

 

■ HandlerMapping

클라이언트의 요청을 Spring의 DispatcherServlet이 처리하도록 설정했다면, 다음으로 해야 할 작업은 어떤 HandlerMapping을 사용할지의 여부를 지정하는 것이다. HandlerMapping은 클라이언트의 요청을 어떤 Controller가 수행할 지의 여부를 결정해주는데, 구현 클래스는 다음과 같다.

 

- BeanNameUrlHandlerMapping : 요청 URI와 동일한 이름을 가진 Controller 빈을 매핑 한다.

- SimpleUrlHandlerMapping : 패턴과 컨트롤러의 이름을 비교 URI가 패턴에 매칭될 때 지정한 컨트롤러를 사용 한다.

- ControllerClassNameHandlerMapping : URI와 매칭 되는 클래스 이름을 갖는 빈을 컨트롤러로 사용 //잘 쓰지 않음

- DefaultAnnotationHandlerMapping : @RequestMapping 어노테이션을 이용하여 요청을 처리할 컨트롤러를 구한다. //annotation을 사용할 경우 핵심

 

ο  BeanNameUrlHandlerMapping

BeanNameUrlHandlerMapping은 요청 URI와 동일한 이름을 갖는 Controller 빈으로 하여금 클라이언트의 요청을 처리하도록 한다. 예를 들어,http://host/hello.action 과 같은 요청 URL에 대해 "/hello.action" 라는 이름을 가진 Controller 빈이 해당 요청을 처리하도록 한다.

 

다음과 같이 alwaysUseFullPath를 true로 설정 하고 다음과 같이 빈을 설정 한 경우


 
         
     
 
     
     

 이 경우 요청 URL을 처리하는 컨트롤 빈은 다음과 같이 매핑 된다.

 

     - /content/**/*.action 빈

       /content/1/test.action

       /content/top/exam.action

 

    -  /hello/hello.action 빈

       /hello/hello.action

 

     - Ant 경로 패턴

       Ant는 자바 기반의 빌드 도구로서 『?』, 『*』, 『**』를 이용하여 경로 패턴을 명시하고 있으며, BeanNameUrlHandlerMapping과 SimpleUrlHandlerMapping은 Ant의 경로 패턴을 이용하여 요청 URL과 컨트롤의 매핑을 처리 한다.

 

       ? : 1개의 문자와 매칭

       * : 0개 이상의 문자와 매칭

       ** : 0개 이상의 디렉토리와 매칭

 

 

ο  SimpleUrlHandlerMapping

SimpleUrlHandlerMapping은 가장 많이 사용되는 HandlerMapping으로 패턴 매칭을 이용해서 다양한 URL 경로를 컨트롤러에 매핑 시켜준다.

 

SimpleUrlHandlerMapping은 다음 처럼 mappings 프로퍼티를 이용하여 패턴과 컨트롤러 사이의 매핑을 지정한다.


 
          
             contentController
             helloController
         
     
 
     
     

SimpleUrlHandlerMapping의 mappings 프로퍼티는 java.util.Properties 타입이다. mappings 프로퍼티의 값에 전달되는 <prop>의 key는 요청 URL과 매칭 될 Ant 경로 패턴을 입력하며 <prop>의 값에는 매핑될 컨트롤러의 이름을 입력 한다.

 

 

■ MVC 관련 컨트롤러

   ο  Controller 종류

     - Controller (interface)

     - AbstractController

     - MultiActionController

 

 

   ο Controller 인터페이스

Controller를 구현하는 가장 간단한 방법은 Controller 인터페이스를 implements 하는 것이지만, Controller 인터페이스를 직접적 implements 하기 보다는, Controller 인터페이스를 implements 하고 몇 가지 추가적인 기능을 구현하고 있는 클래스들을 상속받아 Controller를 구현하는 것이 일반적이다.

 

org.springframework.web.servlet.mvc.Controller 인터페이스는 다음과 같이 정의되어 있다.


public interface Controller {
           ModelAndView handleRequest(HttpServletRequest request,   HttpServletResponse response)    throws Exception
      }

ο AbstractController 추상 클래스

      Controller 인터페이스를 구현한 추상 클래스로 단순히 클라이언트의 요청을 처리한 뒤 ModelAndView 를 리턴할 경우에 AbstractController 클래스를 상속 받아 컨트롤러를 구현 한다.

 

      AbstractController 클래스는 다음과 같이 handleRequestInternal() 추상 메소드를 선언하고 있으며 AbstractController 클래스를 상속받는 컨트롤러 클래스는 이 메소드를 구현해야 한다.


protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception  

ο MultiActionController

     1) 하나의 Controller에서 여러 개의 요청 처리 지원

         - 연관 된 request를 하나의 controller로 묶을 경우 사용

 

     2) 작성

        - MultiActionController 상속

       - client의 요청을 처리할 메소드 구현

    public[ModelAndView|Map|void] 메소드이름(HttpServletRequest req, HttpServletResponse res[HttpSession|Command])[throws Exception]{

  

    }

 

       - return type : ModelAndView, Map, void 중 하나

       - argument : 

        1번 - HttpServletRequest

        2번 - HttpServletResponse

        3번 - 선택적이며  HttpSession 또는 Command 또는 3번 HttpSession

        4번 - Command

 

    3) MethodNameResolver 등록

       - 역할 : 어떤 메소드가 클라이언트의 요청을 처리할 것인지 결정

       - Spring 설정파일에 <bean>으로 등록

       - controller에서는 property로 주입 받는다.

       - 종류 

         - parameterMethodNameResolver : parameter로 메소드 이름 전송

         - InternalPathMethodNameResolver : url 마지막 경로 메소드 이름으로 사용

         - PropertiesMethodNameResolver : URL과 메소드 이름 mapping을 property로 설정



'JSP > JspServlet' 카테고리의 다른 글

서버 도메인 확인  (0) 2013.08.16
None Annotation 스프링 MVC 예제 (abstract, multiaction)  (0) 2013.07.29
액션 태그와 커스텀 태그  (0) 2013.07.29
파입업로드/다운로드  (0) 2013.07.29
포워딩과 리다이렉트  (0) 2013.07.29
Posted by 1+1은?
2013. 7. 29. 15:21

액션 태그와 커스텀 태그


액션 태그

:  JSP  액션  태그는 클라이언트  혹은  서버에게  어떠한 동작을  행하도록  명령을  내리는  태그로 JSP  페

이지  안에서  자바  빈즈를  사용할  수  있도록  하는  액션  태그와  페이지를  활용할  수  있도록  하는  액션  

태그로 나눌 수  있다.



■  형식

 <jsp:액션태그 속성="값">태그에 들어  있는  내용</jsp:액션태그>

또는

<jsp:액션태그 속성="값" />

JSP  액션  태그는 JSP  태그  형식을  따르지  않고 XML형식을  따른다.  그러므로  시작  태그가

있으면 반드시 끝나는 태그가 있어야 한다. 그리고 액션 태그는 접두어 "jsp:"이  붙어서  "<jsp:"으로  시작해야 한다.


액션  태그에 속성  값만  지정하고  내용이  없을  경우에는, XML규칙에  의해  끝나는  태그를  따로

하지  않고 시작  태그의 마지막 부분을  "/>"으로  마무리 한다.



 //useBean : 객체생성
 //setProperty : 생성된 객체의 property 할당

//DemoVO vo = new DemoVO();
//int num1 = Integer.parseInt(request.getParameter("num1"));
//vo.setNum1(num1);

이름 : <%=vo.getName()%>
내용 : <%=vo.getContent()%>



<jsp:include page="포함시킬 문서 경로" /> //특정 문서를 현재 위치에 포함 시킨다.



커스텀 태그

: 개발자가 직접 개발. 중복되는 것들을 모듈화하며, 복잡한 소스를 간편화 시켜준다.

Posted by 1+1은?
2013. 7. 29. 15:19


test1.jsp
제목:
//req.getParameter(“subject”) = null 파일:
//form 객체에 enctype 속성을 주면 기존처럼 request객체의 getParameter로 받는것은 불가능하다. //해당 속성이 없으면 전송한 파일의 제목만 가져올뿐 파일의 내용은 알 수 없다. test1_ok.jsp out.print("request로 넘어온 데이터
"); DataInputStream dis = new DataInputStream(request.getInputStream()); String str; while((str=dis.readLine())!= null) { out.print(new String(str.getBytes("ISO-8859-1"), "euc-kr") + "
"); }//form에서 전송된 파일을 출력

test2.jsp
이름:
제목:
파일:
test2_ok.jsp <% String root = session.getServletContext().getRealPath("/");//서블릿에서 루트경로 구하기 → D:\web\work\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\study\ String pathname = root + File.separator + "saveFile"; File f = new File(pathname); if(! f.exists()) //폴더가 존재하지 않으면 폴더 작성 f.mkdirs(); String encType = "UTF-8"; int maxFilesize = 5*1024*1024; //MultipartRequest(request, 파일을 저장할 경로, 문자셋, 동일한 파일명 보호(덮어쓰기방지)) MultipartRequest mr = new MultipartRequest(request, pathname, maxFilesize, encType, new DefaultFileRenamePolicy()); //사실상 이부분에서 업로드가 완료됨 String name = mr.getParameter("name"); String subject = mr.getParameter("subject"); String saveFilename = mr.getFilesystemName("upload"); //서버에저장된파일명 String originalFilename = mr.getOriginalFileName("upload"); //클라이언트가업로드한파일명 long fileSize = mr.getFile("upload").length(); //File.length() 파일의 길이, return long %> 이름:<%=name %>
제목:<%=subject %>
클라이언트가업로드한파일명:<%=originalFilename %>
서버에저장된파일명:<%=saveFilename %>
파일의크기:<%=fileSize %>Bytes.


'JSP > JspServlet' 카테고리의 다른 글

MVC 관련 핸들러 매핑 및 컨트롤러  (0) 2013.07.29
액션 태그와 커스텀 태그  (0) 2013.07.29
포워딩과 리다이렉트  (0) 2013.07.29
JSP 페이지기본설정  (0) 2013.07.29
JSTL  (0) 2013.07.29
Posted by 1+1은?
2013. 7. 29. 15:17

포워딩과  리다이렉트  


Forwarding, 포워딩

: 요청을  포워딩할  때  해당  요청은  서버의  다른  자원(서블릿  또는  JSP)  에  전달된다.  이때에는  다른  

자원에서  이  요청을  처리할  것을  클라이언트에  알리지  않는다.  이런  방식의 처리는  웹  컨테이너  안에

서만  일어나고,  클라이언트는  알 수  없게 된다. 포워딩은  리다이렉트와는  다르게 객체를  요청에  담고,  

해당 요청을  사용할  다음 자원에  전송한다.


 따라서 클라이언트는  포워딩이  발생한 사실을  알지  못한다.  포워딩은  클라이언트와  통신  없이  서버

에서만 처리되기  때문에 리다이렉트보다 나은 성능을 보여준다.



 ο 포워딩 (Forwarding) 요청을 포워딩할 때 해당 요청은 서버의 다른 자원(서블릿 또는 JSP) 에 전달된다. 이때에는 다른 자원에서 이 요청을 처리할 것을 클라이언트에 알리지 않는다. 이런 방식의 처리는 웹 컨테이너 안에서만 일어나고, 클라이언트는 알 수 없게 된다. 포워딩은 리다이렉트와는 다르게 객체를 요청에 담고, 해당 요청을 사용할 다음 자원에 전송한다. 따라서 클라이언트는 포워딩이 발생한 사실을 알지 못한다. 포워딩은 클라이언트와 통신 없이 서버에서만 처리되기 때문에 리다이렉트보다 나은 성능을 보여준다. request 객체와 response 객체는 포워딩된 서블릿(jsp)로 전달된다. - jsp 포워딩 


 - servlet 포워딩 
RequestDispatcher rd = request.getRequestDispatcher("/view/bbs/list.jsp"); rd.forward(request, response); 
- 포워딩될 jsp 또는 서블릿에 정보를 전달하는 방법 
request.setAttribute("name", "홍길동"); BoardDTO d=dao.getReadData(num); 
// 객체인 경우 request.setAttribute("dto", d); - 포워딩된 페이지에서 포워딩한 페이지가 전달(setAttribute)한 값 받는 방법 <%String name=(String)request.getAttribute("name"); BoardDTO d=(BoardDTO)request.getAttribute("dto"); %> <%=name%><%=d.getName()%>
 - 포워딩된 페이지(jsp)에서 포워딩한 페이지가 전달(setAttribute)한 값 받는 방법(EL)
 ${name} ${dto.name}   


test1_ok.jsp


//request 객체에 attribute를 저장
request.setAttribute("result", msg); //(String, Object) %>

안보이는 text
//전송되지 않는 소스

test1_for.jsp


 //포워딩 된 jsp 또는 servlet은 request와 response객체가 그대로 전달됨
 String name = request.getParameter("name"); //파라미터 받기 
 String msg = (String)request.getAttribute("result"); //설정한 Attribute값 가져오기
%>


<%=name %>님
<%=msg %>
//정상출력


 


 

Redirect, 리다이렉트

: 클라이언트의 요청을  처리 한 후, 컨테이너는 sendRedirect()  메소드가 호출되면 브라우저에  응답을 보낸다.  이 응답에는  브라우저가  웹  컨테이너의  응답을  받은 후  다시 요청을  보낼  새로운  URL  을 포함한다.  여기에서  하나의  요청이  종결된다.  새로  부여받은  URL  로  브라우저에서  완전히  새롭게 요청하기  때문에 이전의 요청 스코프에  저장되어  있는 객체는 새로운 요청  전에 소멸된다.


리다이렉트는 추가적으로  발생한 왕복  처리  때문에  포워딩보다  느리다.  기억해야  할  것은  최종적으

로  수행하는  작업은  새로운  요청에  의한  것이고,  이것을 클라이언트가  알고  있기  때문에 브라우저  창

의  주소가  처음  요청한  주소가  아니고  최종  주소  값으로  변한다.  또한  하나의  요청에  담겨있던  객체



ο 리다이렉트 (Redirect)

클라이언트의 요청을 처리 한 후, 컨테이너는 sendRedirect() 메소드가 호출되면 브라우저에 응답을  보낸다. 이 응답에는 브라우저가 웹 컨테이너의 응답을 받은 후 다시 요청을 보낼 새로운 URL 을 포함한다. 여기에서 하나의 요청이 종결된다. 새로 부여받은 URL 로 브라우저에서 완전히 새롭게 요청하기 때문에 이전의 요청 스코프에 저장되어 있는 객체는 새로운 요청 전에 소멸된다. 리다이렉트는 추가적으로 발생한 왕복 처리 때문에 포워딩보다 느리다. 기억해야 할 것은 최종적으로 수행하는 작업은 새로운 요청에 의한 것이고, 이것을 클라이언트가 알고 있기 때문에 브라우저 창의 주소가 처음 요청한 주소가 아니고 최종 주소 값으로 변한다. 또한 하나의 요청에 담겨있던 객체들은 소멸되어 다음 작업까지 전달되지 않는다.

 request 객체와 response 객체가 초기화 된다.


 - jsp 리다이렉트
   <%
        String cp=response.getContextPath();
    response.sendRedirect(cp+"/bbs/list.kh"); 
   %>


 - servlet 리다이렉트
   String cp=response.getContextPath();
   response.sendRedirect(cp+"/bbs/list.kh"); 



test2_ok.jsp

//request 객체에 attribute를 저장
request.setAttribute("result", msg); //(String, Object) %>

안보이는 text
//전송되지 않는 소스 <% //리다이렉트(클라이언트가 다시 요청하도록 함) //일반적으로 DB에 INSERT, UPDATE, DELETE하거나 loing, logout 후에 리다이렉트를 한다. response.sendRedirect("test2_rs.jsp");

test2_rs.jsp

 String name = request.getParameter("name");
 String msg = (String)request.getAttribute("result");
%>


리다이렉트 된 페이지
request, response는 초기화 된다.
이름 : <%=name %>
<%=msg %>




'JSP > JspServlet' 카테고리의 다른 글

액션 태그와 커스텀 태그  (0) 2013.07.29
파입업로드/다운로드  (0) 2013.07.29
JSP 페이지기본설정  (0) 2013.07.29
JSTL  (0) 2013.07.29
Servlet  (0) 2013.07.29
Posted by 1+1은?
2013. 7. 29. 14:58


<%@ page contentType="text/html; //contentType = 생성할 문서 타입. 기본 값 : "text/html"
 charset=UTF-8" %>

<%@ page trimDirectiveWhitespaces="true" %>
//JSP 2.1 버전에서는 page 디렉티브에 새롭게 추가된 속성으로
불필요하게 생성되는 줄 바꿈 공백 문자를 제거 할 수 있다. 기본 값 : "false"

<% String cp = request.getContextPath();  // ContextPath(문맥경로) : ex) .../study
 request.setCharacterEncoding("utf-8");
// 페이지 자체의 캐릭터 인코딩 지정. 기본 값 : "ISO-8859-1" %>


'JSP > JspServlet' 카테고리의 다른 글

파입업로드/다운로드  (0) 2013.07.29
포워딩과 리다이렉트  (0) 2013.07.29
JSTL  (0) 2013.07.29
Servlet  (0) 2013.07.29
Servlet list 작성  (0) 2013.07.29
Posted by 1+1은?
2013. 7. 29. 14:55

JSTL, JSP  Standard  Tag  Library

: JSP에는  XML처럼 사용자가 태그를 정의해서 사용하는 것이 가능하며 이런 사용자 정의 태그를 커

스텀  태그라고  하는데  이들  중  자주  사용하는  것을  표준으로  만들어  놓은  것이  JSTL  이다.  JSP

Standard  Tag  Library(JSTL)는 일반적인 웹 애플리케이션 기능인 반복(iteration)과 조건, 데이터 관리

포맷,  XML 조작, 데이터베이스 액세스를 구현하는 커스텀 태그 라이브러리 모음이다.


 JSP의 스크립트와 HTML 코드를 같이 혼용하여 사용하면 개발의 편리성을 제공하기 하지만, 코드의

복잡성을  증대시키는  문제점이  있다.  이러한  문제를  해결하기  위해  로직  부분의  JSP  코드를  태그로

대치시켜서 HTML과 같은 태그로 이루어진 코딩 방법이 제시되었다.


 JSTL은  JSP  페이지의  로직을 담당하는  부분인  if,  for,  while,  데이터베이스 처리등과  관련된  표준

커스텀 태그를 제공함으로써 코드를 깔끔하게 하고 가독성을 좋게 하며 데이터 포맷, 반복 콘텐트 또

는 조건 콘텐트 같은 전형적인 표현 레이어를 위한 표준 구현을 제공하기 때문에,  JSP 작성자들이 애

플리케이션 개발에 집중하는데 도움이 된다.


 JSTL 작성 시 한 가지 주의할 사항은 액션 태그도 그렇지만  JSTL과 커스텀 태그도  XML 기반에서

작성이 되었기 때문에 모든 태그는 시작 태그와 종료 태그의 쌍으로 이루어져야 한다.


기존의 컨텍스트에서  JSTL을 사용하기 위해서는 웹 어플리케이션의  WEB-INF/lib 디렉토리에 필요

한 라이브러리를 복사하면 된다.  JSTL의 주된 라이브러리 파일은  jstl.jar,  standard.jar 이고,  xml에서

지원되는 기능을 사용하기 위해서  jaxen-full.jar,  saxpath.jar,  jaxp-api.jar 파일 등이 필요하다. 이 파

일들을 웹 어플리케이션의 WEB-INF/lib 에 복사하고, 컨텍스트를 리 로드 한다.



태그의 종류

1. 코어

⋅기능  : 변수지원, 흐름제어, URL처리

⋅접두어(Prefix)  :  c

⋅directive : <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


■ 표현 언어(EL) 지원 기능

 <c:catch>,  <c:out>,  <c:remove>,  <c:set>

■ 흐름 제어 기능

 <c:choose>(<c:when>,  <c:otherwise>),  <c:forEach>,  <c:forTokens>,  <c:if>

■ URL 관리 기능

 <c:import>(<c:param>),  <c:redirect>  (<c:param>),  <c:url>  (<c:param>)


조건문, if

수:
//액션이 없어서 자기 자신에게 parameter를 전송하는 폼 ${param.num}은 짝수
${param.num}은 홀수
등록된게시물이음슴 ${pageIndexList}


조건문, if~when


 
  ${param.num1 }은 3과 4의 배수
${param.num1 }은 3의 배수
${param.num1 }은 4의 배수
${param.num1 }은 3또는 4의 배수가 아님


반복문, forEach



 ${param.num}*${n}=${param.num*n}
이름:${dto.name}, 제목:${dto.subject}
이름:${dto.name}, 제목:${dto.subject}
현재아이템:${s.current}
0부터의순서:${s.index}
1부터의순서:${s.count}
처음이냐?:${s.first}
마지막이냐?:${s.last}
${dto.num}
${dto.subject}
${dto.name}
${dto.created}
${dto.hitCount}





ㅎㅎㅎ


구글?


여긴어디게


'JSP > JspServlet' 카테고리의 다른 글

포워딩과 리다이렉트  (0) 2013.07.29
JSP 페이지기본설정  (0) 2013.07.29
Servlet  (0) 2013.07.29
Servlet list 작성  (0) 2013.07.29
JSP 개요  (0) 2013.07.29
Posted by 1+1은?
2013. 7. 29. 14:23

Servlet

: 서블릿은 Sun 사에서 내놓은 기술로서 Java 라는 언어를 기반으로 하여 동적인 컨텐츠를 생성하며Java 코드 안에 HTML 태그가 혼재되어 있어서 그 효율성이 떨어진다.


서블릿은 멀티쓰레딩에 의해 사용자 요구를 처리하고 가공해서 이에 대한 결과를 보내며, 서블릿과 JSP 는 상호 연계되어 JSP에서 정적인 부분을 담당하고 서블릿 에서는 동적인 처리를 위한 부분으로

사용 되어 보다 효율적인 웹 사이트를 구성 할 수 있다. 즉, JSP 는 주로 사용자용 뷰(View) 의 구현에 사용되고 서블릿은 사용자용 뷰와 프로그램 로직사이를 제어해주는 역할에 주로 사용 되어 진다.


서블릿은 Servlet 인터페이스를 구현하여 GenericServlet을 만들고 이를 다시 http 프로토콜에 맞게확장한 HttpServlet 클래스를 상속한 후 내부 메소드를 재정의 하여 사용한다. 그리고 HttpServlet 클래스는 상속한 후 재정의해서 사용할 수 있는 주요 멤버 메소드인 service(), doGet(), doPost(),doHead() 메소드를 가지고 있다.


■ 서블릿의 동작 순서

1) 클라이언트의 요청

2) 서블릿 Handler  8080포트에서 요청 받음

3) 서블릿 컨테이너에서 해당 서블릿 검색

4) 해당 서블릿이 데이터베이스 작업을 해야 한다면 DB연결,

5) 모든 작업이 완료 되었다면 응답으로 결과를 리턴 한다.



 ■ 서블릿 작성 방법

ο 서블릿 클래스 작성

    1. 다음의 한가지 방법을 이용하여 서블릿 클래스를 작성 한다.

       1) 첫번째 방법

     GenericServlet abstract 클래스를 상속 받는 서블릿 클래스를 작성하여

     abstract void service(ServletRequest req, ServletResponse res) 메소드를 재정의 한다.

       2) 두번째 방법

            HttpServlet 클래스를 상속 받는 서블릿 클래스를 작성하여 다음의 메소드를 재정의 한다.

      - GET 방식을 처리하는 경우

              void doGet(HttpServletRequest req, HttpServletResponse resp)

      - POST 방식을 처리 하는 경우

               void doPost(HttpServletRequest req, HttpServletResponse resp)


ο WEB-INF/web.xml 파일에서 환경 설정

 : 디플로이먼트 디스크립터(deployment descriptor, 배포 설명자) 파일

     <servlet> 과 <servlet-mapping> 태그를 이용하여 서블릿을 uri와 매핑 한다.

 
          서블릿이름
          패키지명을 포한한 서블릿 클래스 파일명
      

      
          서블릿이름
         경로패턴
     

.../.../WebContent/WEB-INF/web.xml: 톰캣의 동작을 정의하는 환경설정 파일





study
 
   index.html
   index.htm
   index.jsp
   default.html
   default.htm
   default.jsp
 


fServlet
com.svt.FirstServlet
 //톰캣이 생성한 객체의 service()를 호출한다.

 //언제?
fServlet
/first // url 패턴을 찾을 때

//service() 메서드는 GenericServlet 클래스에 존재하며 HttpServlet클래스는 이 GenericServlet 클래스를 상속한다. 따라서 HttpServlet클래스를 상속받은 클래스는 service() 메서드를 갖게 된다.


//service() 메서드는 같은 클래스의 doGet() 또는 doPost()를 실행하도록 정의되어 있다.

만약 전송방식(request객체의 getMethod())을 알 수 없다면 doGet()을 호출한다.


 

URI-pattern 유형

1) 이그잭틀리 매칭(Exactly matching)  : 반드시  "/"로 시작해야 한다.

  예)   /User/abc

2) 디렉토리 매칭(Directory matching)  : 반드시  "/"로 시작하고,  "*"로 끝나야 한다.

  예)  /User/* →  *  : 모두

3)  Extension matching  :  "/"로 시작하면 안 되고, 확장자로 끝나야 한다.

  예)  *.do





■  디플로이먼트 디스크립터(deployment descriptor,  배포 설명자)  이점

 ⋅이미  테스트된 소스 코드에  대한 수정을 최소화  한다.

 ⋅소스  코드  없이 애플리케이션을 목적에  맞게 수정할  수  있다. 

 ⋅코드  변경이나 컴파일을  하지  않고도 서버  자원(DB 등등)을  바꿀 수  있다.

 ⋅접근  제어 목록, 보안  역할과 같은 보안에  관련된  업무도 관리할  수  있다.

 ⋅xml  파일로 되어  있으므로 프로그래머가  아닌 사람도 설정할  수  있다.

■ web.xml  파일의  태그

 ⋅icon  : 웹  애플리케이션을  나타내기 위해  IDE나 GUI  툴에서  사용 되는  하나  또는  두  개의  이미지  

   파일들의 위치를  지정하는데  사용한다.

 ⋅display-name  : GUI  툴이 웹  애플리케이션을 표시하기 위해  사용하는  이름을 지정 하는데 사용

 ⋅description  : 웹  어플리케이션에  대한 설명을  나타낸다.

 ⋅distributable  : distributable  요소가  있다는 것은 웹  어플리케이션이다 중  서버  간에  분산  배치 될 수  있다는 것을 

   의미한다.

 ⋅context-param  :  어플리케이션의 초기화 파라미터를 선언하는데  사용

 ⋅filter  : 서블릿이나 jsp  페이지로 들어오는 요청정보를  사전에 걸러내는 기능

 ⋅filter-mapping  : 필터를  지정했다면 filter-mapping을  지정하여 하나  이상의 서블릿과  연결함

 ⋅listener  :  서블릿2.3  버전으로부터  세션이나  서블릿  컨텍스트가  생성  또는  수정  되거나  소멸되는 것을  알려주는 

  이벤트  리스너

 ⋅servlet  : 서블릿이나 jsp  페이지에  초기화파라미터나사용자url  들을  할당  할  때 사용되는  서블릿이나 jsp  이름을 지정

 ⋅servlet-mapping  : 상대 url  경로를 좀  더 쉽게  다루기 위해  기본 url를  변경 할  때 사용

 ⋅session-config  :  일정  시간  동안  세션으로  접근이  없을  경우  서버는  메모리를  절약하기  위해  사용  하지  않는  

  메모리를 삭제한다. 세션의  시간 유지  기능

 ⋅mime-mapping  : 특정한 mime형을 가진 파일을 웹  어플리케이션에  넣어 두고 싶은  경우 사용

 ⋅welcome-file-list  :  url이  파일명이  아닌  디렉토리  명으로  받았을  경우  기본적으로  불러올 파일명을 지정하는데 사용

 ⋅error-page  : http  상태코드가  반환되거나 예외가  발생했을 때 그  내용을 출력하는 페이지

 ⋅tag-lib  :  태그라이브러리 설명자  파일의  별칭을 지정하는데  사용

 ⋅resource-envref  : 자원(resource)과  연관  되어  관리  되는  객체를  선언하는  역할을 한다.

 ⋅resource-ref  : resource-ref 요소는 외부에서  참조해야 할  자원을 선언할  때 사용

 ⋅security-constraint  :  url이  보호  되도록  지정하는  역할을  한다.  login-config와  연결되어 사용

 ⋅login-config  : 보안된 페이지로 들어가려는  사용자에  대한 서버의  인증  방식을 지정해 준다.

 ⋅security-role  : 통합개발 환경에서  보안  정보를 좀  더 조작하기 쉽게  만들어준다.

 ⋅env-entry  : 웹  어플리케이션의 환경  항목을 선언한다.

 ⋅ejb-ref  :  엔터프리이즈  빈의 홈에  대한  레퍼런스를 선언

 ⋅ejb-local-ref  :  엔터프라이즈  빈의 로컬  홈에  대한 레퍼런스를 선언


* ServletRequest : 클라이언트의 요청을 받음

* ServletResponse : 클라이언트의 요청에 응답

위 클래스는 인터페이스로 자바에서 객체를 직접 생성할 순 없다.(톰캣이 처리함)



1. GenericServlet 을 상속받는 경우


public class FirstServlet extends GenericServlet { private static final long serialVersionUID = 1L; @Override public void service(ServletRequest req, ServletResponse resp)throws ServletException, IOException { //service() 메소드 : 클라이언트가 요청할 때마다 호출되는 메소드 Calendar now = Calendar.getInstance(); String str = String.format("%1$tF %1$tT", now); //서버에서 클라이언트에게 전송하는 문서타입 설정 resp.setContentType("text/html;charset=utf-8"); //서버에서 클라이언트로 전송하기 위한 출력 스트림 PrintWriter out = resp.getWriter(); //서버에서 클라이언트로 데이터 전송 out.println(""); out.println(""); out.println("처음 작성해 보는 서블릿 프로그램
"); out.println("현재 날짜 및 시간 : " + str); out.println(""); out.println(""); } }


public class DemoServlet extends GenericServlet {
 private static final long serialVersionUID = 1L;
 
 @Override
 public void destroy() {
  // 서블릿이 메모리에서 해제되기 직전에 한 번만 실행
 }

 @Override
 public void init(ServletConfig config) throws ServletException {
  // 서블릿이 메모리에 로딩됨과 동시에 한 번만 실행. 초기화 목적으로 사용
 }
 
 /*
  * service() 메서드
  *   클라이언트가 호출할 때 마다 실행되어지는 메서드
  *   ServletRequest: 클라이언트의 요청을 전달 받기 위한 클래스
  *     클라이언트 -> 서버
  *   ServletResponse: 클라이언트에게 응답하기 위한 클래스
  *     서버 -> 클라이언트

 @Override 
public void service(ServletRequest req, ServletResponse resp)
   throws ServletException, IOException
{
 // 클라이언트에서 서버로 전송되는 인코딩 설정
 req.setCharacterEncoding("utf-8");
  
 // 클라이언트에서 전송된 데이터 받기
 String name = req.getParameter("name");
 int age = Integer.parseInt(req.getParameter("age"));
 String msg = name + "님";
 if (age >= 19)
  msg += "의 나이는 " + age + "세이고 성인입니다.";
 else
  msg += "의 나이는 " + age + "세이고 미성년자입니다.";
 
 // 서버에서 클라이언트로 전솓되는 문자 타입
 resp.setContentType("text/html; charset=utf-8");
 
 // 서버에서 클라이언트로 전송하기 위한 출력 스트림
 PrintWriter out = resp.getWriter();
 
 // 전송하기
 out.println("");
 out.println(msg);
 out.println("");
}

2. HttpServlet 을 상속받는 경우


public class BoardServlet extends HttpServlet
{
 private static final long serialVersionUID = 1L;

//service()는 클라이언트의 요청 시 전송방식에 따라
//doGet()이나 doPost() 메서드를 실행하도록 프로그램 되어 있다.
//전송방식을 알 수 없으면 get이라 간주한다.

 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
 {
  process(req, resp);
 }

 @Override
 protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
 {
  process(req, resp);
 }
 
 protected void forward(HttpServletRequest req, HttpServletResponse resp, String path)
throws ServletException, IOException
 {
  //서블릿의 포워딩 방식
  RequestDispatcher rd = req.getRequestDispatcher(path);
  rd.forward(req, resp);
 }
 
 protected void process(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
 {
  req.setCharacterEncoding("utf-8");
  
  String cp = req.getContextPath();
  String uri = req.getRequestURI(); //클라이언트가 요청한 URI


  BoardDAO dao = new BoardDAO();
  MyUtil util = new MyUtil();
  
  if(uri.indexOf("list.kh") != -1) //URI에 따른 응답을 달리한다.
  {
   //게시물 리스트
   forward(req, resp, "/sbbsView/list.jsp");
  } else if(uri.indexOf("created.kh") != -1)

  {
   //글쓰기 폼
   forward(req, resp, "/sbbsView/created.jsp");
  } else if(uri.indexOf("created_ok.kh") != -1)
                  //request의 uri가 "created_ok.kh"를 포함하면
  {
   BoardDTO dto = new BoardDTO();
   dto.setSubject(req.getParameter("subject"));
   dto.setName(req.getParameter("name"));
   dto.setContent(req.getParameter("content"));
   dto.setPwd(req.getParameter("pwd"));
   
   dto.setIpAddr(req.getRemoteAddr());
   
   dao.insertBoard(dto);
   
   resp.sendRedirect(cp + "/sbbs/list.kh");
  }
 }
}


'JSP > JspServlet' 카테고리의 다른 글

JSP 페이지기본설정  (0) 2013.07.29
JSTL  (0) 2013.07.29
Servlet list 작성  (0) 2013.07.29
JSP 개요  (0) 2013.07.29
연산자 검색  (0) 2013.07.29
Posted by 1+1은?
2013. 7. 29. 14:14

Servlet

글리스트

  URI : cp/sbbs/list.kh

  JSP : sbbsView/list.jsp

글쓰기폼

  URI : cp/sbbs/created.kh

  JSP : sbbsView/created.jsp

글저장

  URI : cp/sbbs/created_ok.kh --> 리스트로 리다이렉트

글보기

  URI : cp/sbbs/article.kh

  JSP : sbbsView/article.jsp

글수정폼

  URI : cp/sbbs/update.kh

  JSP : sbbsView/created.jsp

글수정완료

  URI : cp/sbbs/update_ok.kh --> 리스트로 리다이렉트

글삭제

  URI : cp/sbbs/delete.kh --> 리스트로 리다이렉트



* 서블릿 기본 코드


package com.bbs; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class BoardServlet extends HttpServlet{ private static final long serialVersionUID = 1L; // 추상클래스 제네릭서블릿을 받아서 재정의해야됨 // HttpServlet 을 상속받아서 사용 -> doGet, doPost만 재정의 // 서비스에서 get,post 방식 으로 부를때 super 로 보내면 안됨 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 서비스에서 get 방식으로 부를때.. process(req, resp); }// @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 서비스에서 post 방식으로 부를때.. process(req, resp); }// protected void forward(HttpServletRequest req, HttpServletResponse resp, String path) throws ServletException, IOException { // 서블릿에서 포워딩(path로 포워딩). // 포워딩에서의 /는 cp 까지를 의미한다. RequestDispatcher rd = req.getRequestDispatcher(path); rd.forward(req, resp); }// protected void process(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); String cp=req.getContextPath(); String uri=req.getRequestURI(); BoardDAO dao = new BoardDAO(); MyUtil util = new MyUtil(); // url = 전체주소 // uri = cp(context path : 문맥경로)부터시작되는 주소 // 디자인만 jsp로 위임 if (uri.indexOf("list.kh")!=-1){ // 게시물 리스트 String pageNum=req.getParameter("pageNum"); int current_page=1; if(pageNum!=null) current_page=Integer.parseInt(pageNum); // 검색키,값 String searchKey = req.getParameter("searchKey"); String searchValue = req.getParameter("searchValue"); if(searchKey==null) { searchKey="subject"; searchValue=""; } // GET 방식인 경우 디코딩 if(req.getMethod().equalsIgnoreCase("GET")) { searchValue=URLDecoder.decode(searchValue, "UTF-8"); } int numPerPage=10; int total_page=0; int dataCount=0; if(searchValue.length()==0) // 검색이 아닌 경우 데이터개수 dataCount=dao.totalnum(searchKey, searchValue); else // 검색인 경우 dataCount=dao.totalnum(searchKey, searchValue); total_page=util.getpageCount(numPerPage, dataCount); if(current_page>total_page) current_page=total_page; int start=(current_page-1)*numPerPage+1; int end=current_page*numPerPage; List

lists=dao.selectBoard(start, end, searchKey, searchValue);//1 List lists=null; if(searchValue.length()==0) // 검색이아닌경우글리스트 lists=dao.selectBoard(start, end, searchKey, searchValue); else // 검색인경우길리스트 lists=dao.selectBoard(start, end, searchKey, searchValue); String listUrl; String articleUrl; String params=""; if(searchValue.length()!=0) { params="searchKey="+searchKey+"&searchValue="+ URLEncoder.encode(searchValue, "UTF-8"); // 인코딩 } if(params.length()==0) { listUrl=cp+"/sbbs/list.kh"; articleUrl=cp+"/sbbs/article.kh"; } else { listUrl=cp+"/sbbs/list.kh?"+params; articleUrl=cp+"/sbbs/article.kh?"+params; } // 페이징 처리 String pageIndexList = util.pageIndexList(current_page, total_page, listUrl); // 포워딩하는 JSP 파일에 값을 전달하기 위해 req.setAttribute("lists", lists); req.setAttribute("pageIndexList", pageIndexList); req.setAttribute("pageNum", current_page); req.setAttribute("dataCount", dataCount); req.setAttribute("articleUrl", articleUrl); forward(req, resp, "/sbbsView/list.jsp"); } else if (uri.indexOf("created.kh")!=-1){ // 글쓰기폼 forward(req, resp, "/sbbsView/created.jsp"); } else if (uri.indexOf("created_ok.kh")!=-1){ //글저장 BoardDTO dto = new BoardDTO(); dto.setSubject(req.getParameter("subject")); dto.setName(req.getParameter("name")); dto.setContent(req.getParameter("content")); dto.setPwd(req.getParameter("pwd")); dto.setIpAddr(req.getRemoteAddr()); dao.insertBoard(dto); resp.sendRedirect(cp+"/sbbs/list.kh"); } else if (uri.indexOf("article.kh")!=-1){ BoardDTO dto = new BoardDTO(); int num = Integer.parseInt(req.getParameter("num")); String pageNum=req.getParameter("pageNum"); dto = dao.selectContent(num); req.setAttribute("dto", dto); int lineSu = dto.getContent().split("\n").length; String content = dto.getContent().replaceAll("\n", "
").replaceAll(" ", " "); req.setAttribute("pageNum", pageNum); req.setAttribute("lineSu", lineSu); req.setAttribute("content", content); forward(req, resp, "/sbbsView/article.jsp"); } }// }//



ο 포워딩 (Forwarding)

  요청을 포워딩할 때 해당 요청은 서버의 다른 자원(서블릿 또는 JSP) 에 전달된다. 이때에는 다른 자원에서 이 요청을 처리할 것을 클라이언트에 알리지 않는다. 이런 방식의 처리는 웹 컨테이너 안에서만 일어나고, 클라이언트는 알 수없게 된다. 포워딩은 리다이렉트와는 다르게 객체를 요청에 담고, 해당 요청을 사용할 다음 자원에 전송한다.

  따라서 클라이언트는 포워딩이 발생한 사실을 알지 못한다. 포워딩은 클라이언트와 통신 없이 서버에서만 처리되기 때문에 리다이렉트보다 나은 성능을 보여준다.

  request 객체와 response 객체는 포워딩된 서블릿(jsp)로 전달된다.


ο web.xml -> 추가


</welcome-file-list> -> 다음


 
   bbs
   com.bbs.BoardServlet
  
  
   bbs
   /sbbs/*
  


기본은 get방식

form 일때만 post방식

bbs : 서버가 켜질때 객체가 생성됨

com.bbs.BoardServlet 톰캣이 BoardServlet안의 service를 불러옴

url-pattern : 어떤주소를 입력할때..

'JSP > JspServlet' 카테고리의 다른 글

JSTL  (0) 2013.07.29
Servlet  (0) 2013.07.29
JSP 개요  (0) 2013.07.29
연산자 검색  (0) 2013.07.29
달력  (0) 2013.07.29
Posted by 1+1은?