728x90
300x250

[JSP] 25. jQuery와 Ajax 멀티 파일 업로드(개선), POST전송, JSON - 구성하기(2)


1부에 이어서 계속 소개하도록 하겠다.


1. [JSP] 24. jQuery와 Ajax 멀티 파일 업로드(개선), POST전송, JSON - 구성하기(1), 2020-10-03

https://yyman.tistory.com/1445



12. jQuery 다운받기


https://jquery.com/download/


사이트에 접속한다.



그림 19. jQuery 다운로드 사이트 (2020-10-03 현재 모습)


이 글에서는 "Download the uncompressed development jQuery 3.5.1"을 사용하였다.



그림 20. jQuery 다운로드 위치


1단계: 프로젝트 폴더를 찾는다.

2단계: /src/main/webapp/에 들어간다.

3단계: js폴더를 만든다.

4단계: /src/main/webapp/js/jquery-3.5.1.js를 넣어준다.




13. Controller - /board/ListJSONController.java


경로: /src/main/java/com/example/web/controller/board/ListJSONController.java


package com.example.web.controller.board;


import java.io.IOException;

import java.io.PrintWriter;

import java.util.ArrayList;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import org.json.JSONArray;

import org.json.JSONObject;


import com.example.web.controller.Controller;

import com.example.web.model.CompUsers;


public class ListJSONController implements Controller {


@Override

public void execute(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

// 1. 공통 선언

res.setCharacterEncoding("UTF-8");

        res.setContentType("application/json");

        

        // 1-1. ArrayList만 사용할 경우의 반응(방법 1)

        /*

        //  컬렉션 타입

        ArrayList<CompUsers> list = new ArrayList<CompUsers>();

        list.add(new CompUsers("user","mole", 1));

        list.add(new CompUsers("sumin", "pass", 0));

        list.add(new CompUsers("smkim", "php", 1));

      

        PrintWriter out = res.getWriter();


        // 

        JSONObject jsonList = new JSONObject();

        JSONArray itemList = new JSONArray();

        

        jsonList.put("list", list);

        

        out.println(jsonList);

        */

        

        // 1-2. ArrayList와 itemList(JSONArray) 적용

        JSONObject jsonList = new JSONObject();

        JSONArray itemList = new JSONArray();

        

        CompUsers reqUser = new CompUsers();

        

        if ( req.getParameter("username") != null) {

        reqUser.setUsername(req.getParameter("username"));

        System.out.println("참" + reqUser.getUsername());

        }

        

        if ( req.getParameter("password") != null)

        reqUser.setPassword(req.getParameter("password"));

        

        if ( req.getParameter("enanbled") != null)

        reqUser.setEnabled(Integer.valueOf( req.getParameter("enabled")) );

        

        PrintWriter out = res.getWriter();


        ArrayList<CompUsers> list = new ArrayList<CompUsers>();

        list.add(new CompUsers("user","mole", 1));

        list.add(new CompUsers("sumin", "pass", 0));

        list.add(new CompUsers("smkim", "php", 1));

        

        for (CompUsers user:list) {

       

        JSONObject node = new JSONObject();

        node.put("enabled", user.getEnabled());

        node.put("password", user.getPassword());

        node.put("username", user.getUsername());


        itemList.put(node);

        

        }

        

        jsonList.put("list", itemList);

        jsonList.put("command", "바둑이");

        

        // DTO(또는 Model) 단독으로 입력불가

        // jsonList.put("paramUser", reqUser);

        ArrayList<CompUsers> list2 = new ArrayList<CompUsers>();

        list2.add(reqUser);

        //jsonList.put("paramUser", reqUser);

        jsonList.put("paramUser", list2);

        

        out.println(jsonList);

        

        out.flush();

        out.close();


}


}



파일명: ListJSONController.java


[첨부(Attachments)]

ListJSONController.zip




14. Controller - /board/MultiUploadController.java


경로: /src/main/java/com/example/web/controller/board/MultiUploadController.java


package com.example.web.controller.board;


import java.io.IOException;

import java.io.PrintWriter;

import java.util.List;

import java.util.Map;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.example.web.controller.Controller;

import com.example.web.util.HttpUtil;


public class MultiUploadController implements Controller {


@Override

public void execute(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

HttpUtil.uploadFile(req, res);

/*

res.setCharacterEncoding("UTF-8");

        res.setContentType("application/json");

        

        @SuppressWarnings("unchecked")

List<Object> fileInfoList = (List<Object>) req.getAttribute("fileInfoList");

        @SuppressWarnings("unchecked")

List<String> reqInfoList = (List<String>) req.getAttribute("reqInfoList");

        

        // Model 구성해서 만들어도 무방

        HttpUtil.getFileinfoParser(fileInfoList, null);

        HttpUtil.getReqinfoParser(reqInfoList, null);

*/


res.setCharacterEncoding("UTF-8");

PrintWriter out = res.getWriter();

out.print("success");

out.flush();

out.close();

}


}



파일명: MultiUploadController.java


[첨부(Attachments)]

MultiUploadController.zip




14. View 화면 구성하기 - index.jsp (index.do 파일 시작페이지 만들기)


Index.jsp 파일을 시작페이지로 만드는 작업이다.


경로: /src/main/webapp/index.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<jsp:forward page="index.do" />


파일명: index.jsp


[첨부(Attachments)]

index.zip


FrontController.java 파일에 index.do를 command에서 식별할 수 있도록 해준다.

그리고 forward로 redirect처리하여 시작페이지로 보여지게 하는 원리이다.


-> 연계 작업: web.xml, FrontController.java 변경 작업을 해줘야 한다.



그림 21. index.jsp의 위치



15. View - /webapp/WEB-INF/views/index.jsp - 실제 시작 페이지


경로: /src/main/webapp/WEB-INF/views/index.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

</head>

<body>


</body>

</html>


파일명: index.jsp


[첨부(Attachments)]

index.zip





16. Controller(Servlet) - FrontController


경로: /src/main/java/com/example/web/controller/FrontController.java


package com.example.web.controller;


import java.io.IOException;


import javax.servlet.ServletConfig;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import org.json.JSONArray;

import org.json.JSONObject;


import com.example.web.controller.board.InsertController;

import com.example.web.controller.board.ListJSONController;

import com.example.web.controller.board.MultiUploadController;

import com.example.web.util.HttpUtil;


public class FrontController extends HttpServlet {

private static final long serialVersionUID = 1L;

private String charset = null;

       

protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

doAction(req, res, "GET");

}


protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

doAction(req, res, "POST");

}


protected void doAction(HttpServletRequest req, 

HttpServletResponse res,

String flag) 

throws ServletException, IOException {

ServletConfig sc = this.getServletConfig();

charset = sc.getInitParameter("charset");


req.setAttribute("charset", charset);

req.setCharacterEncoding(charset);

res.setContentType("text/html; charset=" + charset);


String uri = req.getRequestURI();

String conPath = req.getContextPath();

String command = uri.substring(conPath.length());


Controller subController = null;


// GET 전송방식만

if(command.equals("/board/write.do") &&

flag.contentEquals("GET")) {

System.out.println("write - page");

System.out.println("----------------");

HttpUtil.forward(req, res, "/WEB-INF/views/board/insert.jsp");

}

// POST 전송방식만

else if(command.equals("/board/write_result.do") && 

flag.contentEquals("POST")){


System.out.println("write - result");

System.out.println("----------------");

subController = new InsertController();

subController.execute(req, res);

}

else if(command.equals("/board/list_json.do") &&

flag.contentEquals("POST")) {

System.out.println("write - result");

System.out.println("----------------");

subController = new ListJSONController();

subController.execute(req, res);

}

else if(command.equals("/board/upload.do") &&

flag.contentEquals("POST")) {

System.out.println("multipart/form - upload");

System.out.println("----------------");

subController = new MultiUploadController();

subController.execute(req, res);

}

else if (command.equals("/index.do")){


System.out.println("index.do");

System.out.println("----------------");

HttpUtil.forward(req, res, "/WEB-INF/views/index.jsp");

}

}

}



파일명: FrontController.java


[첨부(Attachments)]

FrontController.zip





17. View - /board/insert.jsp


경로: /src/main/webapp/WEB-INF/views/board/insert.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>jQuery.post demo</title>

<script src="../js/jquery-3.5.1.js"></script>

<script>

$(document).ready(function(){


// 1. Ajax - Post 결과 출력

$( "#searchForm" ).submit(function( event ) {

 

  // Stop form from submitting normally

  event.preventDefault();

 

// Get some values from elements on the page:

  var $form = $( this ),

    term = $form.find( "input[name='s']" ).val(),

    url = $form.attr( "action" );

 

  // Send the data using post

  var posting = $.post( url, { s: term } );

 

  // Put the results in a div

  posting.done(function( data ) {

    alert( "Data Loaded: " + data );

    var content = data ;

    $( "#result1" ).html( content );

   

});

// Attach a submit handler to the form

});

// 2. Ajax 버튼(수작업 쿼리 - 보내기)

$('#check').click(function(){

    alert('특정 파라메터 보내기\n------------');

var query = {username:'한글', password:1234, enabled:1};

   

    $.ajax({

    url : "list_json.do",

    type : "POST",

    dataType : "json",

    data : jQuery.param(query),

    success : function(data) {

    $.each(data, function(key, value) { //  { logList:[{}], command:{} } 이런구조임


        //alert('성공');

    if (key == "list") {

       

    for (var i = 0; i < value.length; i++) {

       

    // alert(value[i].username);

   

    }

   

    } else if (key == "command") {

       

    $('#result2').html(value);

   

    }else if(key=="paramUser"){


// ArrayList로 받아서 처리함.

    alert(value[0].username + "/" + value.username);


// 인식 여부 (ArrayList로 안 하면, 알수없는 객체로 인식함)

/*

    for (var i = 0; i < value.length; i++) {

    alert(i + "/" + value[i].username);

    }

    */

        } // end of if

   

    });

   

    },

    error : function(msg) {

    alert("error" + msg);

    }

    });

   

});


// 4. 다중 업로드 기능

$(function(){

 

    $('#uploadBtn').on('click', function(){

        uploadFile();

    });

 

});

 

function uploadFile(){

    

    var form = $('#uploadForm')[0];

    var formData = new FormData(form);

 

    $.ajax({

        url : 'upload.do',

        type : 'POST',

        data : formData,

        contentType : false,

        processData : false,

    success : function(data) {

alert('성공');

alert(data);

    },

    error : function(msg) {

    alert("error" + msg);

    }

        

    }).done(function(data){

        callback(data);

    });

}

});

</script>

</head>

<body>

 

 <h3>Ajax - 전송</h3>

<form action="write_result.do" id="searchForm">

  <input type="text" name="s" placeholder="Search...">

  <input type="submit" value="Search">

</form>

<div id="result1"></div>


<h3>JSON 전송 확인(jQuery 미적용)</h3>

<form action="list_json.do" method="POST">

  <input type="text" name="keyword" placeholder="Search...">

  <input type="submit" value="Search">

</form>


<h3>JSON 가져오기(jQuery 적용)</h3>

<label for="userid">USER ID</label>

<input type="text" id="userid">

<button id="check">버튼 누르기</button>

<p id="result2"></p>


<h3>Ajax 기반 - 다중 업로드</h3>

<form id="uploadForm" enctype="multipart/form-data">

<input type="hidden" name="token" value="2">

<input type="text" name="usrID" size="10">

<input type="file" name="uploadFile" multiple>

    <button type="button" id="uploadBtn">Save</button>

</form>

 

</body>

</html>


파일명: insert.jsp


[첨부(Attachments)]

insert.zip




18. View - /board/result.jsp


경로: /src/main/webapp/WEB-INF/views/board/result.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<%

String text = (String)request.getParameter("s");

%>

<%= text %>


파일명: result.jsp


[첨부(Attachments)]

result.zip




19. View - /board/uploadResult.jsp


경로: /src/main/webapp/WEB-INF/views/board/uploadResult.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<%@ page import="java.util.*" %>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>업로드 - 결과</title>

</head>

<body>

<h3>업로드 결과</h3>

<%


//Object name = request.getAttribute("usrID");

//Object login = request.getAttribute("login");

Object obj = request.getAttribute("reqMap");

Map<String, Object> map = null;

if(obj != null){

map = (HashMap<String, Object>)obj;

}


%>


<table style="width:700px;border:1px solid #e2e2e2;">

<tr>

<td style="width:20%;">

<%

        out.println("name : " + map.get("usrID") + "<br />");

%>

</td>

<td style="width:20%;border-left:1px solid #e2e2e2;">

<%

out.println("login : " + map.get("usrPasswd") + "<br />");

%>

</td>

</tr>

<tr>

<td>

</td>

<td>

</td>

</tr>

</table>


</body>

</html>


파일명: uploadResult.jsp


[첨부(Attachments)]

uploadResult.zip





* 맺음글(Conclusion)


jQuery, Ajax, 멀티 파일 업로드, POST 전송, JSON 구성에 대해서 살펴보았다.



* 참고 자료(References)


1. jsp json 데이터 받기, https://happy-hs.tistory.com/16, Accessed by 2020-10-03, Last Modified 2018-09-20.

2. [Java] JSP - JSON 데이터 주고 받기 - JSONParser, https://kiwinam.com/posts/11/jsp-json-parser/, Accessed by 2020-10-03, Last Modified 2017-05-03.

3. jQuery.post() | jQuery API Documentation, https://api.jquery.com/jquery.post/, Accessed by 2020-10-03, Last Modified .

4. [Servlet] JSON 문자열로 응답하기, https://noritersand.github.io/servlet/servlet-json-%EB%AC%B8%EC%9E%90%EC%97%B4%EB%A1%9C-%EC%9D%91%EB%8B%B5%ED%95%98%EA%B8%B0/, Accessed by 2020-10-03, Last Modified 2014-01-14.

5. Java File Upload Example with Servlet, JSP and Apache Commons FileUpload, https://www.codejava.net/java-ee/servlet/apache-commons-fileupload-example-with-servlet-and-jsp, Accessed by 2020-10-03, Last Modified 2019-06-25.

반응형
728x90
300x250

[JSP] 24. jQuery와 Ajax 멀티 파일 업로드(개선), POST전송, JSON - 구성하기(1)


이번에 게시할 프로젝트는 jQuery, Ajax, 파일 업로드, POST전송, JSON 구성하기라는 거창한 제목이긴 하지만, 실제로는 기능별로 분리하여 작업한 결과이다.

이 글은 기존에 게시글에서 작성한 업로드 기능에 "토큰 인증 방식", "파라메터 문자열 분석 및 분리" 등의 기능을 추가하였다.

아무래도 업로드 기능이니깐 그냥 업로드 하는 것보다는 토큰 하나 넣어주는 게 좋지 않겠냐는 생각이다.


1. [JSP] 12. Jsp/Servlet(MVC) Maven 기반의 다중 파일 업로드, 다운로드 구현(1), 2020-09-24

https://yyman.tistory.com/1414

2. [JSP] 13. Jsp/Servlet(MVC) Maven 기반의 다중 파일 업로드, 다운로드 구현(2), 2020-09-24
https://yyman.tistory.com/1415

3. [JSP] 21. Jsp/Servlet(MVC) Maven 기반의 다중 업로드, 다운로드, 삭제 구현(1), 2020-10-01

https://yyman.tistory.com/1436




그림 1. COS(Servlet)


이거는 오래되서 미지원이다. (일부 인터넷 글에 따르면, 사용중이더라 이런 글들이 있는데 태스트를 해본 바로는 오류가 발생하고 안 된다.

(구체적으로 servlet 패키지에서 충돌남)


* IDE: Spring Tool-Suite 4.4 4-4.7.2. RELEASE (Eclipse)

* MVN(pom.xml)

   - javax.servlet-api 4.0.1 (https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api)

   - json - 20200518 (https://mvnrepository.com/artifact/org.json/json)

   - commons-io - 2.8.0 (https://mvnrepository.com/artifact/commons-io/commons-io)

   - commons-fileupload - 1.4 (https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload)

* Javascript: jquery-3.5.1.js


DB 자체를 제거했으며, 이해를 돕기 위해서 매우 순수한 구조로 작성되었다.


자료구조에서 LinkedList에 해당하는 자바의 ArrayList와 Map를 파일 업로드 부분에 적용하였음.



1. 결과


이번에 만들 작업에 관한 결과이다. 결과를 보고 무엇을 만들지 생각하는 방법을 터득했으면 좋겠다.



그림 1. 작업 결과



그림 2. 작업 결과 - 출력된 HTML 소스(1)



그림 3. 작업 결과 - 출력된 HTML 소스(2)



그림 4. 작업 결과(2) - ListJSONController.java



그림 5. 작업결과(3) - 파일 업로드 기능(1)



그림 6. 작업결과(4) - 파일 업로드 기능(2)



그림 6-1. JSON - 결과(1)



그림 6-2. JSON - 결과(2)



그림 6-3. JSON - 결과(3)



그림 6-4. JSON - 결과(4)




2. 프로젝트 구성도


만들어야 할 프로그램들이다. 조금 양이 많다.



그림 7. 프로젝트 구성




3. 프로젝트 생성


프로젝트 생성하는 방법에 대해서 소개하도록 하겠다.



그림 8. 프로젝트 생성하기(1)


File을 누른다.

New-> Maven Project를 클릭한다.

(1단계 중략 - Next만 눌러도 되는 부분)



그림 9. 프로젝트 생성하기(2)


webapp를 검색한다.

org.apache.maven.archetypes    |  maven-archetype-webapp  1.4을 선택한다.

Next를 누른다.



그림 10. 프로젝트 생성하기(3)


Group Id와 Artifact Id를 입력한다.

Finish를 누른다.



4. 프로젝트 속성 - Build Path, Project Factes 설정하기


자바 버전을 변경할 것이다.



그림 11. 프로젝트 선택 후의 마우스 오른쪽 버튼 메뉴


프로젝트를 선택한 후, 마우스 오른쪽 버튼으로 클릭한다.

Properties를 클릭한다.



그림 12. Java Build Path


Java Build Path를 클릭한다.

JRE System Library 버전을 14로 바꿔준다. [Edit 클릭 -> JRE -> Java SE -14]




그림 13. Project Factes


Project Factes를 클릭한다.

Java의 버전을 14로 바꿔준다.



5. pom.xml 수정하기


pom.xml 수정에 관한 것이다.


<?xml version="1.0" encoding="UTF-8"?>


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>


  <groupId>com.webedu</groupId>

  <artifactId>exampleAjax</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  <packaging>war</packaging>


  <name>exampleAjax Maven Webapp</name>

  <!-- FIXME change it to the project's website -->

  <url>http://www.example.com</url>


  <properties>

    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    <maven.compiler.source>1.7</maven.compiler.source>

    <maven.compiler.target>1.7</maven.compiler.target>

  </properties>


  <dependencies>

    <dependency>

      <groupId>junit</groupId>

      <artifactId>junit</artifactId>

      <version>4.11</version>

      <scope>test</scope>

    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->

<dependency>

    <groupId>javax.servlet</groupId>

    <artifactId>javax.servlet-api</artifactId>

    <version>4.0.1</version>

    <scope>provided</scope>

</dependency>

<!-- https://mvnrepository.com/artifact/org.json/json -->

<dependency>

    <groupId>org.json</groupId>

    <artifactId>json</artifactId>

    <version>20200518</version>

</dependency>

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->

<dependency>

    <groupId>commons-io</groupId>

    <artifactId>commons-io</artifactId>

    <version>2.8.0</version>

</dependency>

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->

<dependency>

    <groupId>commons-fileupload</groupId>

    <artifactId>commons-fileupload</artifactId>

    <version>1.4</version>

</dependency>

  </dependencies>


  <build>

    <finalName>exampleAjax</finalName>

    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->

      <plugins>

        <plugin>

          <artifactId>maven-clean-plugin</artifactId>

          <version>3.1.0</version>

        </plugin>

        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->

        <plugin>

          <artifactId>maven-resources-plugin</artifactId>

          <version>3.0.2</version>

        </plugin>

        <plugin>

          <artifactId>maven-compiler-plugin</artifactId>

          <version>3.8.0</version>

        </plugin>

        <plugin>

          <artifactId>maven-surefire-plugin</artifactId>

          <version>2.22.1</version>

        </plugin>

        <plugin>

          <artifactId>maven-war-plugin</artifactId>

          <version>3.2.2</version>

        </plugin>

        <plugin>

          <artifactId>maven-install-plugin</artifactId>

          <version>2.5.2</version>

        </plugin>

        <plugin>

          <artifactId>maven-deploy-plugin</artifactId>

          <version>2.8.2</version>

        </plugin>

      </plugins>

    </pluginManagement>

  </build>

</project>



파일명: pom.xml


[첨부(Attachments)]

pom.zip



6. Servlet 생성하기


서블렛 생성에 대한 것이다.



그림 14. Java Resources 폴더의 마우스 오른쪽 버튼 모습


Java Resources를 마우스 오른쪽 버튼으로 클릭한다.

New->Servlet을 클릭한다.



그림 15. Create Servlet


Java package를 입력해준다. (예: com.example.web.controller)

Class Name을 입력해준다. (예: FrontController)


Finish를 누른다.




7. Web.xml 수정하기


경로: /src/main/webapp/WEB-INF/web.xml


<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xmlns="http://java.sun.com/xml/ns/javaee" 

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 

id="WebApp_ID" version="3.0">

  <display-name>Archetype Created Web Application</display-name>

  <welcome-file-list>

  <welcome-file>index.jsp</welcome-file>

  </welcome-file-list>

  <servlet>

  <servlet-name>FrontController</servlet-name>

  <servlet-class>com.example.web.controller.FrontController</servlet-class>

  <init-param>

<param-name>charset</param-name>

<param-value>UTF-8</param-value>

</init-param>

  </servlet>

  <servlet-mapping>

  <servlet-name>FrontController</servlet-name>

  <url-pattern>*.do</url-pattern>

  </servlet-mapping>

</web-app>


파일명: web.xml


[첨부(Attachments)]

web.zip



8. Controller - Interface 생성하기


경로: /src/main/java/com/example/web/controller/Controller.java


package com.example.web.controller;


import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


public interface Controller {


public void execute(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException;


}




파일명: Controller.java


[첨부(Attachments)]

Controller.zip



9. Controller - board/InsertController.java


경로: /src/main/java/com/example/web/controller/board/InsertController.java


package com.example.web.controller.board;


import java.io.IOException;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.example.web.controller.Controller;

import com.example.web.util.HttpUtil;


public class InsertController implements Controller {


@Override

public void execute(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

HttpUtil.forward(req, res, "/WEB-INF/views/board/result.jsp");


}


}


파일명: InsertController.java


[첨부(Attachments)]

InsertController.zip




10. Util - util/HttpUtil.java (업로드 개선 및 문자열 구분 처리)


토큰, 업로드 개선, 문자열 구분 처리 등을 추가적으로 담아보았다.


경로: /src/main/java/com/example/web/util/HttpUtil.java


package com.example.web.util;


import java.io.File;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Iterator;

import java.util.List;

import java.util.Map;


import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import org.apache.commons.fileupload.FileItem;

import org.apache.commons.fileupload.disk.DiskFileItemFactory;

import org.apache.commons.fileupload.servlet.ServletFileUpload;


public class HttpUtil extends HttpServlet {


private static final long serialVersionUID = 1L;


private static String charset = null; // 문자열


    private static final int MEMORY_THRESHOLD   = 1024 * 1024 * 3;  // 3MB // 

    private static final long MAX_FILE_SIZE      = 1024 * 1024 * 40; // 40MB

    private static final long MAX_REQUEST_SIZE   = 1024 * 1024 * 50; // 50MB

 

private static String UPLOAD_FOLDER = "upload";

private static String UPLOAD_TMP_FOLDER = File.separator + "WEB-INF" + File.separator + "temp";

private static List<String> reqInfoList = null; // req 정보(MultiRequest) - 문맥 방식

private static List<Object> fileInfoList = null; // 다중 파일 지원 - 문맥 방식

private static Map<String, Object> reqInfoMap = null; // req 정보(MultiRequest) - Map 자료구조

private static Map<Integer, Map<String, Object>> fileInfoMap = null; // 다중 파일 지원 - Map 자료구조

private static boolean FILE_TOKEN_CHECK = false; // req 토큰 체크하기 

private static String FILE_AUTH_TOKEN_KEY = null; // req 인증키 추가

private static String FILE_RESTRICT_EXT = ".jpg.jpeg.bmp.png.gif.txt"; // 파일 확장자 제한

private static int reqNum = 0; // reqNum

private static int fileNum = 0; // fileNum


public static void forward(HttpServletRequest req, HttpServletResponse res,

String path) throws ServletException, IOException {


try {

RequestDispatcher dispatcher = req.getRequestDispatcher(path);

dispatcher.forward(req, res);


}catch(Exception e) {

e.printStackTrace();

}

}

public static void uploadFile(HttpServletRequest req, HttpServletResponse res) throws

ServletException, IOException {


reqInfoList = new ArrayList<String>();

fileInfoList = new ArrayList<Object>();


fileInfoMap = new HashMap<Integer, Map<String, Object>>(); 

reqInfoMap = new HashMap<>();

// 파일 인증키 인증 완료 후 업로드

List<FileItem> tmpItems = new ArrayList<FileItem>();

FILE_AUTH_TOKEN_KEY = "1";

reqNum = 1;

fileNum = 1;

    

    PrintWriter out = res.getWriter();

    //out.println("<HTML><HEAD><TITLE>Multipart Test</TITLE></HEAD><BODY>");

try {

        

        //디스크상의 프로젝트 실제 경로얻기

        //String contextRootPath = "c:" + File.separator + "upload";

String dirName = UPLOAD_FOLDER ; 

// String dirName = "upload"; 

String contextRootPath = req.getSession().getServletContext().getRealPath("/") + dirName;

        System.out.println("실제경로:" + contextRootPath);

        

        //1. 메모리나 파일로 업로드 파일 보관하는 FileItem의 Factory 설정

        DiskFileItemFactory diskFactory = new DiskFileItemFactory(); // 디스크 파일 아이템 공장

        diskFactory.setSizeThreshold(MEMORY_THRESHOLD); // 업로드시 사용할 임시 메모리

        // diskFactory.setSizeThreshold(4096); // 업로드시 사용할 임시 메모리

        diskFactory.setRepository(new File(contextRootPath + UPLOAD_TMP_FOLDER)); // 임시저장폴더

        // diskFactory.setRepository(new File(contextRootPath + UPLOAD_TMP_FOLDER)); // 임시저장폴더

        

        //2. 업로드 요청을 처리하는 ServletFileUpload생성

        ServletFileUpload upload = new ServletFileUpload(diskFactory);

        // upload.setSizeMax(3 * 1024 * 1024); //3MB : 전체 최대 업로드 파일 크기

        upload.setSizeMax(MAX_REQUEST_SIZE);

        

        // sets maximum size of upload file(파일 단위 업로드 크기)

        upload.setFileSizeMax(MAX_FILE_SIZE);

        

        //3. 업로드 요청파싱해서 FileItem 목록구함​​

        List<FileItem> items = upload.parseRequest(req); 

        Iterator<FileItem> iter = items.iterator(); //반복자(Iterator)로 받기​            

        while(iter.hasNext()) { //반목문으로 처리​    

            FileItem item = (FileItem) iter.next(); //아이템 얻기

             //4. FileItem이 폼 입력 항목인지 여부에 따라 알맞은 처리

            

            if(item.isFormField()){ 

            //파일이 아닌경우

                processFormField(out, item);

                

            } else {

            //파일인 경우

            // System.out.println("오류:" + item.getName());

           

            // 버그 개선 item 이름값 비어있을 때

            if ( item.getName() != "") {

            tmpItems.add(item);

            // processUploadFile(out, item, contextRootPath);

            }

            // System.out.println("오류2:");

            }

        }

        

        // 파일 토큰 확인될 경우

        if ( FILE_TOKEN_CHECK ) {

       

        // 파일 업로드 처리

        for (FileItem readyItem: tmpItems)

        {

        processUploadFile(out, readyItem, contextRootPath);

        }

       

        }

        

        

        

    } catch(Exception e) {

        e.printStackTrace(out);

    }

//out.println( "usrID(Map): " + reqMap.get("usrID") );

//out.println( "usrPasswd(Map):" + reqMap.get("usrPasswd") );

    

    // out.println("</BODY></HTML>");

// req.setAttribute("usrID", reqMap.get("usrID"));

// req.setAttribute("login", 1);//Object Type으로 넘어감

    req.setAttribute("reqInfoMap", reqInfoMap);

    req.setAttribute("fileInfoMap", fileInfoMap);

    req.setAttribute("reqInfoList", reqInfoList);

    req.setAttribute("fileInfoList", fileInfoList);

    

// System.out.println("오류3:" + reqMap.get("usrID"));

    

}

//업로드한 정보가 파일인경우 처리

private static void processUploadFile(PrintWriter out, FileItem item, String contextRootPath)

throws Exception {

Map<String, Object> fileMapNode = new HashMap<String, Object>();

List<String> fileListNode = new ArrayList<String>();

boolean resultUpload = false;

String dirName = UPLOAD_FOLDER ; 

String name = item.getFieldName(); // 파일의 필드 이름 얻기

String fileName = item.getName(); // 파일명 얻기

// 임시 - 실제 원본 이름 추출

File originalFile = new File(fileName);

String originalFileName = originalFile.getName();

System.out.println("임시:" + originalFileName );

String contentType = item.getContentType(); // 컨텐츠 타입 얻기

long fileSize = item.getSize(); // 파일의 크기 얻기

// 업로드 파일명을 현재시간으로 변경후 저장

String fileExt = fileName.substring(fileName.lastIndexOf("."));

String uploadedFileName = System.currentTimeMillis() + ""; 

System.out.println(fileExt);

System.out.println(uploadedFileName);

// 저장할 절대 경로로 파일 객체 생성

String realUploadFile = File.separator + dirName + File.separator + uploadedFileName;

System.out.println("실제 저장직전폴더:" + contextRootPath + realUploadFile);

File uploadedFile = new File(contextRootPath + realUploadFile);

if ( FILE_RESTRICT_EXT.contains(fileExt.toLowerCase()) ) {

item.write(uploadedFile); // 파일 저장

resultUpload = true; // 파일 업로드 완료

}

//========== 뷰단에 출력 =========//

//out.println("<P>");

//out.println("파라미터 이름:" + name + "<BR>");

//out.println("파일 이름:" + fileName + "<BR>");

//out.println("콘텐츠 타입:" + contentType + "<BR>");

//out.println("파일 사이즈:" + fileSize + "<BR>");

//확장자가 이미지인겨우 이미지 출력

/*

if(".jpg.jpeg.bmp.png.gif".contains(fileExt.toLowerCase())) {

out.println("<IMG SRC='upload/" 

+ uploadedFileName 

+ "' width='300'><BR>");

}

*/

// out.println("</P>");

// out.println("<HR>");

// out.println("실제저장경로 : "+uploadedFile.getPath()+"<BR>");

// out.println("<HR>");

// 파일 전송이 완료되었을 때

if ( resultUpload == true ) {

// 파일 정보(Map 자료구조 방식)

fileMapNode.put("name", name);

fileMapNode.put("fileName", originalFileName);

fileMapNode.put("contentType", contentType);

fileMapNode.put("fileSize", fileSize);

fileMapNode.put("fileExt", fileExt);

fileMapNode.put("uploadedFileName", uploadedFileName);

fileMapNode.put("realName", uploadedFile.getName());

fileMapNode.put("realPath", uploadedFile.getPath());

// 파일 정보(문자열 구분 방식)

fileListNode.add( "id:" + fileNum + ",name:name,value:" + name + "/" );

fileListNode.add( "id:" + fileNum + ",name:filename,value:" + originalFileName + "/" );

fileListNode.add( "id:" + fileNum + ",name:contentType,value:" + contentType + "/" );

fileListNode.add( "id:" + fileNum + ",name:fileSize,value:" + fileSize + "/" );

fileListNode.add( "id:" + fileNum + ",name:fileExt,value:" + fileExt + "/" );

fileListNode.add( "id:" + fileNum + ",name:uploadedFileName,value:" + uploadedFileName + "/" );

fileListNode.add( "id:" + fileNum + ",name:realName,value:" + uploadedFile.getName() + "/" );

fileListNode.add( "id:" + fileNum + ",name:realPath,value:" + uploadedFile.getPath() + "/" );

fileInfoList.add(fileListNode);

fileNum++;

}

}

private static void processFormField(PrintWriter out, FileItem item) 

throws Exception{

String name = item.getFieldName(); //필드명 얻기

Object value = item.getString("UTF-8"); //UTF-8형식으로 필드에 대한 값읽기

//out.println(name + ":" + value + "<BR>"); //출력

// 파일 토큰 인증 여부

if ( name.contentEquals("token")

&& value.equals(FILE_AUTH_TOKEN_KEY) ) {

System.out.println("참 - 인증");

FILE_TOKEN_CHECK = true;

}

// Map 자료구조 저장

reqInfoMap.put(name, value);

// 문자열 구문 저장 - 문자열 검색원리 적용 (검색 기법 적용)

reqInfoList.add( "id:" + reqNum + ",name:" + name + ",value:" + value + "/" );

reqNum++;

}

// FileInfoList 내용 - 문맥 문석기(임시)

public static void getFileinfoParser(List<Object> fileParser, String tarName) {

// 분석 시작

if ( fileParser != null ) {

for ( Object fileNode : fileParser ) {

@SuppressWarnings("unchecked")

List<String> sep = (List<String>) fileNode;

// 문자열 분석 반환 받기 (id = 0, name = 1, value = 2)

Object result = getFileAttrAnal(sep, tarName);

}

}

}


// FileInfoList 내용 - 문자열 구분

private static Object getFileAttrAnal(List<String> fileNode, String tarName) {

int pId = -1;

String pName = null;

Object pValue = null;

String trashTxt = null;

if ( fileNode != null) {

for ( String usrTxt : fileNode  ) {

trashTxt = usrTxt.substring(usrTxt.indexOf("id:") + 3, usrTxt.indexOf(",name") );

pId = Integer.valueOf(trashTxt);

// System.out.print("ID:" + pId);


trashTxt = usrTxt.substring(usrTxt.indexOf("name:") + 5, usrTxt.indexOf(",value") );

pName = trashTxt;

// System.out.print(",name:" + pName);

trashTxt = usrTxt.substring(usrTxt.indexOf("value:") + 6, usrTxt.indexOf("/") );

pValue = trashTxt;

// System.out.println(",value:" + pValue);

}

}

return null;

}


// ReqInfoList 내용 - 문맥 문석기(임시)

public static Object getReqinfoParser(List<String> reqNode, String tarName) {

int pId;

String pName ;

Object pValue ;

String trashTxt;

if ( reqNode != null) {

for ( String usrTxt : reqNode  ) {

trashTxt = usrTxt.substring(usrTxt.indexOf("id:") + 3, usrTxt.indexOf(",name") );

pId = Integer.valueOf(trashTxt);

System.out.print("ID:" + pId);


trashTxt = usrTxt.substring(usrTxt.indexOf("name:") + 5, usrTxt.indexOf(",value") );

pName = trashTxt;

System.out.print(",name:" + pName);

trashTxt = usrTxt.substring(usrTxt.indexOf("value:") + 6, usrTxt.indexOf("/") );

pValue = trashTxt;

System.out.println(",value:" + pValue);

}

}

return null;

}

}


파일명: HttpUtil.java


[첨부(Attachments)]

HttpUtil.zip




11. Model - CompUsers.java


모델은 DB의 테이블 설계를 생각해서 하는 것이 좋다고 본다. (꼭 그렇다는 건 아님.)


아래의 그림 16, 그림 17, 그림 18은 결국은 같은 Table에 대한 것이다.

하나를 바라보는 것이 다양할 수 있다는 이야기를 하는 것이다.



그림 16. Oracle SQL Developer - COMP_USERS (Tables)



그림 17. Oracle SQL Developer - COMP_USERS (Tables)



그림 18. Oracle SQL Developer - COMP_USERS (Tables)


비고: 이 글에서는 DB 설계는 하지 않았음.



경로: /src/main/java/com/example/web/model/CompUsers.java


package com.example.web.model;


public class CompUsers {


private String username;

private String password;

private int enabled;

public CompUsers(String username, String password, int enabled) {

this.username = username;

this.password = password;

this.enabled = enabled;

}


public CompUsers() {

}


public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

public int getEnabled() {

return enabled;

}

public void setEnabled(int enabled) {

this.enabled = enabled;

}

}



파일명: CompUsers.java


[첨부(Attachments)]

CompUsers.zip



* 2부에서는 Jquery 다운받기, JSON, MultiUploadController, View 화면, Index 페이지 구성에 대해서 소개하겠다.


1. [JSP] 25. jQuery와 Ajax 멀티 파일 업로드(개선), POST전송, JSON - 구성하기(2), 2020-10-03

https://yyman.tistory.com/1446


반응형

+ Recent posts