1. 프레임워크 개념

   1-1. 등장 배경

     아키텍처에 해당하는 골격 코드. 애플리케이션을 개발하는 개발에서 기본이 되는 뼈대나 틀을 제공한다.

     개발자에게 모든 것을 위임하는 것이 아니라 애플리케이션의 기본 아키텍처는 프레이워크가 제공하고,

     뼈대에 살을 붙이는 작업만 개발자가 하는 것이다.

   1-2. 장점

     빠른 구현 시간, 쉬운 관리, 개발자들의 역량 획일화, 검증된 아키텍처의 재사용과 일관성 유지

   1-3. 자바 기반 프레임워크 종류

     - Struts : UI 레이어에 중점을 두고 개발된 MVC 프레임워크

     - Spring(MVC) : MVC 아키텍처를 제공하는 UI 레이어 프레임워크. Struts처럼 독립된 프레임워크는 아님

     - Spring(IoC, AOP) : 컨테이너 성격을 가지는 프레임워크

                                       스프링의 IoC, AOP 모듈 이용해 컨테이너에서 동작하는 엔터프라이즈 비즈니스 컴포넌트

                                       개발 가능

     - Hibernate : 완벽한 ORM(Object Relation Mapping) 프레임워크

                           SQL 명령어를 프레임워크가 자체적으로 생성해 DB 연동을 처리

     - JPA : Hibernate를 비롯한 모든 ORM의 공통 인터페이스를 제공하는 자바 표준 API

     - Ibatis : 개발자가 작성한 SQL 명령어와 자바 객체(VO or DTO)를 매핑해주는 기능 제공

                   기존에 사용한 SQL 명령어 재사용하여 개발하는 차세대 프로젝트에 유용하게 적용 가능

     - Mybatis : Ibatis에서 파생된 프레임워크. 기본 개념과 문법은 Ibatis와 동일

 

2. 스프링 프레임워크

   2-1. 스프링 탄생 배경

    2004년 로드 존슨이 만든 오픈소스 프레임워크이다.

    스프링 이전의 자바 기반 엔터프라이즈 애플리케이션은 대부분 EJB(Enterprise Jaba Beans)로 개발되었으나,

    EJB 컨테이너는 스펙이 복잡하여 개발 및 유지보수에 복잡하고, 실행하려면 값비싼 WAS가 필요하다.

    => 평범한 POJO를 사용하면서도 복잡하지 않고 비용을 절감할 수 있는 프레임워크가 대두하게 됨

 

* POJO (Plain Old Java Object)

평범한 옛날 자바 객체. 대표적으로 POJO가 아닌 클래스는 Servlet이다.

POJO가 아닌 클래스는 개발자 마음대로 만들 수 없으며, 요구하는 규칙에 맞게 클래스를 만들어야 실행할 수 있다.

 

   2-2. 스프링 특징

    - 경량 : 개발과 실행, 배포가 빠르고 쉬움. POJO 형태 객체 관리가 쉬움

    - 제어의 역행(IoC) : 낮은 결합도와 높은 응집도. 객체 생성을 자바 코드로 직접 처리하지 않고 컨테이너가 대신

                              처리한다. 객체-객체 사이의 의존관계 역시 컨테이너가 처리한다. (유지보수 편리)

    - 관점지향 프로그래밍(AOP) : 반복해서 등장하는 공통 로직을 분리함으로서 응집도를 높혀 개발하는 것

    - 컨테이너 : 특정 객체의 생성과 관리를 담당하며, 객체 운용에 필요한 다양한 기능을 제공한다.

                    일반적으로는 서버 안에 포함되어 배포 및 구동된다. (Servlet 컨테이너, EJB 컨테이너 등)

   2-3. IoC 컨테이너

     스프링을 이해하는데 가장 중요한 개념.

    컨테이너는 자신이 관리할 클래스들이 등록된 XML 설정 파일을 로딩해 구동하고, 클라이언트 요청이 들어오는

    순간 XML 설정 파일을 참조하여 객체를 생성하고 객체 생명 주기를 관리한다.

    개발자가 어떤 객체를 생성할지, 객체간의 의존관계 등의 작업들을 코드로 처리하지 않고 컨테이너로 처리하는

    것을 의미한다. (낮은 결합도)

 

    대부분의 IoC 컨테이너는 각 컨테이너에서 관리할 객체들을 위한 별도의 설정 파일이 있다.

    스프링에서는 BeanFactory와 이를 상속한 ApplicationContext 두 개 유형의 컨테이너를 제공한다.

    - BeanFactory : 설정 파일에 등록된 <bean> 객체 생성하고 관리하는 기본 컨테이너 기능만 제공한다.

                             클라이언트 요청에 의해서만 bean 객체 생성되는 방식을 사용하기 때문에, 일반적인 스프링에서는

                             BeanFactory를 사용할 일은 없다.

    - ApplicationContext : 기본 객체 관리 기능 외 트랜잭션 관리, 메시지 기반 다국어 처리 등의 기능을 지원한다.

                                         컨테이너 구동 시험에 <bean> 등록된 클래스들 객체를 생성하는 즉시 로딩 방식으로 동작한다.

                                         웹 애플리케이션 개발도 지원하므로 대부분의 스프링 프로젝트는 해당 컨테이너를 이용한다.

  2-4. 스프링 XML 설정

    스프링 컨테이너는 bean 저장소에 해당하는 XML 설정 파일을 참조해 bean 생명 주기를 관리하고 서비스를 제공한다.

  

이클립스 Help > Install New Software 클릭

 

 

 

 

* 설치해야 할 소프트웨어 종류

 

1) Spring Core 3.7.3 (필수)
    http://dist.springsource.com/release/TOOLS/update/e4.4/
    Core / Spring IDE -> Spring IDE Core


2) UML2 Extension 5.1.2 (필수)
    http://download.eclipse.org/releases/mars/
    Modeling -> UML2 Extender SDK


3) Subversive SVN Connector 6.0.1 (필수)
    http://download.eclipse.org/releases/mars/
    Collaboration -> Subbersive SVN Team Provider(3.0.4)
    http://community.polarion.com/projects/subversive/download/eclipse/5.0/mars-site/
    Subversive SVN Connectors -> Subversive SVN Connectors(5.0.3) 설치
    SVNKit 1.8.12 Implementation(5.0.3) 설치


4) eGovFrame 3.6.0 (필수)
    http://maven.egovframe.kr:8080/update_3.6/
    필요한 플러그인 설치(전부 다 설치했음)


5) JUnit 4.12 (필수)
    이클립스에 내장되어있어서 별도 설치과정 필요없음


6) MyBatipse 1.0.23 (선택)
    http://dl.bintray.com/harawata/eclipse
    MyBatipse -> MyBatipse 설치


7) PMD 4.0.11 (선택)
    https://sourceforge.net/projects/pmd/files/pmd-eclipse/update-site/
    PMD for Eclipse 4 -> PMD Plug-in 설치


8) FindBugs 3.0.1 (선택)
    http://findbugs.cs.umd.edu/eclipse
    FindBugs -> FindBugs Feature 설치


9) Properties Editor 6.0.4 (선택)
    http://propedit.sourceforge.jp/eclipse/updates/
    PropertiesEditor 설치


10) EclEmma 2.3.3 (선택)
      http://update.eclemma.org/
      EclEmma -> EclEmma Java Code Coverage 설치


11) Gradle 1.0.21 (선택)
     http://download.eclipse.org/buildship/updates/e45/releases/1.0
     Buildship:Eclipse Plug-ins for Gradle -> Buildship:Eclipse Plug-ins for Gradle 설치


12) Developer Tools 23.0.7 / Android Connector for M2E 1.4.0(안드로이드 개발 필수)
     http://rgladwell.github.com/m2e-android/updates/
     Developer Tools 모두 설치 (Developer Tools)
     Android for Maven Eclipse -> Android for Maven Eclipse 설치 (Android Connector for M2E)

1. 종류

 isNull

 null일 경우

 isNotNull

 null이 아닐 경우

 isEmpty

 공백일 경우

 isNotEmpty

 공백이 아닐 경우

 isGreaterTan

 >

 isGreaterEqual

 >=

 isLessThan

 <

 isLessEqual

 <=

 isEqual

 ==

 isNotEqual

 !=

 

 

2. 사용 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<sql id="Condition">
    WHERE 1 = 1
    -- searchDeptCode 파라미터가 null이 아닐 경우, AND DEPT_CODE = #parameter# 구문이 실행된다.
    <isNotNull property="searchDeptCode" prepend="AND">
        DEPT_CODE = #searchDeptCode#
    </isNotNull>
    -- searchDeptCode 파라미터가 1000과 비교하여 일치할 경우, DEPT_CODE <> 1000 구문이 실행된다.
    <isEqual property="searchDeptCode" compareValue="1000">
        AND DEPT_CODE <> #searchDeptCode#
    </isEqual>
</sql>
 
-- include 구문으로 sql에 id값으로 준 것들중, 원하는 id를 refid로 선언한다.
<select id="selectDept" resultClass="egovMap">
    SELECT * FROM DEPT
    <include refid="Condition" />
</select>
cs

1. 변경 이유

Apache project 팀이 Google code로 팀을 변경하게 되면서 그에 따라 iBatis에서 myBatis로 명칭이 변경되었다.



2. iBatis vs myBatis 비교

항목

iBatis

myBatis

 1) Java 요구 버전

 JDK 1.4 이상

 JDK 1.5 이상

 (myBatis 3.2 부터는 JDK 1.6 이상만 가능)

 2) 패키지 내부 구조

 com.ibatis.*

 org.apache.ibatis.*

 3) sqlMap 내부 구조

 parameterMap을 사용하지 않음

 sqlMapConfig / sqlMap / resultClass 사용

 parameterType으로 대체

 dtd 변경 (http://mybatis.org/dtd/mybatis-3/mapper.dtd)

configuration / Mapper / resultType  사용

 4) 라이브러리

 

 별도의 라이브러리 필요

 5) Annotation

 

 sqlMapClient DI 설정이 불필요해짐

 간편해짐

 Bean id sqlSessionFactory / sqlSessionTemplate만 지정하면 됨

 6) rawhandler

 

 resultHandler로 변경

 자바 @를 사용하여 xml을 사용하지 않음

 자바 코드보다 xml이 우선순위를 가지게 됨

 7) namespace

 <sqlmap namespace="User"  .../>

 <mapper namespace="mybatis.mapper.User" .../>

 필수로 입력해야 하는 항목.

 UserStatement NameSpace 설정을 제거함

 8) 동적 sql

 COLUMN_NAME = #parameter#

 COLUMN_NAME = #{parameter}

 9) 캐시 지원 여부

 X

 O



3. 세부사항

2번 표에서 간단히 요약한 사항들을 세부적으로 파헤쳐본다.

1) Java 요구 버전

2) 패키지 내부 구조

3) sqlMap 내부 구조

4) 라이브러리

5) Annotation

6) rawhandler

7) namespace

8) 동적 sql

9) 캐시 지원 여부

1. 정의

엑셀 파일 템플릿을 이용해 엑셀 파일을 쉽게 다운로드 하는 패키지이다.

또한, XML 설정 파일을 통해 엑셀 파일 데이터를 자바 객체로 읽는 장치도 제공한다.

jXLS 라이브러리는 POI 패키지를 기반으로 동작하기 때문에 jXLS 라이브러리 사용시 POI 라이브러리도 함께 사용해야 한다.

XTLS 객체를 사용하는 방식을 선호하는 이유는, 자바의 MVC 패턴을 그대로 활용 가능하기 때문이다.

기존 코드에 view 단을 담당하는 jsp 대신 엑셀 파일을 view로 활용하여 처리하면 된다.

템플릿을 기반으로 하여 엑셀 파일을 그대로 사용 가능하기 때문에 엑셀 기능의 대부분도 사용 가능하다.



2. 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    <dependency>
        <groupId>net.sf.jxls</groupId>
        <artifactId>jxls-core</artifactId>
        <version>1.0.6</version>
    </dependency>
    <dependency>
        <groupId>org.jxls</groupId>
        <artifactId>jxls-poi</artifactId>
        <version>1.0.9</version>
    </dependency>
    <dependency>
        <groupId>org.jxls</groupId>
        <artifactId>jxls-jexcel</artifactId>
        <version>1.0.6</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.14</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.14</version>
    </dependency>
cs

pom.xml 파일에 다섯 개의 라이브러리를 추가해준다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    @RequestMapping(value = "/listExcel.do")
    public void listExcel(HttpServletRequest request,
            HttpServletResponse response, UserSearchVO searchVO,
            ModelMap modelMap) {

        // Service의 해당 메소드로 실현될 쿼리로는 list select문을 그대로 사용하면 된다.
        List<?> listUser = userService.selectUserList(searchVO);
        Map<String, Object> beans = new HashMap<String, Object>();
        
        beans.put("listUser", listUser);
        
        // 엑셀 다운로드 메소드가 담겨 있는 객체
        MakeExcel me = new MakeExcel();
        
        // 인자로 request, response, Map Collection 객체, 파일명, 폴더명, 견본파일을 받는다.
        me.download(request, response, beans, "파일명""폴더명""견본 파일.확장자");
    }
cs


엑셀 다운로드 컨트롤러이다. jsp에 listExcel.do로 하이퍼링크를 걸어준 뒤 클릭하면 해당 컨트롤러로 이동하게 된다.

엑셀 다운로드가 담겨 있는 MakeExcel 이라는 객체는 이미 존재하는 라이브러리가 아닌 다운로드를 위해 임의로 만든 객체이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class MakeExcel {
    public void download(HttpServletRequest request, HttpServletResponse response,
                    Map<String, Object> bean, String fileName, String templateFile)
                    throws ParsePropertyException, InvalidFormatException {
        
        String tempPath = request.getSession().getServletContext().getRealPath("/WEB-INF/templete");
        
        try {
            InputStream is = new BufferedInputStream(new FileInputStream(tempPath + "\\" + templateFile));
            XLSTransformer xls = new XLSTransformer();
            Workbook workbook = xls.transformXLS(is, bean);
            
            response.setHeader("Content-Disposition""attachment; filename=\"" + fileName + ".xlsx\"");
            
            OutputStream os = response.getOutputStream();
            
            workbook.write(os);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
cs


임의로 생성한 MakeExcel 클래스의 소스이다. InputStream과 OutputStream 객체를 사용해 엑셀 다운로드를 가능하도록 해준다.

tempPath 변수로 값을 복사한 getRealPath() 메소드에 엑셀 템플릿이 들어갈 경로를 적어주면 된다.

엑셀 템플릿에는 실제로 jstl 형식으로 파라미터를 전달하듯 Map에 담은 객체를 ${객체명.파라미터} 를 사용해

jsp list를 출력하듯 엑셀 파일 내에 그대로 적어주면 된다.

1. 정의

AOP는 IoC, DI와 더불어 Spring 프레임워크의 3대 핵심 기술중 하나이다.


전통적인 설계 방법을 따랐던 경우에는 트랜잭션의 분리가 어려웠기 때문에 객체 간의 결합도를 조금이라도 낮추기 위해 관점 지향 프로그래밍을 도입하게 되었다.


주 업무가 아닌, 부가 업무가 응집력이 강한 경우에는 소스가 복잡해진다. OOP (Object Oriented Programming - 객체 지향 프로그래밍)의 보완적 개념으로 관점 지향 프로그램을 사용하고 있다. (클래스들이 공통으로 갖는 기능이나 절차 등을 하나의 것으로 묶어 빼내 별도로 관리하려는 목적)


보조 업무의 코드를 주 업무 코드에서 분리해 작성하고, 필요시에만 도킹(Docking)하여 사용하고, 스프링 프레임워크 내에서 구현하는 방법으로는 xml 스키마를 기반으로 구현하는 방법과 @Aspect 어노테이션을 이용해 구현하는 방법으로 두 가지가 있다.


가장 대표적인 부가 업무의 예로는 로그인, 트랜잭션, 보안, 캐싱 등의 작업이 있다.



2. 특징

순번 

 장점

 1

 부가 업무 소스가 한 곳으로 응집되어 응집력이 높아진다.

 2

 코드가 깔끔해지고 가독성이 높아진다.



3. 실행 순서

Spring 프레임워크에서 AOP의 구현은 프록시를 이용해 구현한다.

ㄱ. 수행할 어드바이스를 프록시에 요청한다.

ㄴ. 핵심 기능을 수행하기 전에 사용할 공통 기능을 수행한다.

ㄷ. 공통 기능을 수행한 후 핵심 기능 쪽으로 가서 핵시 기능 로직을 수행한다.

ㄹ. 핵심 기능을 수행한 후 다시 프록시로 가서 공통 기능을 수행한다.



4. 종류 (Spring이 지원하는 AOP)

ㄱ. AspectJ (eclipse.org/aspectj)

ㄴ. JBoss AOP (labs.jboss.com)

ㄷ. Spring AOP (www.springframework.org)

1. 정의

@RequestBody 어노테이션은 컨트롤러의 메소드 내에서 해당 어노테이션이 붙은 객체를 바인딩시

리턴값을 view로 자동 바인딩 되지만, 컨트롤러에 @ResponseBody 어노테이션이 선언되어 있다면

리턴 값은 view를 통해 출력되지 않고 HTTP Response Body에 직접 쓰여진다.

이 때, 해당 메소드 리턴값의 데이터 타입에 따라 MessageConverter에서 변환이 이뤄진 후 쓰여진다.


주로 jsp에서 비동기 통신(ajax)시 사용한다. application/json을 지원한다.

어노테이션을 <mvc:annotation-driven />을 사용하고 있다면, HttpMessageConverter를 기본으로 등록하기 때문에,

별도의 설정이 필요 없이 Jackson 라이브러리만 추가하면 된다.



2. 예제


1
2
3
4
5
6
7
8
9
10
<dependency>
    <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.13</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>
cs


pom.xml 에 두 개의 라이브러리를 추가한다.


1
2
3
4
5
6
7
8
9
10
11
<!-- @ResponseBody 어노테이션이 있는 Controller는 리턴값이 MessageConvert로 설정된 
    MappingJacksonHttpMessageConverter 에서 JSON 으로 변환 작업이 이뤄진다. -->
<beans:bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >
    <beans:property name="messageConverters">
        <!-- MappingJacksonHttpMessageConverter : MessageConverter의 종류중 하나.
                                                Jackson's ObjectMapper를 사용한다.
                                                request, repsonse를 JSON으로 변환할 떄 사용하는 MessageConverter.
                                                application / json을 지원한다. -->
        <beans:bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
    </beans:property> 
</beans:bean>    
cs


context.xml에 해당 bean을 추가한다.


1
2
3
4
5
6
7
@RequestMapping(value = "/index.do")
public @ResponseBody List memberIdCheck() throws Exception {
        
    List<Map<StringString>> list = new ArrayList<Map<StringString>>();
    
    return list;
}
cs


컨트롤러를 위와 같이 작성한다. 컨트롤러까지 작성한 후, 매핑된 주소를 url에 입력해보면 JSON임을 확인할 수 있다.


Model 객체를 세션에 저장했다가 다시 활용하게 해주는 기능이다.

서블릿은 기본적으로 상태를 유지하지 않으려 하는데, 상태를 유지해줘야 하는 경우에 사용한다.



1. @ModelAttributes

Command Object. 클라이언트측 파라미터를 1:1로 전담하는 property에 담아내는 방식이다.

해당 어노테이션을 붙이면 자동으로 바인딩 되고, 중간 과정을 생략한다. (인자에 넣기만 하면 된다.)

getter / setter 등의 과정을 알아서 생략할 수 있다.


Enum 객체 같은 경우여도 파라미터 이름만 알면 자동으로 매핑해준다.

그러나, 만약 같은 객체가 2개 이상 전달되는 폼 구성인 경우 굉장히 까다로워진다.

세션으로 사용자 파라미터를 List 형태로 저장하게 되는데, DB 입력 후 @ModelAttributes가 적용되지 않는다. (컬렉션을 지원하지 않기 떄문에)


1
2
3
4
5
6
7
// @ModelAttributes는 해당 값을 복수로 받고 싶을 땐
// 오로지 Java Bean 객체를 배열로 선언하는 방법 뿐이다.
public class A {
    private String[] id;
    private String[] pw;
    ...
}
cs


=> 해당 값을 복수로 받고 싶다면, 오로지 Java Bean 객체를 배열로 선언하는 방법 밖에는 없다.

=> 유동적으로 변하는 <form>에는 대응이 까다로워진다.

=> 해당 파라미터에 문제가 있을 경우, 타 단일 객체와 같이 배열이 아닌 배열 속의 객체에 바인딩 에러를 처리해주는 기술이 별도로 필요하다.



2. @SessionAttributes

어노테이션에서 설정한 Model 객체를 세션에 저장하는 역할을 한다. 해당 모델 객체를 사용할 시,

세션에서 불러와 사용하며 view에서도 이름으로 접근 가능하다. @SessionAttributes를 컨트롤러에 붙이고 모델명을 인자로 넣어준다.


 

 용도

 1

 Spring framework에서 제공하는 form 태그 라이브러리 이용시

 2

 몇 단계에 걸쳐 완성되는 form 구성시

 3

 지속적으로 사용자의 입력 값을 유지하고 싶을 떄


스프링에서 상태 유지를 위해 제공하며, 객체 위치는 view와 Controller 사이에 존재한다.

해당 어노테이션이 붙은 컨트롤러는 지정하는 세션명을 @RequestMapping으로 설정한 모든 view에서 공유하고 있어야 한다.

(공유하지 않을 시 에러가 발생함)


=> * 해결 방법

ㄱ. 해당 컨트롤러에서 맨 처음 읽어들이는 Model 객체를 통해 수동적으로 파라미터를 보내주는 것.

(반드시 첫 번째로 해당하는 view를 통해야 한다는 제약 조건)

ㄴ. @ModelAttributes 어노테이션이 붙은 메소드 사용 : 해당 컨트롤러로 접근하는 모든 요청에 어노테이션이 붙은

메소드 command() 로 메소드의 리턴값을 설정된 모델명으로

자동 포함해주는 역할을 담당한다.

클라이언트 접근시 어노테이션이 붙은 메소드의 리턴값을 보장받는다.


해당 어노테이션의 설정값과 동일한 이름을 Model 객체에서 발견시 세션 값으로 자동 변경시켜준다.

그 Model 객체가 세션값으로 대체되면, 세션값을 지우기 전까지 저장된 해당 값을 불러오게 된다.


* @SessionAttributes 사용 예시

- 고객 입력 폼 등에서 잘못 입력되어 경고창을 띄우고 다시 페이지를 만든다고 생각할 때, 최초 입력한 정보를 세션에 저장해두고 이를 바탕으로 입력 화면을 다시 띄우는 경우

- 등록 화면이 여러 페이지에 걸쳐 입력되는 경우, 미리 모델 객체를 생성해 첫번쨰 화면 내용을 객체에 저장해두고

   다음 입력 화면에서 나머지 고객 정보를 입력해 세션 객체에 추가로 저장하는 경우 (유효성 검사 시에도 유리함)


* @ModelAttributes와 같이 컬렉션 프레임워크를 지원하지 않는다. (List 지원 안 함)



3. SessionStatus 객체

사용 완료된 객체는 사용 후 SessionStatus.setComplete(); 메소드로 제거해줘야 한다. 수동으로 제거해주지 않으면 값이 계속 남아 있게 된다.

1. 정의

대한민국 공공 부분 정보화 사업시 플랫폼별 표준화된 개발 프레임워크.

과거 플랫폼 기반의 정보화 구축 사업시 수행 업체의 자체 프레임워크를 사용해 정보 시스템이 구축되어, 유지보수 등 여러가지 문제점이 있었기 때문에 전자정부프레임워크를 개발하게 되었다. 최근에는 모바일 개발 프레임워크도 출시되었다.


정보 시스템 개발을 위해 필요한 기능, 아키텍쳐를 미리 만들어 제공하기 위해 제작되었다. 또한, 효율적인 어플리케이션 구축을 지원한다.


* 프레임워크 vs 라이브러리

- 프레임워크 : 어플리케이션의 틀과 구조를 프레임워크에서 제어하고, 프레임워크 위에서 개발자의 코드가 동작한다.

- 라이브러리 : 개발자의 코드 안에서만 재사용됨을 총칭한다.



2. 특징

순번

 내용

 1

5개 서비스 그룹, 34개의 서비스로 구성

 2

 전자정부 프로젝트에 최적화된 오픈 소스 소프트웨어 선정

 3

경량화된 개발프레임워크로서 사실상 업계 표준에 가까운 Spring 프레임워크를 적용

출처: http://netframework.tistory.com/entry/3-전자-정부-프레임워크의-소개 [Programming is Fun]

경량화된 개발 프레임워크. 업계 표준에 가까운 Spring framework 적용

 4

 DI (Dependency Injection) 방식의 의존 관계 처리

 5

AOP 지원

 6

MVC Model2 아키텍쳐 구조 제공 및 다양한 UI 클라이언트 연계 지원

 7

 전자정부 개발 프레임워크 표준 연계 인터페이스 정의


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

@ResponseBody  (0) 2017.06.28
@SessionAttributes 와 SessionStatus 객체  (0) 2017.06.26
파일 다운로드  (4) 2017.03.14
Ajax :: Ajax (Asynchronos JavaScript And XML)  (0) 2017.01.10
Framework :: JSON (JavaScript Object Notation)  (0) 2017.01.10

1. context.xml 설정


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
    <!-- 모든 경로는 지정한 경로명이 붙으므로 해당 경로를 피하기 위해 업로드 파일들을 resources/ 폴더 아래 넣음 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
        <property name="order" value="1"/>
    </bean>
    
    <!-- BeanNameViewResolver : view 와 동일한 이름을 갖는 bean을 view 객체로 사용
                                custom view 클래스인 UtilFile을 view로 사용해야 하기 때문에 mapping함 -->
    <bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
        <property name="order" value="0" />
    </bean>
 
    <!--custom view 클래스 -->
    <bean id="downloadView" class="com.cafe24.smart.util.UtilFile"/>
 
</beans>
cs



2. 파일 다운로드 하이퍼링크


1
2
3
4
5
6
7
8
<html>
<head>
    <title>title</title>
</head>
<body>
    <a href="<c:url value='/re/fileDownload?reCode=${reward.reCode}'/>">${reward.reDocument}</a>
</body>
</html>
cs


화면에는 업로드된 파일 경로 전체가 보이는 것처럼 느껴지겠지만 Controller에서 해당 파일명 + 확장자까지만 보이게 잘라놓은 상태이다.

해당 파일명을 클릭하면 /re/fileDownload 경로를 값으로 받는 컨트롤러 메소드로 이동하며 get 방식으로 pk컬럼 값을 받게 된다.



3. 파일을 다운로드 하는 컴포넌트 클래스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.cafe24.smart.util;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.Map;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.stereotype.Component;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.view.AbstractView;
 
import com.cafe24.smart.approve.domain.Draft;
import com.cafe24.smart.reward.domain.Reward;
 
//@Component > @Service
//            : 스프링 프레임워크가 관리하는 컴포넌트의 일반적 타입 
//            : 개발자가 직접 조작이 가능한 클래스의 경우 해당 어노테이션을 붙임
//            : ( <=> @Bean : 개발자가 조작이 불가능한 외부 라이브러리를 Bean으로 등록시 사용)
@Component
// AbstractView : 스프링 MVC 사용시 DispatcherServlet 기능
//                : requestURI에 따라 컨트롤러로 분기하고 로직 처리 후 Resolver를 사용하여
//                : 해당 jsp 파일을 찾아 응답하게 되는데 그 사이 시점을 잡아 처리하는 부분의 기능
public class UtilFile extends AbstractView {
//  파일 다운로드
    @Override
    protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
                        HttpServletResponse response) throws Exception {
        
        setContentType("application/download; charset=utf-8");
        
        File file = (File) model.get("downloadFile");
        
        response.setContentType(getContentType());
        response.setContentLength((int) file.length()); 
        
        String header = request.getHeader("User-Agent");
        boolean b = header.indexOf("MSIE"> -1;
        String fileName = null;
        
        if (b) {
            fileName = URLEncoder.encode(file.getName(), "utf-8");
        } else {
            fileName = new String(file.getName().getBytes("utf-8"), "iso-8859-1");
        }
        
        response.setHeader("Conent-Disposition""attachment); filename=\"" + fileName + "\";");
        response.setHeader("Content-Transter-Encoding""binary");
        
        OutputStream out = response.getOutputStream();
        FileInputStream fis = null;
        
        try {
            fis = new FileInputStream(file);
            
            FileCopyUtils.copy(fis, out);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
            
            out.flush();
        }
    }
}
cs



4. 파일 다운로드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Controller
public class RewardController {
//  파일 다운로드 하는 메소드
    @RequestMapping(value = "/re/fileDownload", method = RequestMethod.GET)
//  get 방식 하이퍼링크 경로로 보낸 PK 값을 인자로 받음
    public ModelAndView reDocumentDown(@RequestParam(value="reCode"int reCode) {
        
//      pk 값으로 해당 도메인 객체의 파일 전체 경로 값을 받은 후
        Reward reward = rewardService.reListByReCodeServ(reCode);
        
//      전체 경로를 인자로 넣어 파일 객체를 생성
        File downFile = new File(reward.getReDocument());
        
        System.out.println("RewardController reDocumentDown reCode : " + reCode);
        
//      생성된 객체 파일과 view들을 인자로 넣어 새 ModelAndView 객체를 생성하며 파일을 다운로드
//      (자동 rendering 해줌)
        return new ModelAndView("downloadView""downloadFile", downFile);
    }
}
cs


+ Recent posts