'Program Language/Frmaework'에 해당되는 글 5건

  1. 2009.12.21 Spring Form Data Parameter 넘기기
  2. 2009.12.21 map Injection을 이용한 다운로더
  3. 2009.12.21 Limiting upload file size - Spring 3
  4. 2009.12.21 jstl
  5. 2009.12.21 Automatically Wiring Your Beans

 

SimpleFormController는 앞서 살펴본 AbstractCommandController를 상속해서 구현된 Controller로서...

GET 방식으로 요청이 들어올 경우 formView 프로퍼티에 지정된 뷰를 보여주고..

POST 방식으로 요청이 들어오게 되면 폼으로 넘어온 데이터를 처리한 후 successView 프로퍼티에 지정된 뷰를 보여준다...

물론 폼으로 넘어온 데이터는 commandClass 프로퍼티에 설정된 커맨드 객체에 저장된다..

보통 로그인 페이지를 작성한다고 하면 입력 화면을 처리하는 컨트롤러와 로그인을 처리하는 컨트롤러가 필요하지만..

Spring에서는 이거 하나만 가지고도 2가지 역할을 모두 할 수 있다...

SimpleFormController의 처리 흐름은 다음과 같다...

 

GET 방식인 경우

1. formBackingObject() 메소드 호출

2. showForm() 메소드 호출

 

POST 방식인 경우

1. formBackingObject() 메소드 호출

2. 입력된 폼 검증

    3-1. 검증이 실패할 경우 showForm() 메소드 호출

    3-2. 검증이 성공할 경우 onSubmit() 메소드 호출

 

그렇다면 직접 SimpleFormController를 구현해보도록 하자..

 

public class LoginController extends SimpleFormController
{
    @Override
    protected ModelAndView onSubmit(HttpServletRequest req, HttpServletResponse res,

                                                       Object command, BindException errors) throws Exception
    {
        LoginCommand login = (LoginCommand)command;
  
        if(login.getId().equals("id") && login.getPswd().equals("pswd"))
        {
            ModelAndView mav = new ModelAndView();
            mav.setViewName(getSuccessView());
            mav.addAllObjects(errors.getModel());
   
            return mav;
        }
        else
            return showForm(req, res, errors);
        }

}

 

위와 같이 onSubmit() 메소드를 재정의해주면 된다...

SimpleFormController가 AbstractCommandController를 상속받기 때문에 command를 매개변수로 갖는 것을 볼 수 있다...

아무튼 입력된 폼을 검증하는 코드를 수행한 후에는...

getSuccessView()를 호출하면 successView 프로퍼티에 지정된 뷰를 가져오게 된다...

만약 검증에 실패해서 showForm() 메소드를 실행해주면 formView 프로퍼티에 지정된 뷰를 보여주게 된다...

원한다면 검증 오류 페이지로 ModelAndView를 만들어도 될 것이다..

BindException 객체는 커맨드 객체 정보 및 요청 파라미터 값 검증 결과를 담고 있는데...

getModel() 메소드를 호출하면...

commandName 프로퍼티에 설정된 이름과 commandClass 프로퍼티에 설정된 커맨드 객체 쌍으로 된 Map 객체를 리턴한다...

따라서 View에서는 commandName에 지정된 이름을 통해 커맨드 객체에 접근할 수 있게 된다...

좀 더 자세한 내용은 다음에 알아보도록 하고...

커맨드 클래스는 아래와 같이 간단히 id와 패스워드를 갖도록 만들어 주면 된다...

 

public class LoginCommand
{
    private String id;
    private String pswd;
 
    public String getId()
    {
        return id;
    }
    public void setId(String id)
    {
        this.id = id;
    }
    public String getPswd()
    {
        return pswd;
    }
    public void setPswd(String pswd)
    {
        this.pswd = pswd;
    }
}

 

그 후 XML 다음과 같이 XML 설정을 해주면 된다...

 

<bean name="loginController" class="org.cuvic.web.LoginController">
     <property name="commandClass" value="org.cuvic.web.command.LoginCommand"/>
     <property name="commandName" value="login"/>
     <property name="formView" value="login"/>
     <property name="successView" value="result"/>
</bean>

 

commandClass와 commandName은 AbstractCommandController와 동일한 역할을 하고..

위에서 알아보았듯이 formView는 GET 방식일 때 보여줄 View이고..

successView는 POST 방식으로 넘어온 후 결과를 보여줄 View를 설정해주면 된다...

 

실제 로그인하는 페이지인 login.jsp를 간단하게 만들어 보자...

 

<html>
    <head>
        <title>로그인 테스트</title>
    </head>
    <body>
        <form method="post">
            <input type="text" name="id">
            <input type="password" name="pswd">
            <input type="submit">
        </form>
    </body>
</html>

 

그 후 결과를 보여줄 result.jsp 파일도 간단하게 만든다...

 

<html>
    <head>
        <title>로그인 성공</title>
    </head>
    <body>

        로그인 성공!!

    </body>
</html>

 

그냥 GET 방식으로 접속하면 login.jsp로 접속이 되고...

POST로 전송을 하면 문제가 없다면 result.jsp가 보이고 뭔가 문제가 있으면 바로 login.jsp 페이지가 보여진다...

 

로그인 페이지를 예로 했기 때문에 간단했지만..

회원 가입 폼이나 기타 다른 폼에서는 기본적으로 무언가 정해진 값을 선택해야 하는 경우가 있다..

예를 들어 직업이라던가 학교같은 것들을 콤보박스로 선택할 수 있게 해 놓은 경우라 할 수 있다..

이런 값들은 대개 DB에서 값을 읽어다가 출력하게 되는데...

이렇게 입력 폼에서 사용할 수 있는 값을 설정할 수 있도록 referenceData() 메소드가 제공된다..

이 메소드에서 입력 폼에서 사용할 값을 설정해서 ModelAndView로 전달할 수 있다...

 

@Override

protected Map referenceData(HttpServletRequest request) throws Exception

{

    List job = new ArrayList();

    job.add("학생");

    job.add("직장인");

    job.add("백수");

 

    Map data = new HashMap();

    data.put("job", job);

   

    return data;

}

 

위와 같이 해주면 job이라는 이름으로 입력 폼에서 값을 사용할 수가 있다...

그리고 회원 정보 수정이나 각종 정보 수정 시에는 수정할 정보가 이미 출력이 되어 있어야 하는데..

이럴 때 formBackingObject() 메소드를 사용한다...

이 메소드는 GET방식이던 POST방식이던 무조건 호출되서 커맨드 객체를 생성한다...

그 후 POST방식이면 요청 파라미터 값을 커맨드 객체에 반영하게 된다...

그러므로 폼에 미리 값을 출력해주려면 이 메소드를 재정의한다..

 

@Override

protected Object formBackingObject(HttpServletRequest request) throws Exception

{

    if(!isFormSubmission(request))

    {

        FooCommand foo = new FooCommand();

        foo = barDAO.getFoo();

 

        return foo;

    }

    else

    {

        return super.formBackingObject(request);

    }

}

 

isFormSubmission() 메소드는 POST 요청인지 판단하는 메소드이다..

! 연산자가 사용되어 POST가 아닌 경우..

즉 GET 요청인 경우 BarDAO에서 FooCommand 값을 가져오고 있는 것을 볼 수 있다..

그 외에 POST 요청인 경우에는 전달된 요청 파라미터를 그대로 처리하기 위해...

부모 클래스의 formBackingObject() 메소드를 호출하는 것을 볼 수 있다...

 

AbstractFormController에는 sessionForm 프로퍼티가 있는데..

기본 값은 false이지만 이 값을 true로 설정할 경우 아래와 같이 처리 과정이 약간 달라진다...

 

GET 방식인 경우

1. formBackingObject() 메소드 호출

2. showForm() 메소드 호출

3. HttpSession에 커맨드 객체 저장

 

POST 방식인 경우

1. HttpSession에 커맨드 객체가 있는지 확인

   2-1. 커맨드 객체가 없는 경우 GET 방식 호출

   2-2  커맨드 객체가 있는 경우 HttpSession에서 커맨드 객체 제거 후 입력 폼 검증

          3-1 검증이 실패할 경우 showForm() 메소드 호출

          3-2 검증이 성공할 경우 onSubmit() 메소드 호출

 

GET 요청이 있는 경우 커맨드 객체를 생성하여 HttpSession에 저장하게 된다..

그 후 POST 요청이 들어오면 HttpSession에서 저장된 커맨드 객체를 가져다 사용하게 된다...

왜 이렇게 사용하는지는 Spring 문서를 살펴보면..

 

Indicates whether the form object should be kept in the session when a user asks for a new form.

This allows you e.g. to retrieve an object from the database, let the user edit it, and then persist it again.

Otherwise, a new command object will be created for each request

(even when showing the form again after validation errors).

이 글은 스프링노트에서 작성되었습니다.

Posted by 이버리
,

아.. 진작에 이렇게 할것을...ㅜㅜ

 

downloadmanager-context.xml

  1.  
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <beans xmlns="http://www.springframework.org/schema/beans"
  4.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5.        xsi:schemaLocation="
  6.                 http://www.springframework.org/schema/beans
  7.                 http://www.springframework.org/schema/beans/spring-beans.xsd">

  8.     <bean id="ftpDownloader" class="com.apress.prospring2.ch03.dm.FtpDownloader"/>
  9.     <bean id="httpDownloader" class="com.apress.prospring2.ch03.dm.HttpDownloader"/>
  10.     <bean id="sftpDownaloader" class="com.apress.prospring2.ch03.dm.SftpDownloader"/>
  11.     <bean id="downloadManager" class="com.apress.prospring2.ch03.dm.DownloadManager">
  12.         <property name="downloaders">
  13.             <map>
  14.                 <entry key="ftp" value-ref="ftpDownloader"/>
  15.                 <entry key="http" value-ref="httpDownloader"/>
  16.                 <entry key="sftp" value-ref="sftpDownaloader"/>
  17.             </map>
  18.         </property>
  19.     </bean>


  20. </beans>

 

Test Class : DownloadManager.java

  1.  
  2. package com.apress.prospring2.ch03.dm;

  3. import org.springframework.beans.factory.xml.XmlBeanFactory;
  4. import org.springframework.core.io.ClassPathResource;

  5. import java.io.BufferedReader;
  6. import java.io.IOException;
  7. import java.io.InputStreamReader;
  8. import java.util.Map;
  9. import java.util.regex.Matcher;
  10. import java.util.regex.Pattern;

  11. /**
  12.  * @author janm
  13.  */
  14. public class DownloadManager {
  15. private static final Pattern URI_PATTERN = Pattern.compile("^([^:]*):/(.*)$");
  16. private Map<String, Downloader> downloaders;

  17. public static void main(String[] args) throws IOException {
  18. XmlBeanFactory xbf = new XmlBeanFactory(new ClassPathResource(
  19. "/META-INF/spring/downloadmanager-context.xml"));
  20. DownloadManager dm = (DownloadManager) xbf.getBean("downloadManager");
  21. BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
  22. while (true) {
  23. String uri = reader.readLine();
  24. if (uri.length() == 0)
  25. break;
  26. dm.download(uri);
  27. }
  28. }

  29. private void download(String uri) {
  30. Matcher matcher = URI_PATTERN.matcher(uri);
  31. if (matcher.matches()) {
  32. String scheme = matcher.group(1); //reg Exp 를 이용하여 1번그룹 추출(http, ftp, sftp)
  33. System.out.println(scheme);
  34. String path = matcher.group(2);
  35. Downloader downloader = this.downloaders.get(scheme); // downloaderManager bean의 Map에서 스키마를 꺼낸다
  36. if (downloader != null) {
  37. downloader.download(path);
  38. }
  39. }
  40. }
  41. public void setDownloaders(Map<String, Downloader> downloaders) {
  42. this.downloaders = downloaders;
  43. }
  44. }

 

Interface Downloader.java

  1.  
  2. package com.apress.prospring2.ch03.dm;
  3. public interface Downloader {
        byte[] download(final String uri);
  4. }

 

구현체 FtpDownloader.java , HttpDownloader.java , sFtpDownLoader.java

  1. package com.apress.prospring2.ch03.dm;
  2. import org.springframework.stereotype.Component;
  3. @Component
  4. public class FtpDownloader implements Downloader {
  5.     public byte[] download(String uri) {
  6.         System.out.println("FTP Downloading " + uri);
  7.         return new byte[0];
  8.     }
  9. }

이 글은 스프링노트에서 작성되었습니다.

Posted by 이버리
,

 

You might want to limit the size of file to be uploaded on your website as it eats up some of the bandwidth and this can cause problem to rest of the users of your site. Most of the time we do processing on files when they are uploaded on server and content validations has limitations on client side as you can not read files using javascript on client side (i.e. web browser). 

Limit on upload size makes more sense for specific purposes on your website when you know about expected size of file beforehand like image upload websites etc.

If you are using Spring framework for your project/product you can do this using latest version of commons-fileupload which lets you write your own ProgressListener using which you can limit file upload size and monitor the upload process as well. We are using Ajax in our project and for file upload we are using ajaxfileupload (see more in detail)

Following things need to be done for achieving the goal:

1. Implement the ProgressListener for your application like below by implementing org.apache.commons.fileupload.progresslistener

 
package com.listener;
 
import javax.servlet.http.HttpSession;
import net.sf.json.JSONObject;
import org.apache.commons.fileupload.ProgressListener;
 
public class AjaxProgressListener implements ProgressListener {
 
    public static final String STATUS_UPLOADING = "UPLOADING";
    public static final String STATUS_FAILED = "FAILED";
    public static final String STATUS_DONE = "DONE";
    public static final String STATUS_MAX_SIZE_EXCEEDS = "MAX_SIZE_EXCEEDS";
 
    private HttpSession session;
 
    public void setSession(HttpSession session){
        this.session = session;
    }
 
    public void updateStatus(String status){
        session.setAttribute("progressStatus", status);
    }
 
    public void update(long bytesRead, long contentLength, int item) {
        JSONObject progressMap = new JSONObject();
        progressMap.set("bytesRead", bytesRead);
        progressMap.set("contentLength", contentLength);
        progressMap.set("item", item);
        session.setAttribute("progressMap", progressMap);
 
        if(bytesRead == contentLength) {
                session.setAttribute("progressStatus", STATUS_DONE);
        }
    }
}
 

Progress Listener will read the status of file upload using http request and will set a parameter map in session object so that it can be used for monitoring.


2. Extend the CommonsMultipartResolver provided by Spring framework and use the ProgressListener implemented to check the size of upload.

 
package com.resolver;
 
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUpload;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
 
import com.listener.AjaxProgressListener;
 
 
public class AjaxMultipartResolver extends CommonsMultipartResolver {
    private AjaxProgressListener progressListener;
    private HttpServletRequest httpServletRequest;
 
    public void setProgressListener(AjaxProgressListener progressListener) {
        this.progressListener = progressListener;
    }
 
    public AjaxProgressListener getProgressListener() {
        return progressListener;
    }
 
    public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {
        try {
            this.httpServletRequest = request;
 
            return super.resolveMultipart(request);
        } catch(MaxUploadSizeExceededException ex) {
                 this.progressListener.updateStatus(AjaxProgressListener.STATUS_MAX_SIZE_EXCEEDS);
             throw new MultipartException(ex.getMessage());
        } catch (Exception ex) {
            //exception is typically thrown when user hits stop or cancel
            //button halfway through upload
            this.progressListener.updateStatus(AjaxProgressListener.STATUS_FAILED);
            throw new MultipartException(ex.getMessage());
        }
    }
}
 
 



3. Update your application-beans.xml for your custom MultipartResolver written in step 2 and re-start the server.

 
<bean id="multipartResolver" class="com.resolver.AjaxMultipartResolver">
        <property name="maxInMemorySize">
                <!-- Max in memory 10kbytes -->
                <value>10240</value>
        </property>
        <property name="maxUploadSize">
                <!--  10 MB Max upload size -->
                <value>1024000000</value>
        </property>
        <!--
        <property name="uploadTempDir">
                <value>/tmp</value>
        </property>
        -->
        <property name="progressListener">
                <ref bean="progressListener" />
        </property>
</bean>
 
<bean id="progressListener" class="com.listener.AjaxProgressListener"/>
 



These values will be used for checking the file upload size and will automatically be set in AjaxMultipartResolver at the time of server start. Change these values according to your need. 

 

 

 

  1. package com.mcw.sns.listener;

  2. import javax.servlet.http.HttpSession;

  3. import net.sf.json.JSONObject;

  4. import org.apache.commons.fileupload.ProgressListener;

  5. public class AjaxProgressListener implements ProgressListener {

  6. public static final String STATUS_UPLOADING = "UPLOADING";
  7. public static final String STATUS_FAILED = "FAILED";
  8. public static final String STATUS_DONE = "DONE";
  9. public static final String STATUS_MAX_SIZE_EXCEEDS = "MAX_SIZE_EXCEEDS";

  10. private HttpSession session;

  11. public void setSession(HttpSession session) {
  12. this.session = session;
  13. }

  14. public void updateStatus(String status) {
  15. session.setAttribute("progressStatus", status);
  16. }

  17. public void update(long bytesRead, long contentLength, int item) {
  18. JSONObject progressMap = new JSONObject();
  19. progressMap.put("bytesRead", bytesRead);
  20. progressMap.put("contentLength", contentLength);
  21. progressMap.put("item", item);
  22. session.setAttribute("progressMap", progressMap);

  23. if (bytesRead == contentLength) {
  24. session.setAttribute("progressStatus", STATUS_DONE);
  25. }
  26. }

  27. }

 

 

  1. package com.mcw.sns.resolver;

  2. import javax.servlet.http.HttpServletRequest;

  3. import org.springframework.web.multipart.MaxUploadSizeExceededException;
  4. import org.springframework.web.multipart.MultipartException;
  5. import org.springframework.web.multipart.MultipartHttpServletRequest;
  6. import org.springframework.web.multipart.commons.CommonsMultipartResolver;

  7. import com.mcw.sns.listener.AjaxProgressListener;
  8.  
  9. public class AjaxMultipartResolver extends CommonsMultipartResolver {
  10.     private AjaxProgressListener progressListener;
  11.     private HttpServletRequest httpServletRequest;
  12.  
  13.     public void setProgressListener(AjaxProgressListener progressListener) {
  14.         this.progressListener = progressListener;
  15.     }
  16.  
  17.     public AjaxProgressListener getProgressListener() {
  18.         return progressListener;
  19.     }
  20.  
  21.     public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {
  22.         try {
  23.             this.httpServletRequest = request;
  24.  
  25.             return super.resolveMultipart(request);
  26.         } catch(MaxUploadSizeExceededException ex) {
  27.          this.progressListener.updateStatus(AjaxProgressListener.STATUS_MAX_SIZE_EXCEEDS);
  28.              throw new MultipartException(ex.getMessage());
  29.         } catch (Exception ex) {
  30.             //exception is typically thrown when user hits stop or cancel
  31.             //button halfway through upload
  32.             this.progressListener.updateStatus(AjaxProgressListener.STATUS_FAILED);
  33.             throw new MultipartException(ex.getMessage());
  34.         }
  35.     }
  36. }

 

  1. <bean id="multipartResolver" class="com.mcw.sns.resolver.AjaxMultipartResolver">
  2. <property name="maxInMemorySize">
  3. <!-- Max in memory 10kbytes -->
  4. <value>10240</value>
  5. </property>
  6. <property name="maxUploadSize">
  7. <!--  10 MB Max upload size -->
  8. <value>1024000000</value>
  9. </property>
  10.         
  11.         <property name="uploadTempDir">
  12. <value>D:/Temp/</value>
  13. </property>
  14. <property name="progressListener">
  15. <ref bean="progressListener" />
  16. </property>
  17. </bean>
  18.  
  19. <bean id="progressListener" class="com.mcw.sns.listener.AjaxProgressListener"/>

 

 

 

이 글은 스프링노트에서 작성되었습니다.

Posted by 이버리
,

jstl

Program Language/Frmaework 2009. 12. 21. 15:26

 

개요

JSTL(JSP Standard Tag Library)설명한다.

목차

1. 개요.. 3

2. 설정.. 3<?xml:namespace prefix = o /><?xml:namespace prefix = o />

3. JSTL사용.. 4

4. Expression Language. 5

(1) Expression Language 개요.. 5

(2) Expression Language 기본객체.. 6

(3) 객체사용.. 6

(4) 연산자.. 9

5. core. 10

(1) c:out10

(2) c:set11

(3) c:remove. 11

(4) c:if11

(5) c:choose, c:when, c:otherwise. 12

(6) c:forEach. 12

(7) c:forTokens14

(8) c:url, c:param. 14

(9) c:import15

(10) c:redirect16

(11) c:catch. 16

6. 참고자료.. 16

 

1.
개요

JSTL(JSP Standard Tag Library)설명한다. 프레임워크에서는 JSTL구성하는 4개의태그라이브러리중에서 core 태그라이브러리만을사용한다.

종류

설명

prefix

uri

core

데이터출력, 제어문, URL 처리기본기능

c

http://java.sun.com/jstl/core (1.3)

http://java.sun.com/jsp/jstl/core (1.4)

format

I18N 데이터포멧기능

fmt

http://java.sun.com/jstl/fmt (1.3)

http://java.sun.com/jsp/jstl/fmt (1.4)

xml

XML 문서에대한처리

x

http://java.sun.com/jstl/xml (1.3)

http://java.sun.com/jsp/jstl/xml (1.4)

sql

JDBC 작업수행

sql

http://java.sun.com/jstl/sql (1.3)

http://java.sun.com/jsp/jstl/sql (1.4)


표 1.
JSTL 태그라이브러리

2.
설정

JSTL사용하려면아래파일이어플리케이션디렉토리에위치해야한다.

파일

설명

WEB-INF/lib/jstl.jar

JSTL API 라이브러리

WEB-INF/lib/standard.jar

JSTL 구현라이브러리

WEB-INF/tld/c.tld

JSTL core TLD 파일


표 2.
JSTL 설정을위한파일

J2EE 1.3에서는 JSTL 1.0 라이브러리를, J2EE 1.4에서는 JSTL 1.1 라이브러리를사용한다. 라이브러리는다음(http://jakarta.apache.org/taglibs/doc/standard-doc/intro.html)에서다운로드한다.

그리고 web.xml 파일에태그라이브러리를설정한다. 아래는 J2EE 1.3사용하는경우의설정이다.

 

web.xml

 

<taglib>

<taglib-uri>http://java.sun.com/jstl/core</taglib-uri>

<taglib-location>/WEB-INF/c.tld</taglib-location>

</taglib>

 

그리고아래는 J2EE 1.4사용하는경우의설정이다.

 

web.xml

 

<jsp-config>

<taglib>

<taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>

<taglib-location>/WEB-INF/c.tld</taglib-location>

</taglib>

</jsp-config>

 

3.
JSTL
사용

JSTL사용하는모든 JSP 파일상단에아래내용을추가한다.

 

Example.jsp

 

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>

 

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

 

그런데 J2EE 1.3 J2EE 1.4따라서 uri 속성의값이다르다. 이에따른수정영향을최소화하기위해서 BaseJsp.jsp 파일을사용한다.

 

Example.jsp

 

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>

 

<%@ include file="/BaseJsp.jsp" %>

 

BaseJsp.jsp내용은아래와같다. 프레임워크가제공하는태그라이브러리설정도포함한다.

 

BaseJsp.jsp

 

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

<%@ taglib prefix="framework" uri="http://www.naver.com/ctl/framework" %>

<%@ taglib prefix="ui" uri="http://www.naver.com/ctl/ui" %>

 

4.
Expression Language

(1)
Expression Language
개요

JSTL Expression Language(이하 EL)사용한다. EL데이터혹은객체를표현하는데사용하는스크립트언어로 ${} 안에서사용한다.

 

// 동적인표현작업수행

${Some Expression}

 

EL아래의작업을수행한다.

 
JSP 저장영역(page, request, session, application)대한접근

 
java.util.Collection, java.util.Map, 배열등의객체처리

 
POJO 유형의객체처리

 
수치, 비교, 논리연산자적용

 

J2EE 1.3에서는 EL JSTL 태그의속성값에서만사용할있다. 그러나 J2EE 1.4에서는 EL JSP JSTL 모두에서사용할있다.

(2)
Expression Language
기본객체

EL에서사용가능한주요 JSP API대한 Alias아래와같다.

종류

기본객체

예제

JSP

저장영역

pageScope - PageContext 속성

requestScope - HttpServletRequest 속성

sessionScope - HttpSession 속성

applicationScope - ServletContext 속성

${requestScope.name}

HTTP

요청

파라미터

param - HttpServletRequest 파라미터

paramValues - 동일파라미터이름에값이 2이상존재하는경우

${param.name}

JSP

객체

pageContext - PageContext

cookie - 이름을키로, Cookie값으로하는 java.util.Map

header - 해더이름을키로, 해더값을값으로하는 java.util.Map

headerValues - 동일해더이름에값이 2이상존재하는경우

initParam - JSP 초기변수

${cookie.JSESSIONID.name}

${headerValues['HOST'][0]}"


표 3.
EL 기본객체

(3)
객체
사용

기본데이터타입(Boolean, Integer, Long, String )아래처럼사용한다.

 

request.setAttribute("name", "성선임");

 

// 성선임을출력한다.

${requestScope.name}

 

// 성선임을출력한다. 영역을지정하지않으면 page, request, session, application

// 으로검색한다.

${name}

 

// null출력하지않고아무것도출력하지않는다.

${password}

 

<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><?xml:namespace prefix = st1 /><?xml:namespace prefix = st1 /><?xml:namespace prefix = st1 />POJO 객체의경우에는파라미터가없는 get으로시작하는메소드에서 get제외한나머지메소드이름의첫번째단어를소문자로해서사용한다.

 

Book.java

 

public class Book {

 

private String isbn;

 

public Book(String isbn) {

this.isbn = isbn;

 

public void getIsbn() {

return this.isbn;

}

 

public void setIsbn(String isbn) {

this.isbn = isbn;

}

 

public String toString() {

return "book-object";

}

 

}

 

 

Example.jsp

 

Book book = new Book("100");

request.setAttribute("favoriteBook", book);

 

// toString 메소드가반환하는값을출력한다. book-object출력한다.

${favoriteBook}

 

// . 연산자를사용해서 getIsbn 메소드가반환하는값을출력한다. 100출력한다.

${favoriteBook.isbn}

 

// [] 연산자를사용해도결과는동일하다.

${favoriteBook['isbn']}

 

// 값이없는경우에 NullPointerException발생하지않는다.

${nullBook.isbn}

 

// 해당하는메소드가없는경우에는예외가발생한다.

${book.title}

 

배열객체는아래처럼사용한다.

 

Book[] books = new Book[2];

 

books[0] = new Book("100");

books[1] = new Book("200");

 

request.setAttribute("books", books);

 

// 100출력한다.

${books[0].isbn}

 

// 200출력한다.

${books[1].isbn}

 

java.util.Map 객체는아래처럼사용한다. 키의유형은항상 java.lang.String이어야한다.

 

Map map = new HashMap();

map.put("one", new Integer(1));

map.put("sub.one", new Integer(2));

 

request.setAttribute("numbers", map);

 

// . [] 연산자를모두사용할있다. 1출력한다.

${number.one}

${number['one']}

 

// 키가 . 등의문자를포함하면 [] 연산자를사용한다. 2출력한다.

${number['sub.one']}

 

// java.util.Map키가존재하지않아도예외가발생하지않는다.

${number.two}

 

(4)
연산자

EL에서아래의수치연산자를사용할있다.

연산자

설명

예제

결과

+

더하기

${10 + 2}

12

-

빼기

${10 - 2}

8

*

곱하기

${10 * 2}

20

/ 또는 div

나누기

${10 / 2} 또는 ${10 div 2}

5

% 또는 mod

나머지

${10 % 3} 또는 ${10 mod 3}

1


표 4.
EL 수치연산자

숫자형이아니면숫자형으로자동전환을후에연산을수행한다.

 

// 101아닌 11출력한다.

${"10" + 1}

 

// null 0으로처리한다. 1출력한다.

${null + 1}

 

// 숫자가아니면예외가발생한다.

${"" + 10}

 

EL제공하는비교논리연산자는아래와같다. >, < XML 태그와혼동할우려가있는연산자는문자열연산자(gt, lt)표현하는것을권장한다.

연산자

예제

결과

== 또는 eq

${5 == 5} 또는 ${5 eq 5}

true

!= 또는 ne

${5 != 5} 또는 ${5 ne 5}

false

< 또는 lt

${5 < 7} 또는 ${5 lt 7}

true

> 또는 gt

${5 > 7} 또는 ${5 gt 7}

false

<= 또는 le

${5 <= 5} 또는 ${5 le 5}

true

>= 또는 ge

${5 >= 6} 또는 ${5 ge 6}

false

&& 또는 and

${true && false} 또는 ${true and false}

false

|| 또는 or

${true || false} 또는 ${true or false}

true

! 또는 not

${!true} 또는 ${not true}

false

empty

${empty name}

name null이거나문자열이면 true

not empty

${not empty name}

name null아니고문자열도아니면 true


표 5.
EL 비교논리연산자

5.
core

(1)
c:out

객체를화면에출력한다.

 

// out.println(request.getAttribute("name"));

<c:out value="${name}"/>

 

// 값이없는경우에기본값을출력하려면 default 속성을이용한다.

<c:out value="${age}" default="값이없습니다."/>

 

// 기본적으로 XML 문자를 escape한다. Escape 하지않으려면 escapeXml false한다.

<c:out value="${name}" escapeXml="false"/>

 

(2)
c:set

저장영역에객체를저장한다.

 

// request.setAttribute("name", "<?xml:namespace prefix = st2 ns = "urn:schemas:contacts" /><?xml:namespace prefix = st2 /><?xml:namespace prefix = st2 /><?xml:namespace prefix = st2 />태섭");

// scope 속성으로는 page(기본), request, session, application사용.

<c:set scope="request" var="name" value="송태섭"/>

 

// Book book = (Book) request.getAttribute("book");

// book.setIsbn("300");

<c:set scope="request" target="book" property="isbn" value="300"/>

 

(3)
c:remove

저장영역에서객체를삭제한다.

 

// request.removeAttribute("name");

<c:remove scope="request" var="name"/>

 

(4)
c:if

조건문을제어한다.

 

// test 속성의값이 true c:if 태그의 body 내용을수행한다.

<c:if test="${not empty flag}">

flag존재하면영역을수행한다.

</c:if>

 

(5)
c:choose, c:when, c:otherwise

복합조건문을제어한다.

 

// c:choose 태그는 1이상의 c:when 태그와 0 또는 1개의 c:otherwise 태그로구성

<c:choose>

<c:when test="${flag == 1}">

flag 1이면영역을수행한다.

</c:when>

<c:when test="${flag == 2}">

flag 2이면영역을수행한다.

</c:when>

<c:otherwise>

flag 1 2아니면영역을수행한다.

</c:otherwise>

</c:choose>

 

(6)
c:forEach

반복문을수행한다.

 

<%

for (int i = 0; i < 10; i++) {

out.println(i);

}

%>

 

// 0 1 2 3 4 5 6 7 8 9출력한다.

<c:forEach begin="0" end="9" var="i">

<c:out value="${i}"/>

</c:forEach>

 

step 속성으로간격을조정한다.

 

<%

for (int i = 0; i < 10; i += 2) {

out.println(i);

}

%>

 

// 0 2 4 6 8출력한다.

<c:forEach begin="0" end="9" step="2" var="i">

<c:out value="${i}"/>

</c:forEach>

 

java.util.Collection 객체나배열에대해서는아래처럼한다.

 

<%

Collection books = (Collection) request.getAttribute("books");

for (Iterator all = books.iterator(); all.hasNext();) {

Book each = (Book) all.next();

out.println(each.getIsbn());

}

%>

 

<c:forEach items="${books}" var="book">

<c:out value="${book.isbn}"/>

</c:forEach>

 

items 속성값으로기본타입의배열, java.util.Collection, java.util.Map, java.util.Iterator, java.util.Enumeration, java.lang.Object 배열, 콤마로이루어진 java.lang.String 등의객체를사용할있다.

java.util.Map 객체는아래처럼사용한다.

 

<%

Map books = new HashMap();

books.put("one", new Book("100"));

books.put("two", new Book("200"));

request.setAttribute("books", books);

%>

 

// one 100 two 200출력한다. (순서는정확하지않다.)

<c:forEach items="${books}" var="book">

<c:out value="${book.key}"/>

<c:out value="${book.value.isbn}"/>

</c:forEach>

 

(7)
c:forTokens

구분자로반복문을수행한다.

 

//1 2 3 4출력한다.

<c:forTokens delims="," items="1,2,3,4" var="i">

<c:out value="${i}"/>

</c:forTokens>

 

begin, end, step 속성으로시작위치, 종료위치, 간격을조정한다.

(8)
c:
url, c:param

URL처리한다.

 

// UserForm.jsp출력한다.

<c:url value="UserForm.jsp"/>

 

// value 속성값이 /시작하면컨텍스트를포함한다.

// 컨텍스트를 web으로가정하면 /web/UserForm.jsp출력한다.

<c:url value="/UserForm.jsp"/>

 

// 다른컨텍스트를사용하려면 context 속성을사용한다.

// 때는 value context 속성의값이모두 /시작해야한다.

// /other/UserForm.jsp출력한다.

<c:url value="/UserForm.jsp" context="/other"/>

 

 

scope var 속성을이용해서 URL화면에출력하지않고 JSP 영역에저장할있다.

c:param 태그를이용해서 Query String URL추가한다.

 

// 파라미터값을 escape한다. 따라서

// UserForm.jsp?name=%EC%A0%95%EB%8C%80%EB%A7%8C출력한다.

<c:url value="UserForm.jsp">

<c:param name="name" value="성선임"/>

</c:url>

 

c:param 태그는 c:import c:redirect 태그에서도동일한방법으로사용한다.

(9)
c:import

특정 JSP내용을화면에포함해서출력한다.

 

// UserForm.jsp내용을화면에포함하여출력한다.

<c:import url="UserForm.jsp"/>

 

데이터인코딩에문제가있으면 charEncoding 속성을사용한다.

<c:import url="UserForm.jsp" charEncoding="UTF-8"/>

 

// context 속성을이용하면다른어플리케이션의 JSP포함할있다.

<c:import url="/UserForm.jsp" charEncoding="UTF-8" context="/other"/>

 

var varReader 속성을이용하면내용을화면에출력하지않고변수에저장할있다.

(10)
c:redirect

다른경로로이동한다.

 

// 앞에데이터를브라우저에전송하는코드가없어야한다.

<c:redirect url="http://www.naver.com"/>

 

(11)
c:catch

예외를처리한다.

 

// var 속성값으로발생한예외객체를 page 영역에저장한다.

<c:catch var="e">

<%

if (true) throw new RuntimeException();

%>

</c:catch>

 

<c:out value="${e}"/>

 

6.
참고
자료

 
The J2EE 1.3 Tutorialhttp://java.sun.com/j2ee/1.3/docs/tutorial/doc/index.html

 
The J2EE 1.4 Tutorialhttp://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html

 
JSTL in Action

 
JSTL 1.0 Specificationhttp://jcp.org/aboutJava/communityprocess/final/jsr052

이 글은 스프링노트에서 작성되었습니다.

Posted by 이버리
,

Auto Wire...


스프링은 네 가지 자동 연결 모드를 제공한다. byName, byType, constructor, autodetect가 있다

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="
  5.                 http://www.springframework.org/schema/beans
  6.                 http://www.springframework.org/schema/beans/spring-beans.xsd">

  7. <bean id="foo" class="com.apress.prospring2.ch03.autowiring.Foo" />
  8. <bean id="bar" class="com.apress.prospring2.ch03.autowiring.Bar" />

  9. <bean id="byName" autowire="byName"class="com.apress.prospring2.ch03.autowiring.Target" />
  10. <bean id="byType" autowire="byType"class="com.apress.prospring2.ch03.autowiring.Target" />
  11. <bean id="constructor" autowire="constructor"class="com.apress.prospring2.ch03.autowiring.Target" />
  12. <bean id="autodetect" autowire="autodetect"class="com.apress.prospring2.ch03.autowiring.Target" />

  13. </beans>

 

1) byname연결을 사용하면 스프링은 각 속성과 같은 이름을 가진 빈과 연결을 시도한다. 그러므로 만약 타겟 빈이 foo 라는 속성을 가지고 있고 foo라는 빈이 빈팩토리에 정의되어 있다면 foo 빈은 타겟의 foo 속성에 할당된다.

( 즉 위의 xml처럼 foo,bar가 있고 byName bean이 byName 연결을 사용할경우 Target에 정의된 foo,bar에 할당된다 )

 

2) byType자동 연결을 사용하면 스프링은 빈팩토리에 내부에 타겟 빈의 각 속성의 타입과 같은 타입의 빈으로 연결을 시도한다. 따라서 만약 String 타입 속성을 가진 타겟 빈이 있고 해당 빈팩토리에String 타입 빈이 있다면 스프링은 String 빈을 타겟 빈의 String 타입 속성에 주입할 것이다. 만약 같은 빈팩토리 내부에 같은 타입의 빈이 둘 이상이라면 즉 이 경우에 String 타입 빈이 여러 개면, 스플링은 어떤 것을 자동으로 연결할지 판단할 수 없기 때문에 예외를 발생 시킨다

 

3) constructor연결 모드는 byType 연결과 비슷하지만 주입을 할 때 세터가 아닌 생성자를 사용한다.스프링은 인자 수가 가장 많은 생성자에 대응을 시도한다. 따라서 만약 두 개의 생성자가 있는 데 하나는 String 타입 하나를 받고 다른 하나는 StringInteger를 받고 빈팩토리에 StringInteger 타입의 빈이 스프링은 두 개의 인자를 가지고 있는 생성자를 사용할 것이다.

 

4) autodetect는 스프링이 constructorbyType 모드를 자동으로 선택하게 한다. 만약 빈이 (인자가 없는)기본 생성자를 가지고 있다면 스프링은 byType을 사용하고 그렇지 않으면 constructor 방식을 사용한다

이 글은 스프링노트에서 작성되었습니다.

Posted by 이버리
,