네로개발일기

개발자 네로의 개발 일기, 자바를 좋아합니다 !

'2022/02'에 해당되는 글 5건


반응형

[Spring] Apache POI 를 이용한 엑셀 파일 읽기

✨ 의존성

- Spring Boot

- Spring Web

- Thymeleaf

- Lombok

 

1. Apache POI , Tika 관련 의존성 추가

maven일 경우 pom.xml

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>4.1.2</version>
</dependency>
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>4.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tika/tika-core -->
<dependency>
  <groupId>org.apache.tika</groupId>
  <artifactId>tika-core</artifactId>
  <version>2.3.0</version>
</dependency>

 

 

gradle일 경우 build.gradle

// https://mvnrepository.com/artifact/org.apache.poi/poi
implementation group: 'org.apache.poi', name: 'poi', version: '4.1.2'
implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.2'
// https://mvnrepository.com/artifact/org.apache.tika/tika-core
implementation group: 'org.apache.tika', name: 'tika-core', version: '2.3.0'

spring boot라면 version 입력을 하지 않아도 될 것이다.

 

2. 파일 입력 폼

resources/templates/index.html

<!DOCTYPE HTML>
<html lang="ko" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>

<body>
<form th:action="@{/excel/read}" method="POST" enctype="multipart/form-data">
    <input type="file" th:name="file1">
    <input th:type="submit" value="제출" />
</form>
</body>
</html>

 

3. 객체

ExcelData.java

package model;

import lombok.*;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Builder
public class ExcelData {

    private int num;
    private String name;
}

 

4. 컨트롤러

ExcelDataController.java

import model.ExcelData;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.tika.Tika;
import org.apache.tika.exception.TikaException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@Controller
public class ExcelDataController {

    @PostMapping("/excel/read")
    public String readExcel(@RequestParam("file") MultipartFile file, Model model) throws TikaException, IOException { // 2

        List<ExcelData> dataList = new ArrayList<>();

        try (InputStream is = file.getInputStream();) {

            Tika tika = new Tika();
            String mimeType = tika.detect(is);
            if (isAllowedMIMEType(mimeType)) {
                Workbook workbook = new XSSFWorkbook(file.getInputStream());

                Sheet worksheet = workbook.getSheetAt(0);

                String atchFileId = null;

                for (int i = 1; i < worksheet.getPhysicalNumberOfRows(); i++) { // 1번째 행부터 끝까지
                    Row row = worksheet.getRow(i);
                    
                    ExcelData data = new ExcelData();
                    data.setNum((int) row.getCell(0).getNyumericCellValue());
                    data.setName(row.getCell(1).getStringCellValue());

                    dataList.add(data);
                }

                model.addAttribute("list", dataList);
            } else {
                throw new IOException();
            }
        } catch (Exception e) {
            throw new TikaException("ERROR");
        }

        return "list";
    }


    private boolean isAllowedMIMEType(String mimeType) {
        if (mimeType.equals("application/x-tika-ooxml"))
            return true;
        return false;
    }
}

MultipartFile

Spring 환경이라면 Spring에서 제공하고 있는 MultipartFile 클래스와 MultipartHttpServletRequest 클래스를 사용해서 File 업로드 기능을 구현할 수 있다. 클라이언트에서 서버로 HTTP 요청을 할 때, Content-Type 필드의 내용을 multipart/form-data로 요청한다.

@RequestParam 어노테이션과 함께 MultipartFile 타입을 사용한다. 

 

Apache Tika 라이브러리

Apache Tika 를 사용하여 MIME TYPE를 체크하였다.

 

5. 리스트 화면 

resources/templates/list.html

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
</head>
<body>
  <table class="table table-striped">
    <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">번호</th>
      <th scope="col">이름</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="data : ${datas}" >
      <td th:text="${dataStat.index}"></td>
      <td th:text="${data.num}"></td>
      <td th:text="${data.name}"></td>
    </tr>
    </tbody>
  </table>
</body>
</html>

Stat을 사용해서 상태변수 (index)를 접근하였다.

 

참고

https://stackoverflow.com/questions/50849800/how-to-read-excel-file-using-spring-boot

https://caileb.tistory.com/152

 

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

SSH로 접속할때 ubuntu@123.123.123.123 식으로 입력하여 접속을 한다

 

# 예시
# 사용자명: ubuntu
# IP 주소: 192.168.10.23
# Port 번호: 8000

$ ssh ubuntu@192.168.10.23 -p 8000

 

접속정보를 설정파일로 저장하여 접속할 수 있다. 아래 명령어를 통해 config 파일을 만든다.

$ vi ~/.ssh/config

 

 

config 파일에 아래와 같이 입력한다.

Host myserver
    HostName 192.168.10.23
    Port 8000
    User ubuntu

vi 명령어를 알면 되지만, i 키 눌러서 입력하고 esc 누르고 :wq 입력해서 저장한다.

 

$ ssh myserver

위와 같이 입력하면 맨 위와 같은 명령어와 동일한 일을 진행한다.

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

1. Mybatis resultMap 기능

mybatis는 ORM 기술 중 하나이다. ORM(Object Relational Mapping)이란 객체 지향 언어의 객체와 관계형 데이터를 서로 변환해준다는 것이다.

DB 조회 결과를 복잡한 객체 구조로 변환해야 할 때 mybatis의 resultMap 기능을 사용한다. 여러 테이블의 조인 결과를 여러 자바 객체에 담을 때 resultMap 기능이 유용하다.

 

2. Mybatis mapper 구현 방법

1) annotation으로 구현하기

간단한 SQL을 구현할 때 annotation을 이용하여 구현하는 것이 편하다.

2) mapper XML에서 구현하기

mybatis resultMap 기능을 구현하려면 mapper XML 파일에 구현하는 것이 편하다.

 

mapper/RegisterMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis//DTD Mapper 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-mapper .dtd">

<mapper namespace="mapper.RegisterMapper">
    <resultMap id="RegisterwithStudentCourse" type="dto.Register">
        <id property="id" column="id" />
        <result property="studentId" column="studentId" />
        <result property="courseId" column="courseId" />
        <result property="grade" column="grade" />
        <result property="createDate" column="createDate" />
        <association property="student" javaType="dto.Student">
            <id property="id" column="studentId" />
            <result property="studentNumber" column="studentNumber" />
            <result property="name" column="studentName" />
        </association>
        <association property="course" javaType="dto.Course">
            <id property="id" column="courseId" />
            <result property="courseName" column="courseName" />
            <result property="unit" column="unit" />
        </association>
    </resultMap>
</mapper>

 

<mapper namespace="mapper.RegisterMapper">

RegistMapper에 대한 SQL 명령이나 resultMap 등을 정의하기 위한 mapper 태그이다.

패키지까지 포함해서 mapper 클래스의 이름을 적는다.

 

<resultMap id="RegisterwithStudentCourse" type="dto.Register">

조회 결과를 Regist 객체로 채우는 방법을 정의한다. SQL 조회 결과를 Java 객체 구조에 채우는 방법을 정의한 것이 resultMap이다.

 

<id property="id" column="id" />

조회 결과의 id 칼럼은 Register 클래스의 id 속성(property)에 채운다. 이 칼럼이 테이블의 기본키(primary)이기 때문에 <id> 태그를 사용한다.

 

<result property="studentId" column="studentId" />

조회 결과의 studentId 칼럼을 Register 클래스의 studentId 속성에 채운다. 테이블의 기본키가 아니기 때문에 <result> 태그를 사용한다.

 

<association property="student" javaType="dto.Student">

Register 클래스의 student 속성에 Student 객체를 대입한다.

 

/mapper/RegisterMapper.java

import java.util.List; 

import org.apache.ibatis.annotations.Mapper; 
import org.apache.ibatis.annotations.ResultMap; 
import org.apache.ibatis.annotations.Select; 

import dto.Register; 

@Mapper 
public interface RegisterMapper { 

    @ResultMap("RegisterWithStudentAndCourse") 
    @Select("SELECT r.*, s.studentNumber, s.name studentName, c.courseName, c.unit " + 
            " FROM register r JOIN student s ON r.studentId = s.id " + 
            " JOIN course c ON r.courseId = c.id " + 
            " ORDER BY s.studentNumber ") 
    List<Register> findAll(); 
}

 

@ResultMap("RegisterWithStudentAndCourse")

 

RegisterMapper.xml 파일의 id="RegisterWithStudentAndCourse" resultMap 방법으로 조회 결과를 Java 객체들에 채워서 리턴한다.

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

package.json 파일에 실행 스크립트는 start, build, test, eject 4가지 명령어가 있습니다.

일반적으로 start는 개발모드, build는 배포용이라고 알려져있다.

"scripts": {
  "start": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test",
  "eject": "react-scripts eject"
},

1) npm run start

- 개발 모드로 프로그램을 실행하는 명령어이다.

- HMR(Hot Module Replacement)가 동작해 수정과 동시에 화면이 변경된다.

- 개발 모드에서 코드에 에러가 있을 경우 브라우저에 메시지를 출력한다.

- HTTPS 실행 옵션을 통해 https 인증서 없이 임시로 https 형태로 url을 만들 수 있다.

$ npm start
$ npm run start

> HTTPS 실행 옵션 사용해 실행

$ HTTPS=true npm start

 

2) npm run build

- 배포 환경에서 사용할 파일을 만들어준다.

- 압축 형태로 제공

$ npm build
$ npm run build

 

> 정적 파일 서비스 실행

serve 패키지는 노드(node.js) 환경에서 동작하는 웹 서버 애플리케이션

npx 로 실행하며 build 된 정적 파일을 서비스 할 때 간단하게 사용하기 편리하다.

$ npx serve -s build

 

3) npm test

- 테스트 코드를 실행합니다.

- create-react-app 에는 제스트(jest) 테스트 프레임워크가 기본 동작

 

> 테스트 대상

- __test__ 폴더에 밑에 있는 모든 자바스크립트 파일

- 파일 이름이 .test.js로 끝나는 파일

- 파일 이름이 .spec.js로 끝나는 파일

 

CI(continuous integration)와 같이 watch 모드가 필요 없는 환경에서는 다음 명령어로 테스트 코드를 실행

$ CI=true npm test

 

4) npm run eject

- 숨겨져 있던 create-react-app 내부 설정 파일의 노출한다.

- 바벨이나 웹팩 설정을 변경할 수 있다. (단점은 익숙해야 가능)

- npm run eject 외에도 방법이 존재한다.

  • 방법 1: react-scripts 프로젝트를 포크(fork) 해서 나만의 스크립트를 만든다.
  • 방법 2: react-app-rewired 패키지를 사용한다.

 

추천할 글 > Yarn이란?

https://frogand.tistory.com/82

 

[yarn] Yarn이란? 의존성 관리 / 패키지 매니저

❓ Yarn이란? yarn은 프로젝트의 의존성을 관리하는 javascript의 package manager이다. *Java의 gradle이나 Python의 pip와 같은 것. yarn은 npm과 마찬가지로 package.json을 통해 의존 패키지를 구분하고 프로..

frogand.tistory.com

 

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

curl이란?

Client URL

서버와 통신할 수 있는 커맨드 명령어 툴입니다. curl의 특징은 수많은 프로토콜을 지원합니다.

 

지원하는 프로토콜

DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, Telnet, TFTP

 

SSL 인증방식 역시 가능하다.

 

curl 사용법

$ curl [options] [URL...]
-k --insecure https 사이트를 SSL certificate 검증없이 연결한다. wget 의 --no-check-certificate 과 비슷한 역할 수행
-l --head HTTP header 만 보여주고 content 는 표시하지 않는다.  
-D --dump-header <file> <file> 에 HTTP header 를 기록한다.  
-L --location 서버에서 HTTP 301 이나 HTTP 302 응답이 왔을 경우 redirection URL 로 따라간다.
--max-redirs 뒤에 숫자로 redirection 을 몇 번 따라갈지 지정할 수 있다. 기본 값은 50이다
curl -v daum.net 을 실행하면 결과값으로 다음과 같이 HTTP 302 가 리턴된다.
< HTTP/1.1 302 Object Moved
< Location: http://www.daum.net/

-L 옵션을 추가하면 www.daum.net 으로 재접속하여 결과를 받아오게 된다.
-d --data HTTP Post data FORM 을 POST 하는 HTTP나 JSON 으로 데이타를 주고받는 REST 기반의 웹서비스 디버깅시 유용한 옵션이다
-v --verbose  동작하면서 자세한 옵션을 출력한다.  
-J --remote-header-name 어떤 웹서비스는 파일 다운로드시 Content-Disposition Header를 파싱해야 정확한 파일이름을 알 수 있을 경우가 있다. -J 옵션을 주면 헤더에 있는 파일 이름으로 저장한다. curl 7.20 이상부터 추가된 옵션
-o --output FILE curl 은 remote 에서 받아온 데이타를 기본적으로는 콘솔에 출력한다. -o 옵션 뒤에 FILE 을 적어주면 해당 FILE 로 저장한다. (download 시 유용)  
-O --remote-name file 저장시 remote 의 file 이름으로 저장한다. -o 옵션보다 편리하다.  
-s --silent 정숙 모드. 진행 내역이나 메시지등을 출력하지 않는다. -o 옵션으로 remote data 도 /dev/null 로 보내면 결과물도 출력되지 않는다 HTTP response code 만 가져오거나 할 경우 유리

> 옵션없이 호출할 경우 curl은 지정된 리소스를 표준 출력에 표시합니다.

예를 들어 example.com 홈페이지를 검색하려면 다음을 실행하고

$ curl example.com

이 명령어는 터미널창에 example.com 홈페이지의 소스코드를 출력합니다. 

프로토콜을 지정하지 않은 경우, curl은 사용할 프로토콜을 추측하려고 시도하며 이 프로토콜은 HTTP로 기본

 

설치방법

Ubuntu 및 Debian에 curl 설치

$ sudo apt update
$ sudo apt install curl

CentOS 및 Fedora에 curl 설치

$ sudo yum install curl

 

 

출처

https://jjeongil.tistory.com/1313

 

Linux : Curl 명령어 예시, 예제, 방법

curl은 사용자 상호 작용 없이 작동하도록 설계된 서버에서 또는 서버로 데이터를 전송하기 위한 명령줄 유틸리티입니다. curl을 사용하면 HTTP, HTTPS, SCP , SFTP 및 FTP 등 지원되는 프로토콜 중 하나

jjeongil.tistory.com

 

728x90
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !