Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
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
Archives
Today
Total
관리 메뉴

우리마의 웹 개발

[Spring]파일 업로드의 구현(1개의 파일) 본문

WEB/Spring

[Spring]파일 업로드의 구현(1개의 파일)

우리마 2020. 12. 4. 14:31

안녕하세요. 이번 글에서는 Spring환경에서 파일 업로드에 대해서 이야기하려고 해요.

웹 프로젝트에 있어서 파일 데이터의 전송은 상당히 많은 부분을 차지한다고 생각합니다.

오늘은 게시글에 대해서 하나의 파일 첨부만 구현 한 저의 로직을 소개하겠습니다. 차후에 다중 파일 업로드와 파일 다운로드 기능까지 추가로 올리도록 하겠습니다.

개발 환경
Spring Framework 5.2.3
Tomcat 8.0
DB MySql8 , MyBatis3.5
Browser Chrome
IDE STS 3.9.11

 

파일 관련 DB 테이블 구조

1. idx : 파일 첨부한 파일의 일련번호. (PK, 프라이머리 키) 파일을 관리하는 테이블에서 프라이머리 키는 매우 중요합니다. 프라이머리 키의 값을 가지고 첨부한 이미지의 썸 내일을 그리는 등 꼭 있어야 하는 요소입니다.

2. bbsidx : 파일 첨부판 게시글의 일련번호입니다.(FK, 게시글 테이블을 참조함) 어느 게시글에서 파일 첨부했는지를 나타내기 때문에 꼭 필요한 요소입니다.

 

 

의존성 추가 (pom.xml)
1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
 
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>
 
cs

 

MultipartResolver 설정
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
<?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 https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
 
    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
    
    <!-- Enables the Spring MVC @Controller programming model -->
    <annotation-driven />
 
    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<!--     <resources mapping="/favicon.ico" location="/favicon.ico"/> -->
    <resources mapping="/home/**" location="/home/" />
 
    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
        <beans:property name="contentType" value="text/html; charset=UTF-8"/>
    </beans:bean>
 
    <beans:bean id="loginInterceptor"
        class="com.myProject.training.interceptor.WebDevLoginCheckInterceptor" />
        
<!--     <beans:bean id="excelDownloadView" class="com.myProject.training.webDev.util.ExcelDownloadView"/> -->
<!--     <beans:bean id="jsonView" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/> -->
    <!-- MultipartResolver 설정 -->
    <beans:bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <beans:property name="maxUploadSize" value="100000000" />
        <beans:property name="maxInMemorySize" value="100000000" />
    </beans:bean>
    
    
    <context:component-scan base-package="com.myProject.training" />
    
    
    
</beans:beans>
 
cs

저는 Spring Legacy프로젝트 내에 servlet-context.xml파일에 MultipartResolver를 설정해 줬습니다.

눈여겨봐야 할부분은 32번째 라인부터 입니다. CommonsMultipartResolver는 스프링에서 파일 업로드 기능을 구현해놓은 클래스입니다.  maxUploadSize의 value를 100000000이라고 해놨는데 이는 서버에 업로드할 수 있는 첨부파일의 최대 크기를 의미합니다. 단위는 byte로 10MB로 설정해놨습니다. 이 Resolver덕분에 우리가 실제로 작성해야 할 부분이 많이 줄어듭니다.

 

여기까지 파일 업로드를 위해 설정하는 부분이 끝났습니다. 아래에는 JSP, Controller, SQL 등을 소개하겠습니다.

JSP
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
<form action="" id="communityInsert" name="communityInsert"onsubmit="return false;" method="post"enctype="multipart/form-data">
    <table>
        <thead>
            <tr>
                <th style="text-align: center; font-size: 18px;">제목
                    <em class="mlp20 mrp10" id="communitynoticeEm" style="font-size: 15px; color:#499bf0; ">공지사항</em>
                    <input type="checkbox" id="communitynotice" name="communitynotice">
                </th>
                <th>
                    <span class="title_guide" id="title_guide" style="display: none; position: absolute;"></span> 
                    <input type="text" name="title" id="title" placeholder="제목을 입력하세요." maxlength="80" style="width: 45%; height: 42px; font-size: 20px;">
                </th>
            </tr>
            <tr>
                <th style="text-align: center; font-size: 18px;">작성 날짜</th>
                <th>
                    <input type="text" name="regdate" id="regdate" value="${regDate}" style="width: 45%; height: 30px; font-size: 15px; background-color: #dedede;"disabled="true" />
                </th>
            </tr>
            <tr>
                <th style="text-align: center; font-size: 18px;">작성자</th>
                <th>
                    <input type="text" name="userid" id="userid" value="${userid}" style="width: 45%; height: 30px; font-size: 15px; background-color: #dedede; outline: none; cursor: default;"readOnly />
                </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td colspan="2">
                    <span class="content_guide" id="content_guide" style="display: none; position: absolute;"></span> 
                    <textarea name="content" id="content"></textarea>
                </td>
            </tr>
            <tr>
                <td style="text-align: center; font-size: 18px;">파일 첨부</td>
                <td>
                    <div class="attach">
                        <input type="file" id="file" name="file" class="filebox on">
                    </div>
                </td>
            </tr>
        </tbody>
    </table>
    <input type="hidden" id="bbsidx" name="bbsidx" value="${bbsidx}">
</form>
 
cs

게시글 작성하는 페이지의 form태그 안 부분입니다. 다 볼 필요 없고 중요한 부분은 1번째 줄의 from 태그 안의 속성 값들과 38번째 줄의 파일 첨부 input 태그, 그리고 44번째에 input type="hidden"으로 해당 게시글의 일련번호(bbsidx) 값 

 

1. form 태그 : enctype="multipart/form-data" 이 부분의 제일 중요합니다. form태그의 enctype 이란 form 태그 안의 데이터 가 서버로 제출될 때 해당 데이터가 인코딩 되는 방법을 명시합니다. 이 속성은 method="post"  속성과 꼭 같이 사용해야 합니다 (post 방식인 경우에만 사용할 수 있습니다.)

enctype의 값에는 여러 가지가 있지만 multipart/form-data는 모든 문자를 인코딩하지 않음을 명시합니다. 이 방식은 파일이나 이미지 등을 서버로 전송할 때 주로 사용합니다.

또한 저는 submit버튼을 사용하지 않았고, a태그로 ajax를 이용해 서버로 데이터를 전송하는 방식을 사용하였기 때문에 onsubmit="return false;" 속성을 같이 사용하였습니다.

 

2. bbsidx : 해당 게시글의 일련번호는 게시글 작성 페이지로 들어올 때 Controller에서 model로 값을 넘겨줍니다. 업로드한 파일을 DB에 저장할 때 bbsidx값이 필요하기 때문에 같이 form 안에 담아줍니다.

글 작성 function , ajax -> javascript
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
var btn_communityInsert = document.getElementById("btn_communityInsert");
btn_communityInsert.onclick = function(){ insertCommunity(); }
 
//글작성 ajax
function insertCommunity() {
    var title = $("#title").val();
    var content = $("#content").val();
    var isnotice = 1;
    if($("#communitynotice").is(':checked')){
        isnotice = 1;
    }
    else{
        isnotice = 0;
    }
 
    if (title == '' || title == null || content == ''
            || content == null) {
        Rnd.alert("필수항목을 입력하세요.""warning""확인"function() {
        });
    } else {
        $("#communityInsert").ajaxSubmit({
            type : "POST",
            url : "<c:url value='/insert'/>",
            data : {notice:isnotice, content:content},
            error : function(e) {
                Rnd.alert("통신 오류""error""확인"function() {
                });
            },
            success : function(resultCode) {
                if (resultCode == "0") {
                    Rnd.alert("파일 업로드 오류""error""확인"function() {
                    });
                } else if (resultCode == "1") {
                    Rnd.alert("등록 완료""success""확인"function() {
                        location.href = "/community"
                    });
 
                } else {
                    Rnd.alert("뜨면 안되는 오류""error""확인"function() {
                    });
                }
            }
        });
    }
}
 
cs

1.

var btn_communityInsert = document.getElementById("btn_communityInsert");

btn_communityInsert.onclick = function(){ insertCommunity(); }

이 부분은 '등록' 버튼 이벤트를 세팅하는 부분입니다.

버튼의 아이디가 btn_communityInsert입니다.

 

2. ajax로 /insert를 호출합니다. 이후 success 부분에서 resultCode는 Controller에서 sql오류, catch오류 정상 등록 등에 따라서 int형으로 return해준 값입니다.

Controller ( /insert )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//게시글 작성 insert
@RequestMapping("/insert")
@ResponseBody
public int insertBoard(@RequestParam Map<String,Object> commandMap
                    , MultipartHttpServletRequest multiRequest){
    logger.info("request: /insert");
    int resultCode = 0;
    int fileSuccess;
    int idx =0;
    String realContent = "";
    Map<String,Object> map = new HashMap<>();
    try {
        
        /* 생략 */
        fileSuccess = service.uploadFile(multiRequest, idx);
        /* 생략 */
        
    } catch (Exception e) {
        logger.debug(e.getMessage());
        resultCode = -1;
    }
    return resultCode;
}
 
cs

중요한 부분이 메서드의 파라미터로 MultipartHttpServletRequest multiRequest를 받아야 합니다. 일반 form안의 데이터는 @RequestParam으로 commandMap안에 담기지만 업로드한 파일은 MultipartHttpServletRequest객체로 받아야 합니다.

idx는 commandMap안에 있는 해당 게시글의 일련번호입니다. JSP에서 input type="hidden"으로 보낸 값입니다.

 

uploadFile 서비스는 fileSuccess라는 변수에 담는데 이는 파일 첨부가 있으면 1 없거나 에러가 나면 0을 return 합니다. uploadFile 서비스에 게시글 일련번호 값과 MultipartHttpServletRequest객체를 파라미터로 보내줍니다.

 

FileVO
1
2
3
4
5
6
7
8
9
public class FileVO {
    private int idx;
    private int bbsidx;
    private String filename;
    private String filepath;
    private String fileformat;
    private long filesize;
    private String regDate;
}
cs

FileVO라는 class를 하나 생성해줍니다. FileVO 인스턴스를 생성해서 getter/setter를 통해 값을 넣고 이 값을 DB에 저장할 겁니다. ( getter/setter , 생성자는 생략했습니다.) filesize는 단위가 byte로 입력되기 때문에 데이터 타입을 long으로 했습니다.

 

uploadFile (Service)
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
//파일 업로드
@Override
public int uploadFile(MultipartHttpServletRequest multiRequest, int idx) throws Exception {
    MultipartHttpServletRequest mptRequest = (MultipartHttpServletRequest) multiRequest;
    Iterator<String> fileIter = mptRequest.getFileNames();
    List<FileVO> fileList = new ArrayList<FileVO>();
    int fileSuccess = 0;
    try {
        int bbsidx = Integer.parseInt(multiRequest.getParameter("bbsidx").toString());
 
        String path = "/lsunguk/tomcat/webDev/file"// 본인이 upload한 파일을 저장하고 싶은
        
        while(fileIter.hasNext()) {
            
            MultipartFile mFile = mptRequest.getFile((String)fileIter.next());
            
            // 파일이 존재한다면
            if(mFile.getSize() > 0) {
                FileVO fileVO = new FileVO();
                
                String filename = mFile.getOriginalFilename();
                String fileformat = mFile.getContentType();
                long filesize = mFile.getSize();
                
                String filepath = path + "/" + bbsidx;
                
                FileUtil.uploadFile(mFile, filename, filepath);
                
                // VO에 파일 정보를 셋팅
                fileVO.setIdx(idx);
                fileVO.setBbsidx(bbsidx);
                fileVO.setFileformat(fileformat);
                fileVO.setFilename(filename);
                fileVO.setFilepath(filepath);
                fileVO.setFilesize(filesize);
 
                // fileList ArrayList 배열에 셋팅한 VO를 삽입
                fileList.add(fileVO);
                
                // map에 VO로 부터 파일 정보를 get해서 담아줌
                Map<String,Object> commandMap = new HashMap<String, Object>();
                commandMap.put("idx",fileVO.getIdx());
                commandMap.put("bbsidx", fileVO.getBbsidx());
                commandMap.put("fileformat",fileVO.getFileformat());
                commandMap.put("filename", fileVO.getFilename());
                commandMap.put("filepath",fileVO.getFilepath());
                commandMap.put("filesize",fileVO.getFilesize());
                try {
                    dao.uploadFile(commandMap);
                    File savefilePath = new File(filepath + "/" + filename);
                    if (savefilePath.exists()) {
                        fileSuccess = 1;
                    }
                    else {
                        fileSuccess = 0;
                    }
                }catch(Exception e) {
                    logger.info(e.getMessage());
                }
            }
        }
    }catch(Exception e) {
        logger.info(e.getMessage());
        if(fileList != null){
            for(int i=0; i<fileList.size(); i++){
                String delete_filename = (String) fileList.get(i).getFilename();    // 저장파일명
                String stordFilePath = (String) fileList.get(i).getFilepath();    // 저장경로
                File savefilePath = new File(stordFilePath + delete_filename);
                if (savefilePath.exists()) {
                    savefilePath.delete();
                }
            }
        }
        fileSuccess = 0;
    }
    return fileSuccess;
}
 
cs

드디어 파일 업로드 기능의 실질적인 부분입니다.

11번 라인의 path 변수에 본인이 원하는 file이 서버에 저장되는 위치를 적으면 됩니다. '/'로 시작하면 윈도에서는 C:\로 인십합니다. 쭉쭉쭉하다가 49번 라인에 dao를 타고 파일 정보를 DB에 저장합니다.

이 로직에서 본인이 필요한 정보만 가져다 쓰시면 될꺼같습니다. 중요한 부분은 

filename, filesize, filepath, fileformat 등 파일의 정보를 multiRequest에서 가져와서 27번 라인의 

FileUtil.uploadFile(mFile, filename, filepath); 이 부분으로 정확한 정보를 보내는 게 핵심입니다.

vo에 담은 정보는 다시 map에 담아서 DB에 저장합니다.

아래는 FileUtil.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
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
package com.myProject.training.webDev.util;
 
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.Map;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
 
public class FileUtil {
    
    private static final Logger logger = LoggerFactory.getLogger(FileUtil.class);
    
    public static final int BUFF_SIZE = 2048;
    
    /**
     * 파일을 실제 물리적인 경로에 생성한다. 
     *
     * @param file
     * @param newName
     * @param stordFilePath
     * @throws Exception
     */
    public static void uploadFile(MultipartFile file, String storedFileName, String storedFilePath) throws Exception {
        InputStream inputStream = null;
        OutputStream outputStream = null;
 
        try {
            inputStream = file.getInputStream();
            File cFile = new File(filePathBlackList(storedFilePath));
 
            if (!cFile.isDirectory()){
                //2017.03.03     조성원     시큐어코딩(ES)-부적절한 예외 처리[CWE-253, CWE-440, CWE-754]
                if (cFile.mkdirs()){
                    logger.debug("[file.mkdirs] saveFolder : Creation Success ");
                    /*
                     * if(EgovProperties.getProperty("Globals.OsType").equals("UNIX")) {
                     * Runtime.getRuntime().exec("chown -R msitweb:msit " + stordFilePath);
                     * Runtime.getRuntime().exec("chmod -R 775 " + stordFilePath);
                     * logger.debug("명렁어 실행됨 : chown -R msitweb:msit " + stordFilePath); }
                     */
                }else{
                    logger.error("[file.mkdirs] saveFolder : Creation Fail ");
                }
            }
 
            outputStream = new FileOutputStream(filePathBlackList(storedFilePath + File.separator + storedFileName));
 
            int bytesRead = 0;
            byte[] buffer = new byte[BUFF_SIZE];
 
            while ((bytesRead = inputStream.read(buffer, 0, BUFF_SIZE)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        } finally {
            close(outputStream, inputStream);
        }
//        if(EgovProperties.getProperty("Globals.OsType").equals("UNIX")) {
//            Runtime.getRuntime().exec("chown -R msitweb:msit " + stordFilePath + "/" + newName);
//            Runtime.getRuntime().exec("chmod -R 775 " +stordFilePath + "/" + newName);
//            logger.debug("명렁어 실행됨 : chown -R msitweb:msit " + stordFilePath + "/" + newName);
//        }
    }
 
    /**
     * 서버의 파일을 다운로드한다.
     *
     * @param request
     * @param response
     * @throws Exception
     */
    public static void downFile(HttpServletRequest request, HttpServletResponse response) throws Exception {
 
        String downFileName = "";
        String fileName = (String) request.getAttribute("filename");
 
        // 저장파일명을 추출하여 null 체크 및 값 변수에 할당
        if ((String) request.getAttribute("downFile"== null) {
            downFileName = "";
        } else {
            downFileName = (String) request.getAttribute("downFile");
        }
 
        // 저장파일명을 기반으로 파일 객체 생성
        File file = new File(filePathBlackList(downFileName));
 
        // 파일이 존재하는지 여부 체크
        if (!file.exists()) {
            throw new FileNotFoundException(downFileName);
        }
 
        // 파일 타입인지 체크
        if (!file.isFile()) {
            throw new FileNotFoundException(downFileName);
        }
 
        // 파일 bytes 크기 추출
        int fSize = (int) file.length();
 
        // 파일이 존재한다면
        if (fSize > 0) {
            BufferedInputStream in = new BufferedInputStream(
                    new FileInputStream(file));
            // String mimetype = servletContext.getMimeType(requestedFile);
            String mimetype = "application/octet-stream";
 
            response.setBufferSize(fSize);
            response.setContentType(mimetype);
            response.setHeader("Content-Disposition""attachment; filename=\""
                    + fileName + "\"");
            response.setContentLength(fSize);
 
            FileCopyUtils.copy(in, response.getOutputStream());    // copy 함수는 write()를 하기 위해 만들어놓은 함수이다.
            in.close();
 
            response.getOutputStream().flush();
            response.getOutputStream().close();
        } else {
            //setContentType을 프로젝트 환경에 맞추어 변경
            response.setContentType("application/x-msdownload");
            PrintWriter printwriter = response.getWriter();
            printwriter.println("<html>");
            printwriter.println("<br><br><br><h2>Could not get file name:<br>"
                    + fileName + "</h2>");
            printwriter
                    .println("<br><br><br><center><h3><a href='javascript: history.go(-1)'>Back</a></h3></center>");
            printwriter.println("<br><br><br>&copy; webAccess");
            printwriter.println("</html>");
            printwriter.flush();
            printwriter.close();
        }
 
    }
 
    
    public static String filePathBlackList(String value) {
        String returnValue = value;
        if (returnValue == null || returnValue.trim().equals("")) {
            return "";
        }
 
        returnValue = returnValue.replaceAll("\\.\\.""");
 
        return returnValue;
    }
    
    /**
     * Resource close 처리. 
     * @param resources
     */
    public static void close(Closeable  ... resources) {
        for (Closeable resource : resources) {
            if (resource != null) {
                try {
                    resource.close();
                } catch (IOException ignore) {
                    logger.error("[IOException] : Connection Close");
                } catch (Exception ignore) {
                    logger.error("["+ ignore.getClass() +"] Connection Close : " + ignore.getMessage());
                }
            }
        }
    }
    
    /**
     * 공통 컴포넌트 utl.fcc 패키지와 Dependency제거를 위해 내부 메서드로 추가 정의함
     * 응용어플리케이션에서 고유값을 사용하기 위해 시스템에서17자리의TIMESTAMP값을 구하는 기능 
     *
     * @param
     * @return Timestamp 값
     * @see
     */
    public static String getTimeStamp(String pattern) {
 
        String rtnStr = null;
        // 문자열로 변환하기 위한 패턴 설정(년도-월-일 시:분:초:초(자정이후 초))
 
        SimpleDateFormat sdfCurrent = new SimpleDateFormat(pattern, Locale.KOREA);
        Timestamp ts = new Timestamp(System.currentTimeMillis());
 
        rtnStr = sdfCurrent.format(ts.getTime());
 
        return rtnStr;
    }
    
    /**
     * 객체가 null인지 확인하고 null인 경우 "" 로 바꾸는 메서드
     * @param object 원본 객체
     * @return resultVal 문자열
     */
    public static String isNullToString(Object object) {
        String string = "";
 
        if (object != null) {
            string = object.toString().trim();
        }
 
        return string;
    }
 
    public static String removeCRLF(String parameter) {
         return parameter.replaceAll("\r""").replaceAll("\n""");
    }
}
 
 
cs

이렇게 까지 하면 JSP로 1을 return 하여 ajax의 success함수에서 정상적으로 글이 등록되었다는 문구가 뜰 것입니다.

 

다음에 다중 파일 첨부와 파일 다운로드 부분을 기재하겠습니다.

 

즐겁지 않은즐거운 코딩 하세요

 

Comments