보낼 메시지와 시간만 정해두면, 카카오톡 PC에서 정해진 시각에 자동으로 발송됩니다. 매일 같은 공지나 반복 안내, 여러 단톡방에 같은 메시지를 손으로 보내지 않아도 됩니다. Windows 전용입니다.

 

 

예약 발송, 매일·매주·매월 반복 예약, 여러 단톡방과 친구에게 한 번에 보내는 그룹 발송, 사진·파일 첨부 발송을 지원합니다. 보내는 도중 ‘지금 멈추기’와 발송 기록도 있습니다.

 

받는 곳과 내용, 시간만 고르면 됩니다. 예약함에서 진행·완료·실패를 확인합니다. 아래는 실제 프로그램 화면입니다(예시 데이터, 개인정보 미포함).

 

 

무료 1일 체험을 드립니다. 먼저 써보고 결정하세요. 문의는 아래 오픈채팅으로 주시면 체험키와 사용법을 안내해 드립니다.

https://open.kakao.com/o/sSfLmmBi

 

K톡 마크로

K톡 마크로

open.kakao.com

동작은 사용 환경에 따라 다를 수 있습니다. 본 프로그램은 개인 학습·실험용 도구이며, 과도한 대량·매크로성 사용은 카카오 서비스 약관에 저촉되어 계정 제재 위험이 있습니다(책임은 사용자 본인).

블로그 이미지

미나미나미

,

0.1 시작 전 Gradle 설정 내용 확인

https://minaminaworld.tistory.com/218

 

[SpringBoot] 멀티 데이터베이스 설정하기 - 설정편

1. Gradle 설정 dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'junit:junit..

minaminaworld.tistory.com

0.2 JPA 설정편 확인: JPA에서 생성한 데이터를 읽어오는 테스트 코드 작성함

https://minaminaworld.tistory.com/219

 

[SpringBoot] 멀티 데이터베이스(DB) 설정하기 JPA 편

0. 시작 전 Gradle 설정 내용 확인 https://minaminaworld.tistory.com/218 [SpringBoot] 멀티 데이터베이스 설정하기 - 설정편 1. Gradle 설정 dependencies { implementation 'org.springframework.boot:spring-..

minaminaworld.tistory.com


1. 테스트 DB, 스키마, 테이블 정보

 - 테스트 DB명: db1

 - 테스트 스키마: jpa

 - 테스트 테이블: userjpa (Jpa Option: create를 통한 자동 생성함)

 

 


2. application.yml 과 application-local.yml

 - application.yml

spring:
  profiles:
    active: local

- application-local.yml

spring:
  config:
    activate:
      on-profile: local
  datasource:
    jpa:
      #     jdbc-url: jdbc:postgresql://localhost:5432/db1
      url: jdbc:postgresql://localhost:5432/db1
      username: postgres
      password: postgres
      driver-class-name: org.postgresql.Driver
    mybatis:
      #      jdbcUrl: jdbc:postgresql://localhost:5432/db1
      url: jdbc:postgresql://localhost:5432/db1
      username: postgres
      password: postgres
      driver-class-name: org.postgresql.Driver
server:
  port: 8090 # 서버 포트 변경

2. MybatisDbProperties.java

package com.example.multidb.database.config;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "spring.datasource.mybatis") // application-local.yml 참고
@Getter
@Setter
public class MybatisDbProperties {
    String url;
    String username;
    String password;
    String driverClassName;
}

3. mybatis-config.xml 작성 (* resources 폴더 생성)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="cacheEnabled" value="true" />
        <setting name="useColumnLabel" value="true" />
        <setting name="useGeneratedKeys" value="false" />
        <setting name="mapUnderscoreToCamelCase" value="true" />
        <setting name="defaultStatementTimeout" value="25000" />
        <setting name="mapUnderscoreToCamelCase" value="true" />
        <setting name="jdbcTypeForNull" value="NULL"/>
    </settings>
    <typeAliases>
        <!-- 오탈자 조심 -->
        <package name="com.example.multidb.domain.mybatis"/>
    </typeAliases>
</configuration>

4. UserMybatis.java: 테이블 읽어올 항목 작성(VO 생성)

package com.example.multidb.domain.mybatis;

import javax.persistence.Column;

public class UserMybatis {
    private Long id;
    private String name;
    private String email;
    private int age;

    @Override
    public String toString() {
        return "UserMybatis{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
}

5. UserMybatisMapper.java와 UserMybatisMapper.xml 작성

- UserMybatisMapper.java

package com.example.multidb.persistence.mybatis.mapper;

import com.example.multidb.domain.mybatis.UserMybatis;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.Map;

@Repository
public interface UserMybatisMapper {
    public ArrayList<UserMybatis> getUsers() throws Exception;
}

- UserMybatisMapper.xml : namespace 부분 확인하시면서 하세요. 오탈자 조심

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

    <select id="getUsers" resultType="com.example.multidb.domain.mybatis.UserMybatis">
            SELECT * FROM jpa.userjpa;
    </select>

</mapper>

6. MybatisDb.java

package com.example.multidb.database.config;

import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;

@Configuration
@RequiredArgsConstructor
@MapperScan(
        basePackages = {"com.example.multidb.persistence.mybatis.mapper"}
)
public class MybatisDb {

    private final MybatisDbProperties mybatisDbProperties;

    @Bean(name = "mybatisDataSource")
    public DataSource dataSource() {
        // 빌더 dataSource 생성
        // 프로퍼티 정보
        System.out.println("------------------------------------------");
        String url = mybatisDbProperties.getUrl();
        String username = mybatisDbProperties.getUsername();
        String password = mybatisDbProperties.getPassword();
        String driverClassName = mybatisDbProperties.getDriverClassName();

        System.out.println("url = " + url);
        System.out.println("username = " + username);
        System.out.println("password = " + password);
        System.out.println("driverClassName = " + driverClassName);
        System.out.println("------------------------------------------");

        return  DataSourceBuilder.create()
                .url(mybatisDbProperties.getUrl())
                .username(mybatisDbProperties.getUsername())
                .password(mybatisDbProperties.getPassword())
                .driverClassName(mybatisDbProperties.getDriverClassName())
                .build();
    }

    @Bean(name = "mybatisSessionFactory")
//    @Primary
    public SqlSessionFactory sqlSessionFactory(@Qualifier("mybatisDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
        sessionFactoryBean.setDataSource(dataSource);
        sessionFactoryBean.setTypeAliasesPackage("com.example.multidb.domain.jpa");
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactoryBean.setConfigLocation(new ClassPathResource("mybatis/mybatis-config.xml"));
        sessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:mybatis/mapper/**/*.xml"));
        return sessionFactoryBean.getObject();
    }

    @Bean(name = "mybatisSqlSessionTemplate")
    public SqlSessionTemplate firstSqlSessionTemplate(@Qualifier("mybatisSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

6. MybatisService.java 및 테스트 코드 작성

- MybatisService.java

package com.example.multidb.service;

import com.example.multidb.domain.jpa.UserJpa;
import com.example.multidb.domain.mybatis.UserMybatis;
import com.example.multidb.persistence.jpa.repository.UserJpaRepository;
import com.example.multidb.persistence.mybatis.mapper.UserMybatisMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;

@Service
@RequiredArgsConstructor
public class MybatisService {
    private final UserMybatisMapper userMybatisMapper;

    @Transactional(readOnly = true)
    public void readUser() {
        try {
            ArrayList<UserMybatis> users = userMybatisMapper.getUsers();
            for (UserMybatis user : users) {
                System.out.println("user = " + user);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

- MybatisServiceTest.java

package com.example.multidb.service;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class mybatisServiceTest {

    @Autowired
    private MybatisService mybatisService;

    @Test
    @DisplayName("JPA에서 생성한 유저 읽어오기")
    void readUser() {
        mybatisService.readUser();
    }
}

7.  결과화면

 

블로그 이미지

미나미나미

,

0. 시작 전 Gradle 설정 내용 확인

https://minaminaworld.tistory.com/218

 

[SpringBoot] 멀티 데이터베이스 설정하기 - 설정편

1. Gradle 설정 dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'junit:junit..

minaminaworld.tistory.com


1. 테스트 DB, 스키마, 테이블 정보

 - 테스트 DB명: db1

 - 테스트 스키마: jpa

 - 테스트 테이블: userjpa (Jpa Option: create를 통한 자동 생성함)

 

 


2. application.yml 과 application-local.yml

 - application.yml

spring:
  profiles:
    active: local

- application-local.yml

spring:
  config:
    activate:
      on-profile: local
  datasource:
    jpa:
      #     jdbc-url: jdbc:postgresql://localhost:5432/db1
      url: jdbc:postgresql://localhost:5432/db1
      username: postgres
      password: postgres
      driver-class-name: org.postgresql.Driver
    mybatis:
      #      jdbcUrl: jdbc:postgresql://localhost:5432/db1
      url: jdbc:postgresql://localhost:5432/db1
      username: postgres
      password: postgres
      driver-class-name: org.postgresql.Driver
server:
  port: 8090 # 서버 포트 변경

3. JpaDbProperties.java : 데이터베이스 설정 정보 세팅(yml 참고)

package com.example.multidb.database.config;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "spring.datasource.jpa") // application-local.yml 참고
@Getter
@Setter
public class JpaDbProperties {
    String url;
    String username;
    String password;
    String driverClassName;
}

4. UserJpa.java와 UserJpaRepository.java

- UserJpa.java

package com.example.multidb.domain.jpa;

import lombok.*;
import javax.persistence.*;

@Entity
@SequenceGenerator(
        name = "USER_SEQ_GEN", // 시퀀스 제너레이터 이름
        sequenceName = "USER_SEQ", // 시퀀스 이름
        initialValue = 1,
        allocationSize = 1 // 메모리를 통해 할당할 범위 사이즈
)
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(schema = "jpa")
public class UserJpa {

    @Id
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "USER_SEQ_GEN"
    )
    private Long id;

    private String name;

    @Column(unique = true, nullable = false)
    private String email;

    private int age;

    public UserJpa(String name, String email, int age) {
        this.name = name;
        this.email = email;
        this.age = age;
    }

}

- UserJpaRepository.java

package com.example.multidb.persistence.jpa.repository;

import com.example.multidb.domain.jpa.UserJpa;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserJpaRepository extends JpaRepository<UserJpa, Long> {

}

4. JpaDb.java: DB 설정하기

 - 1번과 2번 방식 동일하게 DataSouce를 생성할 수 있음으로 참고하시길 바랍니다.

 

package com.example.multidb.database.config;

import com.google.common.collect.ImmutableMap;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = "jpaEntityManagerFactory",
        transactionManagerRef = "jpaTransactionManager",
        basePackages = {"com.example.multidb.persistence.jpa.repository"} // Repository 위치
)
@RequiredArgsConstructor
public class JpaDb {
//// 1번 방식 ----------------------------------------------------------------------------
//    @Bean
//    @ConfigurationProperties(prefix = "spring.datasource.jpa")
//    public DataSourceProperties jpaDataSourceProperties() {
//        DataSourceProperties dataSourceProperties = new DataSourceProperties();
//        return dataSourceProperties;
//    }
//
//    @Bean(name = "jpaDataSource")
//    public DataSource dataSource(@Qualifier("jpaDataSourceProperties") DataSourceProperties dataSourceProperties) {
//        // 프로퍼티 정보
//        String url = dataSourceProperties.getUrl();
//        String username = dataSourceProperties.getUsername();
//        String password = dataSourceProperties.getPassword();
//        String driverClassName = dataSourceProperties.getDriverClassName();
//
//        System.out.println("------------------------------------------");
//        System.out.println("url = " + url);
//        System.out.println("username = " + username);
//        System.out.println("password = " + password);
//        System.out.println("driverClassName = " + driverClassName);
//        System.out.println("------------------------------------------");
//
//        return dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
//    }
//// ---------------------------------------------------------------------------- 1번 방식

    // 2번 방식 ----------------------------------------------------------------------------
    private final JpaDbProperties jpaDbProperties;

    @Primary
    @Bean(name = "jpaDataSource")
    public DataSource dataSource() {
        // 빌더 dataSource 생성

        // 프로퍼티 정보
        System.out.println("------------------------------------------");
        String url = jpaDbProperties.getUrl();
        String username = jpaDbProperties.getUsername();
        String password = jpaDbProperties.getPassword();
        String driverClassName = jpaDbProperties.getDriverClassName();

        System.out.println("url = " + url);
        System.out.println("username = " + username);
        System.out.println("password = " + password);
        System.out.println("driverClassName = " + driverClassName);
        System.out.println("------------------------------------------");

        return  DataSourceBuilder.create()
                .url(jpaDbProperties.getUrl())
                .username(jpaDbProperties.getUsername())
                .password(jpaDbProperties.getPassword())
                .driverClassName(jpaDbProperties.getDriverClassName())
                .build();
    }
    // ---------------------------------------------------------------------------- 2번 방식

    @Bean(name = "jpaEntityManagerFactory")
    @Primary
    public EntityManagerFactory entityManagerFactory(
            @Qualifier("jpaDataSource") DataSource dataSource
    ) {
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setDataSource(dataSource);
        factory.setPackagesToScan(new String[]{"com.example.multidb.domain.jpa"}); //Entity 위치
        factory.setPersistenceUnitName("jpa");

        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setJpaPropertyMap(ImmutableMap.of(
                "hibernate.hbm2ddl.auto", "create",
//                "hibernate.hbm2ddl.auto", "create-drop",
                "hibernate.dialect", "org.hibernate.dialect.PostgreSQL10Dialect",
                "hibernate.show_sql", "true",
                "hibernate.format_sql", "true",
                "hibernate.open-in-view", "false"
        ));
        factory.afterPropertiesSet();
        return factory.getObject();
    }

    @Bean(name = "jpaTransactionManager")
    @Primary
    public PlatformTransactionManager transactionManager(@Qualifier("jpaEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        JpaTransactionManager tm = new JpaTransactionManager();
        tm.setEntityManagerFactory(entityManagerFactory);
        return tm;
    }

}

5. JpaService.java와 JpaServiceTest.java: UserJpa 생성 서비스 코드와 테스트 작성

- JpaService.java

package com.example.multidb.service;

import com.example.multidb.domain.jpa.UserJpa;
import com.example.multidb.persistence.jpa.repository.UserJpaRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class JpaService {

    private final UserJpaRepository userJpaRepository;

    @Transactional
    public void createUser(String name, String email, int age) {
//        UserJpa userJpa = new UserJpa("A", "a@email.com", 20);
        userJpaRepository.save(new UserJpa(name, email, age));
    }
}

- JpaServiceTest.java

package com.example.multidb.service;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class JpaServiceTest {

    @Autowired
    private JpaService jpaService;

    @Test
    @DisplayName("JPA 유저 생성")
    void createUser() {
        //        UserJpa userJpa = new UserJpa("A", "a@email.com", 20);
        for (int i = 0; i < 10; i++) {
            jpaService.createUser("A" + i, "a" + i + "@email.com", 20 + i);
        }
    }
}

6. 테스트 결과


 

블로그 이미지

미나미나미

,

1. Gradle 설정

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'

    testImplementation 'junit:junit:4.13.1'

    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'

    // postgresql
    // https://mvnrepository.com/artifact/org.postgresql/postgresql
    implementation group: 'org.postgresql', name: 'postgresql'

    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"

    // mybatis -----
    implementation 'org.springframework.boot:spring-boot-starter-data-jdbc:2.6.7'
    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.2'
    // ----- mybatis

    // lombok -----
    annotationProcessor 'org.projectlombok:lombok'
    // ----- lombok

    // 다중 DB JPA 속성 관련
    implementation group: 'com.google.guava', name: 'guava', version: '31.1-jre'
}

 

블로그 이미지

미나미나미

,

1. react-pdf 설치

   - npm install react-pdf


2. 폴더 구조

 - Page 파일 : pdfView.js

 - 테스트 파일 : somefile.pdf


3. pdfView.js

import React, {useState} from 'react';
import {Document, Page, pdfjs} from 'react-pdf';

pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

const pdfView = () => {
    const [numPages, setNumPages] = useState(null); // 총 페이지수
    const [pageNumber, setPageNumber] = useState(1); // 현재 페이지
    const [pageScale, setPageScale] = useState(1); // 페이지 스케일

    function onDocumentLoadSuccess({numPages}) {
        console.log(`numPages ${numPages}`);
        setNumPages(numPages);
    }

    return (
        <>
            {/* pdf 크기가 1280 * 720이 넘는 경우, overflow 처리 */}
            <div style={{width: '1280px', height: '720px', overflow: 'auto'}}>
                <Document file="/somefile.pdf" onLoadSuccess={onDocumentLoadSuccess}>
                    <Page width={1280} height={720} scale={pageScale} pageNumber={pageNumber}/>
                </Document>
            </div>
            <div>
                <p>
                    Page {pageNumber} of {numPages}
                </p>

                <p>페이지 이동 버튼</p>
                <button onClick={() => {
                    setPageNumber(numPages === pageNumber ? pageNumber : pageNumber + 1)
                }}> +
                </button>
                <button onClick={() => {
                    setPageNumber(pageNumber === 1 ? pageNumber : pageNumber - 1)
                }}> -
                </button>

                <p>페이지 스케일</p>
                <button onClick={() => {
                    setPageScale(pageScale === 3 ? 3 : pageScale + 0.1)
                }}> +
                </button>
                <button onClick={() => {
                    setPageScale((pageScale - 1) < 1 ? 1 : pageScale - 1)
                }}> -
                </button>
            </div>
        </>
    );
};

export default pdfView;

4. 결과화면

 

블로그 이미지

미나미나미

,

* 이미지 파일 DB에 넣는 과정입니다.

https://minaminaworld.tistory.com/212

 

[java]PostgreSQL DB (데이터베이스)에 file(이미지) 넣기

# Java와 PostgreSQL을 통한 파일을 집어 넣기 전 준비 사항 1. postgreSQL JDBC Jar 추가하기 (https://jdbc.postgresql.org/download.html) PostgreSQL JDBC Download Download About Binary JAR file downloads..

minaminaworld.tistory.com


1. 테이블 구조


2. DB에서 데이터 읽어오는 부분과 이미지 정보 DTO 구성

* DB 에서 이미지 정보 읽어 오기

public void readImg() {
        String sql = "SELECT file_id, filename, filesize, file, inst_dt from public.img_test";
        Connection connection = null;
        PreparedStatement pstmt = null;

        try {
            connection = DriverManager.getConnection(connurl, user, password);
            pstmt = connection.prepareStatement(sql);
            ResultSet resultSet = pstmt.executeQuery();

            ImgDto imgDto = new ImgDto();
            while (resultSet.next()) {
                imgDto.setFileId(resultSet.getInt("file_id"));
                imgDto.setFilename(resultSet.getString("filename"));
                imgDto.setFilesize(resultSet.getLong("filesize"));
                imgDto.setFile(resultSet.getBytes("file"));
                imgDto.setInsDt(resultSet.getTimestamp("inst_dt").toLocalDateTime());
            }
            System.out.println("imgDto.toString() = " + imgDto.toString());
            // 이미지 정보를 파일로 저장하는 함수 호출
            saveImg(imgDto);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                pstmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

* DB에서 가져온 데이터 DTO로 변환

import java.time.LocalDateTime;

public class ImgDto {
    private int fileId;
    private String filename;
    private Long filesize;
    private byte[] file;
    private LocalDateTime insDt;

    public ImgDto() {
    }

    public int getFileId() {
        return fileId;
    }

    public void setFileId(int fileId) {
        this.fileId = fileId;
    }

    public String getFilename() {
        return filename;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public Long getFilesize() {
        return filesize;
    }

    public void setFilesize(Long filesize) {
        this.filesize = filesize;
    }

    public byte[] getFile() {
        return file;
    }

    public void setFile(byte[] file) {
        this.file = file;
    }

    public LocalDateTime getInsDt() {
        return insDt;
    }

    public void setInsDt(LocalDateTime insDt) {
        this.insDt = insDt;
    }

    @Override
    public String toString() {
        return "ImgDto{" +
                "fileId=" + fileId +
                ", filename='" + filename + '\'' +
                ", filesize=" + filesize +
                ", insDt=" + insDt +
                '}';
    }
}

3. Img 파일로 저장

private void saveImg(ImgDto imgDto) {
		// 저장할 위치 
        String strPath = "D:/testFolder/aaa";
        Path path1 = Paths.get(strPath + "/" + imgDto.getFilename());
        try {
            Files.write(path1, imgDto.getFile());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

4. 결과화면

 * Console 로그

 * 저장된 파일 


더보기
public void readImg() {
    String sql = "SELECT file_id, filename, filesize, file, inst_dt from public.img_test";
    Connection connection = null;
    PreparedStatement pstmt = null;

    try {
        connection = DriverManager.getConnection(connurl, user, password);
        pstmt = connection.prepareStatement(sql);
        ResultSet resultSet = pstmt.executeQuery();

        ImgDto imgDto = new ImgDto();
        while (resultSet.next()) {
            imgDto.setFileId(resultSet.getInt("file_id"));
            imgDto.setFilename(resultSet.getString("filename"));
            imgDto.setFilesize(resultSet.getLong("filesize"));
            imgDto.setFile(resultSet.getBytes("file"));
            imgDto.setInsDt(resultSet.getTimestamp("inst_dt").toLocalDateTime());
        }
        System.out.println("imgDto.toString() = " + imgDto.toString());
        saveImg(imgDto);
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        try {
            pstmt.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

private void saveImg(ImgDto imgDto) {
    String strPath = "D:/testFolder/aaa";
    Path path1 = Paths.get(strPath + "/" + imgDto.getFilename());
    try {
        Files.write(path1, imgDto.getFile());
    } catch (IOException e) {
        e.printStackTrace();
    }
}
블로그 이미지

미나미나미

,

1. html Head에 필요한 Script 요청

<head>
    <link rel="stylesheet"
        href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/css/ol.css">
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js">
    </script>
    <title>Openlayers View make Rectangle</title>
    <style>
        #map {
            height: 100vh;
            width: 100%;
        }
    </style>
</head>

2. Body 내용

<body>
    <div id="map"></div>
</body>

3. Script 내용

var mapView = new ol.View({ //뷰 생성
        projection: 'EPSG:3857', //좌표계 설정 (EPSG:3857은 구글에서 사용하는 좌표계) 
        center: new ol.geom.Point([128.5, 36.1]) //처음 중앙에 보여질 경도, 위도 
            .transform('EPSG:4326', 'EPSG:3857') //GPS 좌표계 -> 구글 좌표계
            .getCoordinates(), //포인트의 좌표를 리턴함
        zoom: 9 //초기지도 zoom의 정도값
    });

    //기본지도
    var baseMap = new ol.layer.Tile({
        source: new ol.source.XYZ({
            //Vworld Tile 변경
            url: 'http://xdworld.vworld.kr:8080/2d/Base/202002/{z}/{x}/{y}.png'
        })
    });

    var map = new ol.Map({
        target: 'map',
        layers: [baseMap],
        view: mapView,
    });

    // MAP 이동이 끝나신 점에서 동작할 함수 지정 
    map.on('moveend', _moveEnd);

    /**
     *  화면에 BOX 형태 View 그리기
     */
    function makePolygon(box) {
        // 기존 Polygon 레이어 지우기
        // const ly = map.getLayers().array_.find((layer)=> layer.values_.id === 'layer');
        // map.removeLayer(ly);

        // box 레이어 스타일 
        const styles = [
            new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color: 'blue',
                    width: 3
                }),
            }),
        ];
        // box 소스 
        const vectorSource = new ol.source.Vector({
            features: [box],
            projection: 'EPSG:4326',
        });
        
        // 레이어 생성 
        const vectorLayer = new ol.layer.Vector({
            id: 'layer',
            source: vectorSource,
            style: styles
        });
        map.addLayer(vectorLayer);
    }

    /**
     * MAP 이동이 끝날 때, 작동할 함수 
     */
    function _moveEnd(evt) {
        console.log(evt);

        setTimeout(() => {
            const _map = evt.map;
            const size = _map.getSize();
            const extent = _map.getView().calculateExtent(size);
            const topLeft = ol.proj.toLonLat(ol.extent.getTopLeft(extent));
            const topRight = ol.proj.toLonLat(ol.extent.getTopRight(extent));
            const bottomLeft = ol.proj.toLonLat(ol.extent.getBottomLeft(extent));
            const bottomRight = ol.proj.toLonLat(ol.extent.getBottomRight(extent));
            // console.log('topLeft', topLeft);
            // console.log('topRight', topRight);
            // console.log('bottomLeft', bottomLeft);
            // console.log('bottomRight', bottomRight);
            const polygonString = `${topLeft[0]} ${topLeft[1]},${topRight[0]} ${topRight[1]},${bottomRight[0]} ${bottomRight[1]},${bottomLeft[0]} ${bottomLeft[1]},${topLeft[0]} ${topLeft[1]}`;
            console.log(polygonString.trim());
            // makePolygon(polygonString);

            var box = new ol.Feature(new ol.geom.LineString(
                [
                    [bottomLeft[0], bottomLeft[1]],
                    [bottomRight[0], bottomRight[1]],
                    [topRight[0], topRight[1]],
                    [topLeft[0], topLeft[1]],
                    [bottomLeft[0], bottomLeft[1]]
                ])
            );

            // 박스 좌표를 현재 지도 환경에 맞게 변경
            var current_projection = ol.proj.get('EPSG:4326');
            var change_projection = ol.proj.get('EPSG:3857');
            box.getGeometry().transform(current_projection, change_projection);
            // 박스 생성 함수 실행 
            makePolygon(box);
        }, []);
    };

4. 결과 화면 


5. 전체 소스 코드

더보기
<!doctype html>
<html lang="ko">

 

<head>
    <link rel="stylesheet"
    </script>
    <title>Openlayers View make Rectangle</title>
    <style>
        #map {
            height: 100vh;
            width: 100%;
        }
    </style>
</head>

 

<body>
    <div id="map"></div>
</body>
<script type="text/javascript">
    var mapView = new ol.View({ //뷰 생성
        projection: 'EPSG:3857', //좌표계 설정 (EPSG:3857은 구글에서 사용하는 좌표계)
        center: new ol.geom.Point([128.5, 36.1]) //처음 중앙에 보여질 경도, 위도
            .transform('EPSG:4326', 'EPSG:3857') //GPS 좌표계 -> 구글 좌표계
            .getCoordinates(), //포인트의 좌표를 리턴함
        zoom: 9 //초기지도 zoom의 정도값
    });

 

    //기본지도
    var baseMap = new ol.layer.Tile({
        source: new ol.source.XYZ({
            //Vworld Tile 변경
            url: 'http://xdworld.vworld.kr:8080/2d/Base/202002/{z}/{x}/{y}.png'
        })
    });

 

    var map = new ol.Map({
        target: 'map',
        layers: [baseMap],
        view: mapView,
    });

 

    // MAP 이동이 끝나신 점에서 동작할 함수 지정
    map.on('moveend', _moveEnd);

 

    /**
     *  화면에 BOX 형태 View 그리기
     */
    function makePolygon(box) {
        // 기존 Polygon 레이어 지우기
        // const ly = map.getLayers().array_.find((layer)=> layer.values_.id === 'layer');
        // map.removeLayer(ly);

 

        // box 레이어 스타일
        const styles = [
            new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color: 'blue',
                    width: 3
                }),
            }),
        ];
        // box 소스
        const vectorSource = new ol.source.Vector({
            features: [box],
            projection: 'EPSG:4326',
        });
       
        // 레이어 생성
        const vectorLayer = new ol.layer.Vector({
            id: 'layer',
            source: vectorSource,
            style: styles
        });
        map.addLayer(vectorLayer);
    }

 

    /**
     * MAP 이동이 끝날 때, 작동할 함수
     */
    function _moveEnd(evt) {
        console.log(evt);

 

        setTimeout(() => {
            const _map = evt.map;
            const size = _map.getSize();
            const extent = _map.getView().calculateExtent(size);
            const topLeft = ol.proj.toLonLat(ol.extent.getTopLeft(extent));
            const topRight = ol.proj.toLonLat(ol.extent.getTopRight(extent));
            const bottomLeft = ol.proj.toLonLat(ol.extent.getBottomLeft(extent));
            const bottomRight = ol.proj.toLonLat(ol.extent.getBottomRight(extent));
            // console.log('topLeft', topLeft);
            // console.log('topRight', topRight);
            // console.log('bottomLeft', bottomLeft);
            // console.log('bottomRight', bottomRight);
            const polygonString = `${topLeft[0]} ${topLeft[1]},${topRight[0]} ${topRight[1]},${bottomRight[0]} ${bottomRight[1]},${bottomLeft[0]} ${bottomLeft[1]},${topLeft[0]} ${topLeft[1]}`;
            console.log(polygonString.trim());
            // makePolygon(polygonString);

 

            var box = new ol.Feature(new ol.geom.LineString(
                [
                    [bottomLeft[0], bottomLeft[1]],
                    [bottomRight[0], bottomRight[1]],
                    [topRight[0], topRight[1]],
                    [topLeft[0], topLeft[1]],
                    [bottomLeft[0], bottomLeft[1]]
                ])
            );

 

            // 박스 좌표를 현재 지도 환경에 맞게 변경
            var current_projection = ol.proj.get('EPSG:4326');
            var change_projection = ol.proj.get('EPSG:3857');
            box.getGeometry().transform(current_projection, change_projection);
            // 박스 생성 함수 실행
            makePolygon(box);
        }, []);
    };

 

</script>

 

</html>

'[openlayers]' 카테고리의 다른 글

[openlayers] openlayers 지도 만들기  (0) 2019.04.06
블로그 이미지

미나미나미

,

# 사전준비: OpenAPI Key를 발급받습니다.

https://www.data.go.kr/data/15057210/openapi.do


1.  공공데이터포털 API Response 데이터를 활용 받은 JSON 정보를 받을 DTO 생성

import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.List;

public class WthrHourDto {

    @JsonProperty("response")
    private Response response;

    public Response getResponse() {
        return response;
    }

    public void setResponse(Response response) {
        this.response = response;
    }

    public static class Response {
        @JsonProperty("body")
        private Body body;
        @JsonProperty("header")
        private Header header;

        public Body getBody() {
            return body;
        }

        public void setBody(Body body) {
            this.body = body;
        }

        public Header getHeader() {
            return header;
        }

        public void setHeader(Header header) {
            this.header = header;
        }
    }

    public static class Body {
        @JsonProperty("totalCount")
        private int totalCount; // 데이터 총 개수
        @JsonProperty("numOfRows")
        private int numOfRows; // 한 페이지당 표출 수
        @JsonProperty("pageNo")
        private int pageNo; // 페이지 수
        @JsonProperty("items")
        private Items items; //
        @JsonProperty("dataType")
        private String dataType; // 응답 자료 형식

        public int getTotalCount() {
            return totalCount;
        }

        public void setTotalCount(int totalCount) {
            this.totalCount = totalCount;
        }

        public int getNumOfRows() {
            return numOfRows;
        }

        public void setNumOfRows(int numOfRows) {
            this.numOfRows = numOfRows;
        }

        public int getPageNo() {
            return pageNo;
        }

        public void setPageNo(int pageNo) {
            this.pageNo = pageNo;
        }

        public Items getItems() {
            return items;
        }

        public void setItems(Items items) {
            this.items = items;
        }

        public String getDataType() {
            return dataType;
        }

        public void setDataType(String dataType) {
            this.dataType = dataType;
        }
    }

    public static class Items {
        @JsonProperty("item")
        private List<Item> item;

        public List<Item> getItem() {
            return item;
        }

        public void setItem(List<Item> item) {
            this.item = item;
        }
    }

    public static class Item {
        @JsonProperty("m03Te")
        private String m03Te; // 30cm 지중 온도(섭씨)
        @JsonProperty("m02Te")
        private String m02Te; // 20cm 지중 온도(섭씨)
        @JsonProperty("m01Te")
        private String m01Te; // 10cm 지중 온도(섭씨)
        @JsonProperty("m005Te")
        private String m005Te; // 5cm 지중 온도(섭씨)
        @JsonProperty("tsQcflg")
        private String tsQcflg; // 지면 온도 품질 검사 플래그
        @JsonProperty("ts")
        private String ts; // 지면 온도(섭씨)
        @JsonProperty("dmstMtphNo")
        private String dmstMtphNo; // 현상번호(국내식)
        @JsonProperty("gndSttCd")
        private String gndSttCd; // 지면상태 => 종료 16.7.1.00 시
        @JsonProperty("vs")
        private String vs; // 시정(10m)
        @JsonProperty("lcsCh")
        private String lcsCh; // 최저운고(100m)
        @JsonProperty("clfmAbbrCd")
        private String clfmAbbrCd; // 운형(운형약어)
        @JsonProperty("dc10LmcsCa")
        private String dc10LmcsCa; // 중하층운량(10분위)
        @JsonProperty("dc10Tca")
        private String dc10Tca; // 전운량(10분위)
        @JsonProperty("hr3Fhsc")
        private String hr3Fhsc; // 3시간 신적설(cm)
        @JsonProperty("dsnw")
        private String dsnw; // 적설(cm)
        @JsonProperty("icsr")
        private String icsr; // 일사(MJ/m2): 지표면에 도달한 태양복사에너지. 태양복사(단파복사)를 말하지만 여러 요인들로 인해 태양상수보다 작게 나온다.
        @JsonProperty("ssQcflg")
        private String ssQcflg; // 일조 품질검사 플래그
        @JsonProperty("ss")
        private String ss; // 일조(hr): 태양 광선이 구름이나 안개로 가려지지 않고 땅 위를 비치는 것
        @JsonProperty("psQcflg")
        private String psQcflg; // 일조 품질검사 플래그
        @JsonProperty("ps")
        private String ps; // 해면기압
        @JsonProperty("paQcflg")
        private String paQcflg; // 해면기압 품질검사 플래그
        @JsonProperty("pa")
        private String pa; // 현지기압(hPa)
        @JsonProperty("td")
        private String td; // 이슬점온도(섭씨)
        @JsonProperty("pv")
        private String pv; // 증기압(hPa)
        @JsonProperty("hmQcflg")
        private String hmQcflg; // 습도 품질검사 플래그
        @JsonProperty("hm")
        private String hm; // 습도(%)
        @JsonProperty("wdQcflg")
        private String wdQcflg; // 풍향 품질검사 플래그
        @JsonProperty("wd")
        private String wd; // 풍향(16방위)
        @JsonProperty("wsQcflg")
        private String wsQcflg; // 풍향 품질검사 플래그
        @JsonProperty("ws")
        private String ws; // 풍속(m/s)
        @JsonProperty("rnQcflg")
        private String rnQcflg; // 강수량 품질검사 플래그
        @JsonProperty("rn")
        private String rn; // 강수량(mm)
        @JsonProperty("taQcflg")
        private String taQcflg; // 기온 품질검사 플래그
        @JsonProperty("ta")
        private String ta; // 기온(섭씨)
        @JsonProperty("stnNm")
        private String stnNm; // 종관기상관측 지점명
        @JsonProperty("stnId")
        private String stnId; // 지점 번호
        @JsonProperty("rnum")
        private String rnum; // 목록 순서
        @JsonProperty("tm")
        private String tm; // 시간

        public String getM03Te() {
            return m03Te;
        }

        public void setM03Te(String m03Te) {
            this.m03Te = m03Te;
        }

        public String getM02Te() {
            return m02Te;
        }

        public void setM02Te(String m02Te) {
            this.m02Te = m02Te;
        }

        public String getM01Te() {
            return m01Te;
        }

        public void setM01Te(String m01Te) {
            this.m01Te = m01Te;
        }

        public String getM005Te() {
            return m005Te;
        }

        public void setM005Te(String m005Te) {
            this.m005Te = m005Te;
        }

        public String getTsQcflg() {
            return tsQcflg;
        }

        public void setTsQcflg(String tsQcflg) {
            this.tsQcflg = tsQcflg;
        }

        public String getTs() {
            return ts;
        }

        public void setTs(String ts) {
            this.ts = ts;
        }

        public String getDmstMtphNo() {
            return dmstMtphNo;
        }

        public void setDmstMtphNo(String dmstMtphNo) {
            this.dmstMtphNo = dmstMtphNo;
        }

        public String getGndSttCd() {
            return gndSttCd;
        }

        public void setGndSttCd(String gndSttCd) {
            this.gndSttCd = gndSttCd;
        }

        public String getVs() {
            return vs;
        }

        public void setVs(String vs) {
            this.vs = vs;
        }

        public String getLcsCh() {
            return lcsCh;
        }

        public void setLcsCh(String lcsCh) {
            this.lcsCh = lcsCh;
        }

        public String getClfmAbbrCd() {
            return clfmAbbrCd;
        }

        public void setClfmAbbrCd(String clfmAbbrCd) {
            this.clfmAbbrCd = clfmAbbrCd;
        }

        public String getDc10LmcsCa() {
            return dc10LmcsCa;
        }

        public void setDc10LmcsCa(String dc10LmcsCa) {
            this.dc10LmcsCa = dc10LmcsCa;
        }

        public String getDc10Tca() {
            return dc10Tca;
        }

        public void setDc10Tca(String dc10Tca) {
            this.dc10Tca = dc10Tca;
        }

        public String getHr3Fhsc() {
            return hr3Fhsc;
        }

        public void setHr3Fhsc(String hr3Fhsc) {
            this.hr3Fhsc = hr3Fhsc;
        }

        public String getDsnw() {
            return dsnw;
        }

        public void setDsnw(String dsnw) {
            this.dsnw = dsnw;
        }

        public String getIcsr() {
            return icsr;
        }

        public void setIcsr(String icsr) {
            this.icsr = icsr;
        }

        public String getSsQcflg() {
            return ssQcflg;
        }

        public void setSsQcflg(String ssQcflg) {
            this.ssQcflg = ssQcflg;
        }

        public String getSs() {
            return ss;
        }

        public void setSs(String ss) {
            this.ss = ss;
        }

        public String getPsQcflg() {
            return psQcflg;
        }

        public void setPsQcflg(String psQcflg) {
            this.psQcflg = psQcflg;
        }

        public String getPs() {
            return ps;
        }

        public void setPs(String ps) {
            this.ps = ps;
        }

        public String getPaQcflg() {
            return paQcflg;
        }

        public void setPaQcflg(String paQcflg) {
            this.paQcflg = paQcflg;
        }

        public String getPa() {
            return pa;
        }

        public void setPa(String pa) {
            this.pa = pa;
        }

        public String getTd() {
            return td;
        }

        public void setTd(String td) {
            this.td = td;
        }

        public String getPv() {
            return pv;
        }

        public void setPv(String pv) {
            this.pv = pv;
        }

        public String getHmQcflg() {
            return hmQcflg;
        }

        public void setHmQcflg(String hmQcflg) {
            this.hmQcflg = hmQcflg;
        }

        public String getHm() {
            return hm;
        }

        public void setHm(String hm) {
            this.hm = hm;
        }

        public String getWdQcflg() {
            return wdQcflg;
        }

        public void setWdQcflg(String wdQcflg) {
            this.wdQcflg = wdQcflg;
        }

        public String getWd() {
            return wd;
        }

        public void setWd(String wd) {
            this.wd = wd;
        }

        public String getWsQcflg() {
            return wsQcflg;
        }

        public void setWsQcflg(String wsQcflg) {
            this.wsQcflg = wsQcflg;
        }

        public String getWs() {
            return ws;
        }

        public void setWs(String ws) {
            this.ws = ws;
        }

        public String getRnQcflg() {
            return rnQcflg;
        }

        public void setRnQcflg(String rnQcflg) {
            this.rnQcflg = rnQcflg;
        }

        public String getRn() {
            return rn;
        }

        public void setRn(String rn) {
            this.rn = rn;
        }

        public String getTaQcflg() {
            return taQcflg;
        }

        public void setTaQcflg(String taQcflg) {
            this.taQcflg = taQcflg;
        }

        public String getTa() {
            return ta;
        }

        public void setTa(String ta) {
            this.ta = ta;
        }

        public String getStnNm() {
            return stnNm;
        }

        public void setStnNm(String stnNm) {
            this.stnNm = stnNm;
        }

        public String getStnId() {
            return stnId;
        }

        public void setStnId(String stnId) {
            this.stnId = stnId;
        }

        public String getRnum() {
            return rnum;
        }

        public void setRnum(String rnum) {
            this.rnum = rnum;
        }

        public String getTm() {
            return tm;
        }

        public void setTm(String tm) {
            this.tm = tm;
        }

        @Override
        public String toString() {
            return "Item{" +
                    "  m03Te='" + m03Te + '\'' +
                    ", m02Te='" + m02Te + '\'' +
                    ", m01Te='" + m01Te + '\'' +
                    ", m005Te='" + m005Te + '\'' +
                    ", tsQcflg='" + tsQcflg + '\'' +
                    ", ts='" + ts + '\'' +
                    ", dmstMtphNo='" + dmstMtphNo + '\'' +
                    ", gndSttCd='" + gndSttCd + '\'' +
                    ", vs='" + vs + '\'' +
                    ", lcsCh='" + lcsCh + '\'' +
                    ", clfmAbbrCd='" + clfmAbbrCd + '\'' +
                    ", dc10LmcsCa='" + dc10LmcsCa + '\'' +
                    ", dc10Tca='" + dc10Tca + '\'' +
                    ", hr3Fhsc='" + hr3Fhsc + '\'' +
                    ", dsnw='" + dsnw + '\'' +
                    ", icsr='" + icsr + '\'' +
                    ", ssQcflg='" + ssQcflg + '\'' +
                    ", ss='" + ss + '\'' +
                    ", psQcflg='" + psQcflg + '\'' +
                    ", ps='" + ps + '\'' +
                    ", paQcflg='" + paQcflg + '\'' +
                    ", pa='" + pa + '\'' +
                    ", td='" + td + '\'' +
                    ", pv='" + pv + '\'' +
                    ", hmQcflg='" + hmQcflg + '\'' +
                    ", hm='" + hm + '\'' +
                    ", wdQcflg='" + wdQcflg + '\'' +
                    ", wd='" + wd + '\'' +
                    ", wsQcflg='" + wsQcflg + '\'' +
                    ", ws='" + ws + '\'' +
                    ", rnQcflg='" + rnQcflg + '\'' +
                    ", rn='" + rn + '\'' +
                    ", taQcflg='" + taQcflg + '\'' +
                    ", ta='" + ta + '\'' +
                    ", stnNm='" + stnNm + '\'' +
                    ", stnId='" + stnId + '\'' +
                    ", rnum='" + rnum + '\'' +
                    ", tm='" + tm + '\'' +
                    '}';
        }
    }

    public static class Header {
        @JsonProperty("resultMsg")
        private String resultMsg;
        @JsonProperty("resultCode")
        private String resultCode;

        public String getResultMsg() {
            return resultMsg;
        }

        public void setResultMsg(String resultMsg) {
            this.resultMsg = resultMsg;
        }

        public String getResultCode() {
            return resultCode;
        }

        public void setResultCode(String resultCode) {
            this.resultCode = resultCode;
        }
    }
}

2.  데이터 받을 서비스 코드 작성

* 여기서 URLEncoder 부분 'dataCd, dateCd ,startDt ,startHh ,endDt, endHh'를 활용하여 데이터 기간을 변경할 수 있습니다. 이 글에서는 하루씩 받기 위해서 소스코드가 작성되어 있으니, 필요에 따라 변형해서 사용하시면 될거 같습니다.

@Service
public class WeatherService {
    public String serviceKey = "서비스키 입력";
    /**
     *
     * @param year 시작 년도
     * @param month 시작 달
     * @param day 시작 일
     * @return
     * @throws IOException
     */
    public List<WthrHourDto.Item> getWthrDataListHour(String year, String month, String day) throws IOException {
        LocalDate startDt = LocalDate.of(Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(day)); // 시작일
        String strStartDt = startDt.format(DateTimeFormatter.ofPattern("yyyyMMdd")); // ex) 20220410
        LocalDate endDt = startDt.plusDays(1);
        String strEndDt = endDt.format(DateTimeFormatter.ofPattern("yyyyMMdd"));// ex) 20220411

        StringBuilder urlBuilder = new StringBuilder("http://apis.data.go.kr/1360000/AsosHourlyInfoService/getWthrDataList"); /*URL*/
        urlBuilder.append("?" + URLEncoder.encode("serviceKey", "UTF-8") + "=" + serviceKey); /*Service Key*/
        urlBuilder.append("&" + URLEncoder.encode("pageNo", "UTF-8") + "=" + URLEncoder.encode("1", "UTF-8")); /*페이지번호 Default : 10*/
        urlBuilder.append("&" + URLEncoder.encode("numOfRows", "UTF-8") + "=" + URLEncoder.encode("24", "UTF-8")); /*한 페이지 결과 수 Default : 1*/
        urlBuilder.append("&" + URLEncoder.encode("dataType", "UTF-8") + "=" + URLEncoder.encode("json", "UTF-8")); /*요청자료형식(XML/JSON) Default : XML*/
        urlBuilder.append("&" + URLEncoder.encode("dataCd", "UTF-8") + "=" + URLEncoder.encode("ASOS", "UTF-8")); /*자료 분류 코드(ASOS)*/
        urlBuilder.append("&" + URLEncoder.encode("dateCd", "UTF-8") + "=" + URLEncoder.encode("HR", "UTF-8")); /*날짜 분류 코드(HR)*/
        urlBuilder.append("&" + URLEncoder.encode("startDt", "UTF-8") + "=" + URLEncoder.encode(strStartDt, "UTF-8")); /*조회 기간 시작일(YYYYMMDD)*/
        urlBuilder.append("&" + URLEncoder.encode("startHh", "UTF-8") + "=" + URLEncoder.encode("00", "UTF-8")); /*조회 기간 시작시(HH)*/
        urlBuilder.append("&" + URLEncoder.encode("endDt", "UTF-8") + "=" + URLEncoder.encode(strEndDt, "UTF-8")); /*조회 기간 종료일(YYYYMMDD) (전일(D-1) 까지 제공)*/
        urlBuilder.append("&" + URLEncoder.encode("endHh", "UTF-8") + "=" + URLEncoder.encode("00", "UTF-8")); /*조회 기간 종료시(HH)*/
        urlBuilder.append("&" + URLEncoder.encode("stnIds", "UTF-8") + "=" + URLEncoder.encode("108", "UTF-8")); /*종관기상관측 지점 번호 (활용가이드 하단 첨부 참조)*/
        URL url = new URL(urlBuilder.toString());
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Content-type", "application/json");
        System.out.println("Response code: " + conn.getResponseCode());
        BufferedReader rd;
        if (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
            rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        } else {
            rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
        }
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = rd.readLine()) != null) {
            sb.append(line);
        }
        rd.close();
        conn.disconnect();

        String json = sb.toString();
        WthrHourDto wthrHourDto = new ObjectMapper().readValue(json, WthrHourDto.class);
//        System.out.println("wthrHourDto.getResponse().getBody().getNumOfRows() = " + wthrHourDto.getResponse().getBody().getNumOfRows());
//        System.out.println("wthrHourDto.getResponse().getBody().getTotalCount() = " + wthrHourDto.getResponse().getBody().getTotalCount());
        List<WthrHourDto.Item> items = wthrHourDto.getResponse().getBody().getItems().getItem();
        System.out.println("wthrHourDto.getResponse().getBody().getItems().getItem() = " + items);
        for (WthrHourDto.Item item : items) {
            System.out.println("item = " + item);
        }
        return items;
    }
}

3.  Controller 작성

@RestController
public class WeatherAPIController {

    private final WeatherService weatherService;

    public WeatherAPIController(WeatherService weatherService) {
        this.weatherService = weatherService;
    }

    @GetMapping("wthrhour")
    public ResponseEntity wthrhour(
            @PathParam("year") String year,
            @PathParam("month") String month,
            @PathParam("day") String day
    ) {
        List<WthrHourDto.Item> wthrDataListHour = null;
        try {
            wthrDataListHour = weatherService.getWthrDataListHour(year,month,day);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseEntity.ok().body(wthrDataListHour);
    }
}

4. 결과화면

 

블로그 이미지

미나미나미

,