보안 2017. 4. 13. 00:54


Client와 Server간의 암호화 통신을 위한 SSL/TLS


SSL(TLS)란?

SSL은 Secure Socket Layer의 약자로 웹서버와 웹 브라우저 간의 암호화 통신을 위하여 응용계층과 TCP/IP 계층에서 동작하는 프로토콜이며, Netscape사에서 만들었으며 ISO표준 정식명칭은 TLS(Transport Layer Security)이다.



SSL/TLS의 주요기능

1) 인증 : 상대 사이트에 대한 신뢰성 인증

2) 암호화 : 다양한 암호화 알고리즘을 이용하여 메시지 암호화

3) 무결성 : 송/수신 메시지에 대한 Checksum기능, 변조 방지

4) 지원 프로토콜 : HTTPS(port:443), TELNETS(port:992), POP3S(port:995), SFTP(port:22)



SSL/TLS 처리과정


[Handshake 과정]


위의 그림에서 보듯이 많은 단계를 거쳐야 메시지 송/수신 처리가 가능하다. 그만큼 처리 속도가 떨어진다는 얘기다. 또한, DDOS 공격 시 그 만큼 부하가 많이 발생한다는 의미이기도 하다. 그래서 주요정보가 송/수신되는 기능에만 SSL/TLS 처리가 필요함.


그외 암호화 통신을 위해 SET(전자결제), IPSEC(VPN 구현) 등이 있음.

'보안' 카테고리의 다른 글

코드 난독화 (Obfuscation)  (0) 2017.01.26
Ransomware(랜섬웨어)  (1) 2017.01.25
posted by 생각퍼즐
:
프로그래밍 2017. 3. 17. 11:30

공지사항 등록 테스트


1. 등록화면 호출

 - http://localhost:8080/board/regNoticeView.do



2. 테스트 데이터 입력 및 첨부파일 등록



3. DB 확인


3.1 공지사항 입력 내용 확인


1
2
SELECT *
  FROM SCOTT.TB_NOTICE
cs



3.2 첨부파일 확인

1
2
SELECT *
  FROM SCOTT.TB_ATT_FILE
cs



사용자가 입력한 값이 정상적으로 DB에 저장된 것을 확인했습니다.

이것으로 길고 길었던 스프링 프로젝트 - 공지사항 구현을 끝내도록 하겠습니다.

공지사항 목록조회는 지금까지의 포스팅된 내용을 참고하여 구현하시면 좀 더 쉽게 하실 수 있을 겁니다. 


posted by 생각퍼즐
:
프로그래밍 2017. 3. 16. 11:30

공지사항 등록 비즈니스 로직


1. Controller 구현

 - request 등록을 수행하는 regNotice 메소드의 return 값은 정상적으로 처리하면 "redirect:/notice/공지사항목록화면"으로 처리해야 됩니다. 공지사항 목록화면 구현 후 수정하시면 됩니다.


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
package com.devdic.board.controller;
 
import javax.servlet.http.HttpServletRequest;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
import com.devdic.board.service.NoticeService;
import com.devdic.board.vo.NoticeVO;
 
@Controller
public class NoticeController {
    
    @Autowired
    public NoticeService noticeService;
    
    private static final Logger logger = LoggerFactory.getLogger(NoticeController.class);
    
    // 등록화면 보여주기
    @RequestMapping(value="/regNoticeView")
    public String regNoticeView(HttpServletRequest request) throws Throwable {
        
        return "/notice/regNotice";
    }
    
    // request정보 등록
    @RequestMapping(value="/regNotice")
    public String regNotice(HttpServletRequest request, NoticeVO noticeVO) throws Throwable {
        noticeService.regNotice(request, noticeVO);
        return "/notice/regNotice";
    }
}
 
cs


2. Service 구현(interface제외)

 - 공지사항 등록이 비즈니스 로직을 담당


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
package com.devdic.board.service.impl;
 
import java.util.List;
 
import javax.servlet.http.HttpServletRequest;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import com.devdic.board.dao.NoticeDao;
import com.devdic.board.service.NoticeService;
import com.devdic.board.vo.NoticeVO;
import com.devdic.util.file.FileUpload;
 
@Service
public class NoticeServiceImpl implements NoticeService{
    
    @Autowired
    public NoticeDao noticeDao;
 
    @Override
    public int regNotice(HttpServletRequest req, NoticeVO noticeVO) throws Exception {
        // TODO Auto-generated method stub
        
        // 공지사항 정보 등록
        insertNotice(noticeVO);
        
        FileUpload fileUpload = new FileUpload();
        List<NoticeVO> list= fileUpload.parseInsertFileInfo(req);
        int i = 0;
        for(NoticeVO fileList: list){
            i++;
            noticeVO.setAttFileId(i);
            noticeVO.setAttFileNm(fileList.getAttFileNm());
            noticeVO.setAttFileSaveNm(fileList.getAttFileSaveNm());
            noticeVO.setAttFileSize(fileList.getAttFileSize());
            noticeVO.setDelYn("N");
            // 첨부파일 등록
            insertAttFile(noticeVO);
        }
        return 0;
    }
    
    private int insertNotice(NoticeVO noticeVO) throws Exception{
        return noticeDao.insertNotice(noticeVO);
    }
    
    private int insertAttFile(NoticeVO notieceVO) throws Exception{
        return noticeDao.insertAttFile(notieceVO);
    }
 
}
 
cs


3. Repository(DAO) 구현(interface제외)

 - namespace는 mapper(notice.xml)에 정의된 namespace 값입니다.

 - 4.SQL작성의 notice.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
27
package com.devdic.board.dao.impl;
 
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
 
import com.devdic.board.dao.NoticeDao;
import com.devdic.board.vo.NoticeVO;
 
@Repository
public class NoticeDaoImpl implements NoticeDao{
    
    @Autowired
    private SqlSessionTemplate sqlSession;
    
    private final String namespace = "SqlMapNoticeDao";
    
    public int insertNotice(NoticeVO noticeVO) throws Exception{
        return sqlSession.insert(namespace+".insertNotice", noticeVO);
    }
    
    public int insertAttFile(NoticeVO noticeVO) throws Exception{
        return sqlSession.insert(namespace+".insertAttFile", noticeVO);
    }
 
}
 
cs


4. SQL 작성

 - root-context.xml 설정파일에서 mybatis 설정부분을 보면...

   mapper(SQL) 파일의 경로를 설정한 것이 기억나시죠^^

   

1
2
<!-- SQL(mapper) 경로 지정 -->
<property name="mapperLocations" value="classpath:sqlMap/**/*.xml"/>
cs


아래의 그림처럼 공지사항과 관련된 SQL을 작성하기 위한 notice.xml 파일을 하나 생성합니다.



notice.xml을 아래의 코드를 참조하여 작성합니다.

mybatis의 바인드 처리는 "#"으로 처리하시면 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.2//EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
 
<mapper namespace="SqlMapNoticeDao">
 
    <insert id="insertNotice" parameterType = "com.devdic.board.vo.NoticeVO">
    <selectKey keyProperty="noticeId" resultType="int" order="BEFORE">
        SELECT NVL(MAX(NOTICE_ID) + 1, 1) AS NOTICE_ID FROM TB_NOTICE 
    </selectKey>
    INSERT INTO TB_NOTICE(NOTICE_ID, NOTICE_TITLE, NOTICE_CONTENT, DEL_YN)
    VALUES(#{noticeId}, #{noticeTitle}, #{noticeContent}, #{delYn})
    </insert>
    
    <insert id="insertAttFile" parameterType = "com.devdic.board.vo.NoticeVO">
    INSERT INTO TB_ATT_FILE(NOTICE_ID, FILE_ID, ATT_FILE_SAVE_NM, ATT_FILE_NM, ATT_FILE_SIZE, DEL_YN)
    VALUES(#{noticeId}, #{attFileId}, #{attFileSaveNm}, #{attFileNm}, #{attFileSize}, #{delYn})
    </insert>
    
</mapper>
 
cs



공지사항 등록을 위한 소스구현은 되었으니, 테스트를 해봐야죠~~~

posted by 생각퍼즐
:
프로그래밍 2017. 3. 10. 11:30

공지사항 첨부파일 처리



1. 첨부파일 처리


1.1 File을 다루기위한 FileUtil 클래스 구현

 - 아래의 소스처럼 파일을 다루기위한 메소드를 util로 미리 만들어 놓으세요!


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
package com.devdic.util.file;
 
import java.io.File;
import java.net.URLEncoder;
 
import com.devdic.util.date.DateUtil;
 
public class FileUtil {
    
    // 디렉토리 확인, 존재하지 않을 경우 생성
    public static void exsitDir(File file) throws Exception{
        if(file.exists() == false){
            file.mkdirs();
        }
    }
    
    // DB에 저장할 유일한 파일명으로 변경
    public static String getSaveFileNm(String orgFileName, String orgFileExtension) throws Exception{
        StringBuffer sb = new StringBuffer();
        sb.append(DateUtil.getDate());
        sb.append("_");
        sb.append(orgFileName);
        sb.append(orgFileExtension);
        return sb.toString();
    }
    
    // 파일 다운로드 시 Cilent의 브라우저에 따라 파일명의 인코딩 설정
    public static String getEncodedFileNameByBrowser(String filename, String browser) throws Exception {
        
           String encodedFilename = null;
           if (browser.equals("MSIE")) {
                encodedFilename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+""%20");
           } else if (browser.equals("Firefox")) {
                encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1"+ "\"";
           } else if (browser.equals("Opera")) {
                encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1"+ "\"";
           } else if (browser.equals("Chrome")) {
              StringBuffer sb = new StringBuffer();
              for (int i = 0; i < filename.length(); i++) {
                          char c = filename.charAt(i);
                          if (c > '~') {
                                     sb.append(URLEncoder.encode("" + c, "UTF-8"));
                          } else {
                                     sb.append(c);
                          }
              }
              encodedFilename = sb.toString();
           } else {
              throw new RuntimeException("Not supported browser");
           }
           return encodedFilename;
        }
    
    // 파일을 해당 디렉토리에서 삭제
    public static void deleteFile(String filePath) throws Exception{
        File file = new File(filePath);
        file.delete();
    }
 
}
 
cs


1.2 DB에 유일한 파일명으로 저장하기 위해 시간값을 사용

 - DataUtil 구현


1
2
3
4
5
6
7
8
9
10
11
12
package com.devdic.util.date;
 
import java.util.Calendar;
 
public class DateUtil {
    
    public static long getDate() throws Exception{
        Calendar  today = Calendar.getInstance();
        long date = today.getTimeInMillis();
        return date;
    }
}
cs


1.3 HttpServletRequest 객체에서 사용자가 업로드한 파일을 서버에 저장 및 DB에 저장하기 위한 정보처리

 - FileUpload.java 구현


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
package com.devdic.util.file;
 
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
 
import javax.servlet.http.HttpServletRequest;
 
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
 
import com.devdic.board.vo.NoticeVO;
 
public class FileUpload {
    
    // 나중에 properties파일로 변경하여 관리
    private static final String filePath = "C:\\devdic\\file\\upload\\";
         
    public List<NoticeVO> parseInsertFileInfo(HttpServletRequest request) throws Exception{
        
        // Client의 request를 MultipartHttpServletRequest 객체로 캐스팅(변환)
        MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest)request;
        
        // MultipartHttpServletRequest 객체에서 파일정보를 Iterator타입으로 저장
        Iterator<String> iterator = multipartHttpServletRequest.getFileNames();
         
        MultipartFile multipartFile = null;
        String orgFullFileNm = null// 사용자가 업로드한 파일명(확장자 포함) 
        String orgFileNm = null// 사용자가 업로드한 파일명(확장자 제외) 
        String orgFileExtension = null// 파일 확장자명
        String saveFileNm = null// DB에 저장할 파일명
        
        // 사용자가 업로드한 여러개의 파일을 처리하기 위해 List 객체 생성
        List<NoticeVO> list = new ArrayList<NoticeVO>();
        
        // 각각의 파일정보를 저장할 VO 객체 초기화
        NoticeVO listMap = null
        
        // 파일을 저장할 디렉토리 확인, 디렉토리 없을 시 생성하는 로직 포함
        File file = new File(filePath);
        FileUtil.exsitDir(file);
        
        // MultipartHttpServletRequest 객체에서 파일의 개수 만큼 아래의 로직을 반복 수행
        while(iterator.hasNext()){
            multipartFile = multipartHttpServletRequest.getFile(iterator.next());
            if(multipartFile.isEmpty() == false){
                orgFullFileNm = multipartFile.getOriginalFilename();
                orgFileNm = orgFullFileNm.substring(0,orgFullFileNm.lastIndexOf("."));
                System.out.println("orgFileNm : " + orgFileNm);
                orgFileExtension = orgFullFileNm.substring(orgFullFileNm.lastIndexOf("."));
                saveFileNm = FileUtil.getSaveFileNm(orgFileNm, orgFileExtension);
                 
                file = new File(filePath + "/" +saveFileNm);
                multipartFile.transferTo(file);
                 
                listMap = new NoticeVO();
                
                listMap.setAttFileNm(orgFullFileNm);
                listMap.setAttFileSaveNm(saveFileNm);
                listMap.setAttFileSize(multipartFile.getSize());
                
                list.add(listMap);
            }
        }
        return list;
    }
 
}
 
cs



posted by 생각퍼즐
:
프로그래밍 2017. 2. 21. 00:59


Request 정보 처리를 위한 설정


사용자가 공지사항 등록화면에서 입력한 정보와 첨부파일 정보를 저장할 테이블을 생성하고 DB연동을 위한 Datasource 설정, Mybatis연동 설정, Transaction설정, 파일처리를 위한 multipartResolver 설정을 차례대로 설명하겠습니다.


1. Database 테이블 생성


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
/*
    공지사항 정보 저장
*/
CREATE TABLE SCOTT.TB_NOTICE(
NOTICE_ID       NUMBER(10),
NOTICE_TITLE    VARCHAR2(200),
NOTICE_CONTENT  VARCHAR2(4000),
DEL_YN          CHAR(1)
)
TABLESPACE USERS
STORAGE
(
    INITIAL 64K
    NEXT 1M
)
NOCOMPRESS;
 
/*
    공지사항 첨부파일 정보 저장
*/
CREATE TABLE SCOTT.TB_ATT_FILE(
NOTICE_ID           NUMBER(10),
FILE_ID             NUMBER(3),
ATT_FILE_SAVE_NM    VARCHAR2(200),
ATT_FILE_NM         VARCHAR2(4000),
ATT_FILE_SIZE       NUMBER(10),
DEL_YN              CHAR(1)
)
TABLESPACE USERS
STORAGE
(
    INITIAL 64K
    NEXT 1M
)
NOCOMPRESS;
 
ALTER TABLE SCOTT.TB_NOTICE
ADD CONSTRAINT PK_TB_NOTICE PRIMARY KEY (NOTICE_ID);
 
ALTER TABLE SCOTT.TB_ATT_FILE
ADD CONSTRAINT PK_TB_ATT_FILE PRIMARY KEY (NOTICE_ID, FILE_ID);
 
ALTER TABLE SCOTT.TB_ATT_FILE
ADD CONSTRAINT FK_TB_ATT_FILE FOREIGN KEY (NOTICE_ID) REFERENCES SCOTT.TB_NOTICE (NOTICE_ID);
cs



2. Datasource 및 Transaction 설정

 - root-context.xml 파일을 참조하여 네임스페이스와 설정 정보를 추가합니다.

 - oracle Driver를 찾지 못하는 error가 발생하면, 오라클 설치 폴더에서 ojdbc를 찾아 JAVA를 설치한 곳으로 복사하면 error가 해결됩니다.

=> 오라클홈 -> jdbc -> lib -> ojdbc6.jar 파일을

=> 자바설치폴더 -> jre -> lib -> ext 폴더로 복사


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
80
81
82
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
    
    <!--  
        @Service, @Repository 스트레오타입 어노테이션이 선언된 클래스를 빈으로 등록한다.
    -->
     <context:component-scan base-package="com.devdic.board">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    
    <context:annotation-config/>
    
    <!-- 
    datasource 설정에 필요한 라이브러리 추가를 위해 아래의 내용을 pom.xml에 추가필요
    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.3</version>
    </dependency>
    -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin@127.0.0.1:1521:orcl" />
        <property name="username" value="SCOTT"/>
        <property name="password" value="SCOTT"/>
    </bean>
    
    <!-- Transaction 설정 -->
    <!-- 
    Transaction 설정에 필요한 라이브러리 추가를 위해 아래의 내용을 pom.xml에 추가
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${org.springframework-version}</version>
    </dependency>  
     -->
     <!-- dataSource를 활용하는 트랜잭션 매니저를 등록 -->
     <!-- dataSource 빈을 DataSourceTransactionManager 트랜잭션 매니저의 dataSource 속성에 지정  -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <!-- AOP advisor 를 활용하여 트랜잭션을 처리함
        아래의 dependency를 pom.xml에 추가 
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.9</version>
        </dependency>
    -->
     <tx:advice id="txAdvice" transaction-manager="txManager">
       <tx:attributes>
       <!--
            모든 메소드에 대해서 트랜잭션을 REQUIRED 으로 지정하고
            Exception 발생 시 롤백 지정
        -->
       <tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
       </tx:attributes>
    </tx:advice>
    <!-- 
    com.devdic.board 아래의 클래스 명이 ~~~ServiceImpl로 끝나는
    클래스 내의 모든 메소드는 트랜재션 처리가 된다.
     -->
    <aop:config><!-- execution(* *..service.impl.*ServiceImpl.*(..)) -->
        <aop:pointcut id="requiredTx" expression="execution(* com.devdic.board..*ServiceImpl.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="requiredTx" />
    </aop:config>
cs


3. myBatis 연동

 3.1  root-context.xml에 아래의 myBatis 연동 설정 정보 추가


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
<!--  Mybatis 연동
    pom.xml 추가
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.1</version>
    </dependency>
    
    마이바티스 스프링 연동 모듈
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.0</version>
    </dependency>
    -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- mybatis config파일 경로 지정 -->
        <property name="configLocation" value="/WEB-INF/config/mybatis-config.xml"/>
        
        <!-- SQL(mapper) 경로 지정 -->
        <property name="mapperLocations" value="classpath:sqlMap/**/*.xml"/>
    </bean>
    
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
          <constructor-arg ref="sqlSessionFactory" />
    </bean>
cs


3.2 WEB-INF -> config(폴더생성) -> mybatis-config.xml(파일 추가)

 - mybatis-config.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.2//EN" "HTTP://mybatis.org/dtd/mybatis-3-config.dtd">
 
<configuration>
    <settings>
        <setting name="cacheEnabled" value="false" />
        <setting name="useGeneratedKeys" value="true" />
        <setting name="defaultExecutorType" value="BATCH" />
        <setting name="jdbcTypeForNull" value="NULL" />
        <setting name="callSettersOnNulls" value="true" />
    </settings>
 
    <typeAliases>
        <typeAlias type="java.util.Map" alias="map"/>
    </typeAliases>
 
    <mappers>
    </mappers>
</configuration>
cs



4. 첨부파일 처리를 위한 multipartResolver 설정
  - root-context.xml 파일에 아래와 같이 추가합니다.
  - dependency 추가를 위한 정보는 주석부분을 참조하세요!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    <!-- MultipartResolver -->
    <!-- 
        <dependency>
            <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
     -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">   
<property name="maxUploadSize" value="50000000"></property>
    </bean>
 
cs


posted by 생각퍼즐
:
프로그래밍 2017. 2. 17. 02:30

공지사항 등록 화면 구현


1. 패키지 구성

1.1 jQuery 사용을 위한 디렉토리 생성

- webapp --> resources --> js(디렉토리 생성) --> common(디렉토리 생성)

- jQuery 사이트로 이동

- 아래 그럼의 다운로드 버튼 클릭



 - 아래 그림에서 처럼 동일한 버전에 여러가 타입의 jQuery를 제공하고 있습니다.

 - 소스 용량을 줄이기 위해서 저는 압축된 타입으로 다운로드 할게요~

"Download the compressed, production jQuery 3.1.1"

 - 다운로드된 파일을 webapp --> resources --> js --> common 아래로 이동합니다.


1.2 화면 디렉토리 생성

 - WEB-INF --> views --> notice 디렉토리 생성


1.3 소스 패키지 생성

 - 아래의 그럼처럼 Top-Level package 아래에 4개의 패키지를 추가합니다.



2. 공지사항 등록화면 구현

 - 화면 디렉토리로 생성된 "notice" 디렉토리 아래에 regNotice.jsp 파일을 생성

 - 아래의 소스코드를 참조하여 공지사항 등록화면을 구현하세요!

 - 첨부파일을 서버로 전송하기 위해서는 form 속성 중 "enctype"은 아래와 같이 반드시 "multipart/form-data"로 설정해야 합니다.


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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
 
<!-- jstl을 사용하기 위한 CDN 추가 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
 
<!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=UTF-8">
<title>Insert title here</title>
 
<!-- jQuery 사용을 위한 설정 -->
<script type="text/javascript" src='<c:url value="/resources/js/common/jquery-3.1.1.min.js"/>'></script>
 
<script type="text/javascript">
$(document).ready(function(){
 
    /*
        공지사항 목록화면으로 이동
    */
    $('#btn_list').click(function(){
        $("#frm").attr("action","<c:url value='/notice/noticeList.do'/>").submit();
    });
 
    /*
        첨부파일 추가를 위한 기능
    */
    $("#btn_file").click(function(){
        fn_openFileWindow();
        
    });
    
    /*
        첨부파일 제거를 위한 기능
    */
    $("#btn_del_file").click(function(){
        
        $("#attachFile").val("");
        $("#fileInfo").text("");
        $("#attFileNm").val("");
    });
    
    /*
        첨부된 파일정보 화면에 보여주기
    */
    $("#attachFile").change(function(){
        var fileList=this.files;
        var fileListSize=fileList.length;
        var strOption='';
        var fileNm = '';
     
        for(var i=0; i<fileListSize; i++){
            var file=fileList[i];
            var attFileNm=file.name;
            var fileSize=file.size;
     
            strOption+='<option>'+attFileNm+' ('+fileSize+' byte)'+'</option>';
            fileNm = attFileNm;
        }
     
        document.getElementById("fileInfo").innerHTML=strOption;
        document.getElementById("attFileNm").value=fileNm;
    });
    
    //전송버튼 클릭이벤트
    $("#btn_reg").click(function(){
        
       var noticeTitle = $("#noticeTitle").val();
       var bbsContent = $("#noticeContent").val();
 
       /*
               공지사항 필수 등록정보 유효성 확인
       */
       if(noticeTitle === ""){
           alert("공지사항 제목을 입력하세요!");
           $("#noticeTitle").focus();
           return false;
       }
       if(bbsContent === "<p>&nbsp;</p>"){
           alert("공지사항 내용을 입력하세요!");
           return false;
       }
       /*
               submit 수행
       */
       $("#frm").attr("action","<c:url value='/regNotice.do'/>").submit();
   });
    
});
 
function fn_openFileWindow(){
     frm.attachFile.click();
}
</script>
</head>
<body>
<h1>공지사항 등록</h1>
<form id="frm" name="frm" enctype="multipart/form-data" method="post" >
 
    <div>
        <table style="width:100%;">
             <colgroup>
                <col width="15%">
                <col width="*%"/>
            </colgroup
            <tbody>
                <tr>
                    <th scope="row"><span></span>제목</th>
                    <td style="padding-left:10px;"><input type="text" id="noticeTitle" name="noticeTitle" style="width:790px;"></td>
                </tr>
                <tr>
                        <th scope="row"><span></span>내용</th>
                        <td style="padding-left:10px;">
                        <textarea rows="5" cols="100" title="내용" id="noticeContent" name="noticeContent"  style="width:790px; height:200px;"></textarea>
                        </td>
                </tr>
                <tr>
                        <th scope="row">파일첨부</th>
                        <td style="padding-left:10px;">
                            
                            <div id="fileInfo" ></div>
                            <input type="file" id="attachFile" name="attachFile" style="display:none">
                            <input type="hidden" id="attFileNm" name="attFileNm" >
                            <!-- <input type="text" id="fileListLength" name="fileListLength"> -->
                            <div align="left">
                            <input type="button" id="btn_file"  style="text-align: center; width:120px;" value="파일찾기"/>
                            <input type="button" id="btn_del_file"  style="text-align: center; width:120px;" value="파일삭제"/>
                            </div>
                        </td>
                        
                </tr>
            </tbody>
        </table>
        </div>
        <div style="text-align: center; padding: 20px;">
            <input type="button" id="btn_reg"  style="text-align: center; width:100px;" value="저  장"  />
            <input type="button" id="btn_list" style="text-align: center; width:100px;" value="목  록"  />
       </div>
    </form>
 
</body>
</html>
cs


3. Controller 구현


 - 스프링 프로젝트를 만들 때 default로 생성된 HomeController 파일을 삭제하고 아래의 NoticeController 클래스를 하나 생성합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.devdic.board.controller;
 
import javax.servlet.http.HttpServletRequest;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller
public class NoticeController {
    
    private static final Logger logger = LoggerFactory.getLogger(NoticeController.class);
    
    @RequestMapping(value="/regNoticeView")
    public String regNoticeView(HttpServletRequest request) throws Throwable {
        
        return "/notice/regNotice";
    }
}
cs


http://localhost:8080/board/regNoticeView 요청 URL을 호출하면 아래와 같이 퍼브리싱이 되지않은 기본화면이 나타나면... NoticeController가 빈으로 성공적으로 등록되었으며, RequestMapping 설정도 성공~~~




 

posted by 생각퍼즐
:
물음표 & 느낌표/aphorism 2017. 2. 15. 23:29




쫓는자가 여유로울까?

쫓기는자가 여유로울까?


누굴 쫓고 누구에게 쫓기는걸까?

무엇을 쫓고 무엇에게 쫓기고 있나?

posted by 생각퍼즐
:
프로그래밍 2017. 2. 15. 00:07

스프링 환경설정


바로 코딩을 시작할 줄 알았는데...

또 환경설정을 해야되냐구요?

지금까지는 개발을 위한 환경구성에 초점이 맞춰졌다면, 이제는 웹과 스프링 프레임워크 사용을 위한 기본 설정파일에 대한 설정과 설명을 하고 개발로 넘어가야 할 것 같아서... 몇 가지 준비했습니다.


web.xml [배포 서술자 : (DD, Deployment Descriptor)]

웹 애플리케이션의 기본적인 설정을 기술하는 파일입니다.

기본적인 설정이라 함은 filter, listener, servlet, session 등을 설정하는 것입니다.


web.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
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
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 
 
    <!-- 웹 애플리케이션 이름 정의 -->
    <display-name>myapp</display-name>
    
    <!-- filter 설정 추가 -->
    <!-- filter : Client와 Servlet Containder 사이에서 HTTP 요청/응답을 변경할 수 있는 재사용 코드 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <!-- ContextLoaderListener가 사용할 설정파일 위치 변경 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param>
    
    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <!-- listener 설정 -->
    <!-- listener : 루트 웹 애플리케이션 컨텍스트를 등록할 때 사용
                    웹 애플리케이션의 시작과 종료 시 발생하는 이벤트를 처리하는 listener인
                    ServletContextListener를 구현한 ContextLoaderListener가 웹 애플리케이션이
                    시작될 때 root application context를 생성 및 초기화하고,
                    웹 애플리케이션이 종료될 때 context를 종료하는 기능을 담당한다.  -->
                    
    <!-- 별다른 설정을 하지 않고 아래처럼 listener를 정의하면 /WEB-INF/applicationContext.xml 파일을
         디폴트 설정파일로 사용한다.
         설정파일의 위치는 <context-param> 항목을 이용해 변경할 수 있다.
         위의 <context-param> 항목을 참조!  -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
 
    <!-- Processes application requests -->
    <!-- 서블릿 설정과 서블릿 애플리케이션 컨텍스트 등록 -->
    <!-- DispatcherServlet이 초기화될 때 자신만의 컨텍스트를 생성 및 초기화한다.
         그리고 웹 애플리케이션 레벨에 등록된 루트 웹 애플리케이션 컨텍스트를 찾아서
         자신의 부모 컨텍스트로 사용한다. -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- DispatcherServlet의 컨텍스트에 대한 디폴트 설정을 변경하고 싶다면
             아래와 같이 contextConfigLocation을 정의하여 경로를 설정하면 된다. -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
        
    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
 
</web-app>
 
cs



servelt-context.xml 설정과 설명(child context)


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
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="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">
 
    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
    
    <!-- Enables the Spring MVC @Controller programming model -->
     
     <!-- 
     1. RequestMappingHandlerMapping bean등록(기존 DefaultAnnotationHandlerMapping)
     2. RequestMappingHandlerAdapter bean등록(기존 AnnotationMethodHandlerAdapter) : customArgumentResolvers, customReturnValueHandlers 추가 가능
     3. JSR-303의 검증용 어노테이션(@Valid)를 사용할 수 있도록 LocalValidatorFactoryBean bean설정 (JSR-303지원 라이브러리 존재 시)
     4. RequestMappingHandlerAdapter의 messageConverters프로퍼티로 메시지 컨버터들 등록
     주의사항
     <mvc:annotation-driven>을 사용할 때는 직접 RequestMappingHandlerAdapter를 등록해주어서는 안되며 직접 등록이 필요한 경우에는 
     <mvc:annotation-driven>을 설정하지 않고 각각의 필요한 설정을 수동으로 해주어야 한다.
     -->
     <annotation-driven />
    
    <!-- @Controller, @Repository, @Service, @Component 스트레오타입 어노테이션이 선언된 클래스를 빈으로 등록한다. -->
     <context:component-scan base-package="com.devdic.board"/>
 
 
    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />
 
    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <!-- 
    InternalResourceViewResolver는 웹 어플리케이션 컨텍스트에 존재하는 템플릿에게 랜더링에 대한 책임을 위임하는
    View 객체를 논리적인 View 이름을 사용하여 결정한다.
    View 객체는 기본적으로 InternalResourceViewResolver이며, 이 객체는 실제 랜더링을 수행할 JSP에 단순히 요청을 전달하는 일을 한다.
    만약 JSTL 태그를 사용한다면 viewClass 특성을 설정함으로써 InternalResourceView를 JstlView로 대체하여 JstlView 요청을 JSP에 전달한다.
     -->
    <beans:bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    
    <!-- JSP파일 경로와 접미어 설정 -->
    <beans:property name="prefix" value="/WEB-INF/views/"/>
    <beans:property name="suffix" value=".jsp" />
    </beans:bean>
    
</beans:beans>
 
cs


root-context.xml 설정과 설명(parent context)

<context~> 항목을 사용하기 위해 네임스페이스를 추가하셔야 합니다.

아래코드에서 굵은 글씨로 된 부분을 추가하시면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="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">
    
    <!--  
        @Service, @Repository 스트레오타입 어노테이션이 선언된 클래스를 빈으로 등록한다.
    -->
     <context:component-scan base-package="com.devdic.board">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    
    <context:annotation-config/>
    
</beans>
cs


기본적인 설정은 어느정도 된것 같습니다.

DB연결을 위한 datasource, JDBC를 좀 더 쉽게 사용하기 위한 Mybatis연동, 논리적 작업단위의 Transaction 설정 등 몇가지가 남았지만...

잠시 뒤로 미루어두고 공지사항 등록 화면을 만들어보죠~~~

 

posted by 생각퍼즐
:
프로그래밍 2017. 2. 8. 00:50

게시판 만들기 - 스프링 프로젝트 생성


스프링 프로젝트 생성

이클립스 화면 왼쪽의 Project Explorer 창에서 마우스 오른쪽 버튼 클릭 --> New --> Project --> Spring --> Spring Legacy Project 선택 --> [Next] 버튼 클릭



Project name(myapp)을 입력하고, Templates를 "Spring MVC Project"로 선택 후 [Next] 버튼 클릭



Spring MVC Project에 필요한 것을 다운로드 할거냐? 라고 묻고있네요!

당연히 "Yes"를 선택합니다.



Top-Level package name을 입력하라고 하네요...

저는 아래와 같이 입력했습니다.(com.devdic.board)



이클립스가 프로젝트를 잘 만들고 있게죠? 믿고 기다리면 아래와 같은 웹 애플리케이션 구조를 가진 프로젝트가 하나 만들어지면 성공입니다^^



그리고 Local Repository로 설정한 경로에 스프링 프로젝트를 위한 각종 라이브러리가 다운로드 된것을 확인할 수 있습니다.



이제 Hello World 화면을 보기위한 마지막 단계인 Server를 추가해볼게요!


이클립스 화면 아래쪽에 보시면 아래 그림과 같은 여러개의 탭이 보일겁니다.

여러개의 탭중에 [Servers] 탭을 선택하시고, 아래의 create a new server...를 클릭하세요!



다음 그림과 같은 Tomcat 버전을 선택할 수 있는 창이 띄워집니다.

그러면 자신이 설치한 Tomcat 버전을 선택(저는 Tomcat v8.0을 선택)

그리고 [Next] 버튼을 클릭!



현재 생성된 웹 애플리케이션 목록이 왼쪽(Available)에 표시가 될겁니다.

tomcat에 추가할 웹 애플리케이션을 선택한 후 [Add] 버튼 클릭하면...

선택한 웹 애플리케이션이 오른쪽(Configured)으로 이동이 됩니다.

그리고 나서 역시 [Finish] 버튼을 클릭하면 tomcat(Web Server + WAS) 생성 및 웹 애플리케이션 추가가 완료됩니다.



Hellow World 화면을 만나기 전에 마직마으로 하나만 점검하고 넘어가죠~~


server.xml의 Context 설정과 web.xml의 Servlet 설정을 확인해야지만 어떤 URL로 호출하면 "Hello World" 화면을 만날 수 있는 지 알수가 있습니다.


1
2
<Context docBase="myapp" path="/board" reloadable="true" source="org.eclipse.jst.jee.server:myapp"/>
 
cs

[server.xml]


그리고 myapp 프로젝트 하위에 src > main >webapp > WEB-INF > web.xml의 Servlet 설정을 확인해보죠!


서블릿에 설정에 대한 설명을 [웹 환경의 이해1][웹 환경의 이해2]를 참고하세요!

여기서 확인할 내용은 <url-pattern> 부분입니다.

url-pattern의 설정은 여러가지 방법으로 할 수 있는데요..

확장자로 매핑하는 [*.do(확장자 지정)]  또는 모든 URL을 매핑하는[/*] 등의 패턴으로 설정할 수 있습니다.

여기서는 스프링 프로젝트를 생성하면 default로 설정된 [/]로 일단 처리하겠습니다.

 

"/"의 의미는 default servlet으로 처리된다는 말이다. 즉, tomcat에 미리 정의된 servlet mapping(*.jsp 및 *.jspx)을 통과한 URL을 처리하게 된다. 하지만, 스프링의 DispatcherServlet을 사용하면 정적 리소스 즉, jpg, png 등의 URL 호출 시 404 에러가 발생합니다. <mvc:default-servlet-handler /> 설정으로 해결하면 됩니다. 


일단 여기까지만 알고 빨리 Hello World 화면을 만나러 가죠~~~


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
        
    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
 
cs


스프링 프로젝트 생성 시 기본으로 생성된 HomeController의 내용입니다.

확인할 부분은 @RequestMapping(요청URL과의 매핑) 부분입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Controller
public class HomeController {
    
    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
    
    /**
     * Simply selects the home view to render by returning its name.
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(Locale locale, Model model) {
        logger.info("Welcome home! The client locale is {}.", locale);
        
        Date date = new Date();
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
        
        String formattedDate = dateFormat.format(date);
        
        model.addAttribute("serverTime", formattedDate );
        
        return "home";
    }
}
 
cs


위의 내용들을 종합해보면...

http://[IP Address][:PORT]/board로 시작되는 요청 URL은 myapp 웹 애플리케이션에서 처리하며, 요청을 처리하기 위한 Servlet을 찾기 위해 web.xml의 서블릿 설정을 확인 후 DispatcherServlet으로 요청정보를 전달하고 DispatcherServlet은 요청 URL과 매핑되는 Controller를 찾아 해당 메서드를 수행한다.


이클립스 화면 아래쪽에 추가된 tomcat 서버 마우스 우클릭하시면 아래와 같은 메뉴 창이 띄워집니다. 그러면 묻지도 말고 start 클릭!!!



서버가 start가 오류없이 성공했으면, 웹 브라우저를 열고 주소창에...

http://localhost:8080/board라고 치면 보고자 했던 Hello World 화면이 보여집니다.



이제 드디어 게시판(공지사항)을 만들 수 있는 준비는 완료되었습니다.


다음 시간부터는 본격적인 개발(코딩)을 시작하겠습니다.

posted by 생각퍼즐
:
프로그래밍 2017. 2. 7. 21:41

이클립스 환경설정 및 플러그인 설치


[웹 환경의 이해1]와 [웹 환경의 이해2]에서 집중적으로 다루었던 Application Tier에 필요한 SW(JDK, WAS)와 IDE 툴(Eclipse)를 설치했습니다.


본격적인 개발에 앞서 이클립스 환경설정과 각종 플러그인을 설치하도록 하겠습니다.


1. Encoding 설정


개발을 완료한 후에 인코딩을 변경하면 한글이 깨지는 등 예상치 못한 문제가 발생하므로 개발전에 인코딩을 설정하고 시작하는게 좋습니다.


인코딩은 다국어를 지원하는 "UTF-8"로 설정을 하는 방법을 설명드리겠습니다.


eclipse.ini 파일 수정

 - 이클립스가 설치된 폴더 아래의 eclipse.ini 파일에 아래와 같이 옵션을 추가합니다.



eclipse.exe를 실행하여 상단 메뉴의 

Window --> Preferences --> General --> Workspace 클릭

Text file encoding 부분의 Default 값이 UTF-8로 설정된 것을 확인할 수 있습니다.

eclipse.ini 파일의 옵션을 추가하지 않으면, MS949로 되어 있습니다.




WEB 및 XML 인코딩 설정

위의 Workspace 단위의 기본 인코딩 값을 확인 했으면

Window --> Preferences --> Web 하위의 CSS Files, HTML Files, JSP Files 

Window --> Preferences --> XML 하위의 XML Files 의 인코딩을 UTF-8로 설정합니다.

Apply --> OK로 마무리!!!



Workspace 단위로 파일의 인코딩을 UTF-8로 설정했는데...

위의 항목에 대한 인코딩을 UTF-8로 설정(확인)하는 이유는 JSP, HTML 등 위에서 언급한 파일들은 페이지 내에서 ecoding 정보를 설정할 수 있게 때문입니다.


아래의 소스코드는 이클립스에 설정된 JSP Template 입니다.

Window --> Preferences --> Web --> JSP Files 항목에 설정된 encoding 정보가 아래 소스코드의 ${encoding} 변수의 값으로 사용됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
<%@ page language="java" contentType="text/html; charset=${encoding}"
    pageEncoding="${encoding}"%>
<!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=${encoding}">
<title>Insert title here</title>
</head>
<body>
${cursor}
</body>
</html>
cs

 



2. JRE 설정(확인)

JDK를 성공적으로 잘 설치했으면, 아래의 그럼처럼 default JRE가 설정되어 있겠죠~

다른경로의 JRE를 사용하고 싶으시면, [Edit] 버튼을 클릭하셔서 JRE Home의 경로를 설정하시면 됩니다.





3. Tomcat 연동


Web Server와 Web Application Server(WAS) 역할을 수행할 Tomcat을 아래의 그럼처럼 이클립스와 연동을 합니다.

Window --> Preferences --> Server --> Runtime Environments 클릭

Tomcat directory를 자신이 설치한 경로로 설정합니다.



web application을 생성한 후에 서버를 추가하는 방법을 설명하겠습니다.


3. 플러그인 설치 : STS(Spring Tool Suite)


상단 메뉴의 Help --> Eclipse Marketplace 클릭하여 검색창에 "STS" 입력 후 Enter

[Install] 버튼을 클릭하여 설치 시작....



설치목록을 선택한다. (설치시간을 참을 수 있다면 그냥 All Select^^)



설치하시려면 무조건 동의해야 겠죠~~



설치시작...



설치가 완료되면 이클립스를 다시 시작 할까요?라고 물으면 "Yes" 선택

 


이클립스가 자동으로 다시 시작되고...

STS가 성공적으로 설치되었는지 확인을 하자! Welcome 페이지를 닫고...


이클립스 화면 왼쪽의 Project Explorer 창에서 마우스 오른쪽 버튼 클릭 --> New --> Project 선택하시면, 그동안 보이지 않았던 "Spring"이란 폴더가 생겼습니다.

그럼 STS 설치에 성공하신 겁니다~~~




4. maven 설정


이클립스 neon은 maven 플러그인이 설치된 상태로 배포되므로 따로 플로그인을 설치할 필요는 없습니다.


다만, 모든 환경구성 파일을 한 곳에서 관리한다는 정책을 지키기 위해 maven Repository를 devdic 하위로 설정하기 위한 설명을 하겠습니다.

별도로 설정하지 않으면, 사용자 > .m2 > repository입니다.


먼저 devdic 하위에 maven --> Repository 폴더를 생성합니다.



그리고 maven 폴더에 settings.xml 파일을 하나 만들고 아래의 내용을 추가합니다.

localRepository 부분의 경로는 자신의 폴더 구성에 맞게 수정하시면 됩니다.


1
2
3
4
5
6
7
8
9
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
 
  <localRepository>C:/devdic/maven/Repository</localRepository>
 
</settings>
 
cs


이클립스 상단 메뉴 Window --> Preferences --> Maven --> User Settings 선택

settings.xml 파일이 위치를 변경하고 [Update Settings] 버튼 클릭

마무리 아시죠? Apply --> OK~~~

그리고 settings.xml에 정의한Local Repository가 제대로 설정되었는지 확인한다.

참고로 Local Repository는 프로젝트 수행에 필요한 라이브러리 파일을 저장하는 곳입니다.




4. ETC 플로그인 및 Util


- SVN : 소스형상관리

- maven : 빌드 및 의존성 관리(이클립스 neon은 설치되어 있음)

- jQuery : 게시판(공지사항) 프로젝트를 진행하면서 필요할 때 설치방법 설명

- JSDT jQuery : jQuery 자동완성

- properties editor : 프로퍼티 파일 편집기

- notepadd++ : 개발자에게 필요한 울트라 에디터 및 에디터 플러스와 유사한 기능을 제                       공하는 프리웨어 에디터입니다.

시스템 개발 및 이클립스 사용에 필요한 플러그인이 많으며, 필요에 따라서 설치하면 되고, 여기서는 필요가 없어서 생략합니다.


그럼 이제 Spring 프로젝트 하나를 만들어 보시죠~~ GO!GO!GO!


posted by 생각퍼즐
: