728x90

출처

application.properties

#File upload settings
# support multipart uploads (default: true)
spring.servlet.multipart.enabled=true
# Threshold at which files are written to memory (default: 0B)
#spring.servlet.multipart.file-size-threshold=0B 
# Temporary storage space for uploaded files
spring.servlet.multipart.location=d:/usr/local/cnssm/resources
# Maximum size of the file (default: 1MB)
spring.servlet.multipart.max-file-size=10144MB
# Maximum size of request (default: 10MB)
spring.servlet.multipart.max-request-size=10144MB

FileStorageProperties.java

package com.bx.config.property;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties(prefix = "spring.servlet.multipart")
public class FileStorageProperties {

	private String location;

	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}
}

FileUploadController.java

package com.bx.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.stream.Collectors;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import com.bx.common.util.ExcelUtil;
import com.bx.config.property.FileStorageProperties;
import com.bx.service.FileStorageService;

@Controller
public class FileUploadController {

	@Autowired
	private FileStorageService fileStorageService;

	@Autowired
	private FileStorageProperties fileStorageProperties;

	@RequestMapping(value = "/bx/uploadFile", method = RequestMethod.POST)
	public String uploadFile(@RequestParam("file") MultipartFile file, ModelMap modelMap) {
		String fileName = fileStorageService.storeFile(file);
		modelMap.put("fileName", fileName);
		
		try {
			if (fileName != null && (fileName.endsWith(".xls") || fileName.endsWith(".xlsx"))) {
				FileInputStream fis = new FileInputStream(new File(fileStorageProperties.getLocation() + "/" + fileName));
				Workbook workbook = new XSSFWorkbook(fis);
				
				Sheet sheet = workbook.getSheetAt(0); // 첫 번째 시트 가져오기
				
				// 행 반복 (첫 번째 행부터 마지막 행까지)
				for (Row row : sheet) {
					// 열 반복 (첫 번째 열부터 마지막 열까지)
					for (Cell cell : row) {
						// 셀 값 출력
						System.out.print(ExcelUtil.getCellValue(cell) + "\t");
					}
					System.out.println(); // 행 끝나면 줄바꿈
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return "bx/uploadOk";
	}

	@RequestMapping(value = "/uploadMultipleFiles", method = RequestMethod.POST)
	public String uploadMultipleFiles(@RequestParam("files") MultipartFile[] files, ModelMap modelMap) {
		Arrays.asList(files).stream().map(file -> uploadFile(file, modelMap)).collect(Collectors.toList());

		return "bx/uploadOk";
	}

}

FileStorageService.java

package com.bx.service;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import com.bx.common.exception.FileNotFoundException;
import com.bx.common.exception.FileStorageException;
import com.bx.config.property.FileStorageProperties;

@Service
public class FileStorageService {

	private final Path fileStorageLocation;

	@Autowired
	public FileStorageService(FileStorageProperties fileStorageProperties) {
		this.fileStorageLocation = Paths.get(fileStorageProperties.getLocation()).toAbsolutePath().normalize();

		try {
			Files.createDirectories(this.fileStorageLocation);
		} catch (Exception ex) {
			throw new FileStorageException("Could not create the directory where the uploaded files will be stored.", ex);
		}
	}

	public String storeFile(MultipartFile file) {
		// Normalize file name
		String fileName = StringUtils.cleanPath(file.getOriginalFilename());

		try {
			// Check if the file's name contains invalid characters
			if (fileName.contains("..")) {
				throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
			}

			// Copy file to the target location (Replacing existing file with the same name)
			Path targetLocation = this.fileStorageLocation.resolve(fileName);
			Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);

			return fileName;
		} catch (IOException ex) {
			throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
		}
	}

	public Resource loadFileAsResource(String fileName) {
		try {
			Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
			Resource resource = new UrlResource(filePath.toUri());
			if (resource.exists()) {
				return resource;
			} else {
				throw new FileNotFoundException("File not found " + fileName);
			}
		} catch (MalformedURLException ex) {
			throw new FileNotFoundException("File not found " + fileName, ex);
		}
	}
}

FileNotFoundException.java

package com.bx.common.exception;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(HttpStatus.NOT_FOUND)
public class FileNotFoundException extends RuntimeException {

	private static final long serialVersionUID = 1L;
	
	public FileNotFoundException(String message) {
		super(message);
	}
	
	public FileNotFoundException(String message, Throwable cause) {
		super(message, cause);
	}
}

FileStorageException.java

package com.bx.common.exception;

public class FileStorageException extends RuntimeException {
	
	private static final long serialVersionUID = 1L;

	public FileStorageException(String message) {
		super(message);
	}
	
	public FileStorageException(String message, Throwable cause) {
		super(message, cause);
	}
}

HTML

<form method="post" action="<c:url value="/cnssm/uploadFile"/>" enctype="multipart/form-data">

  <div>
    file : <input type="file" name="file" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">
  </div>
  
  <input type="submit">

</form>
728x90
728x90

출처

Maven pom.xml 설정

Maven 배포시 프로파일 선택 옵션 : mvn clean package -P prod

  <build>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <excludes>
          <exclude>**/*.java</exclude>
        </excludes>
      </resource>
      <resource>
        <directory>src/main/resources/bluexmas-${profile}</directory>
        <excludes>
          <exclude>**/*.java</exclude>
        </excludes>
      </resource>
    </resources>
    
    <!-- 생략 -->  
  </build>
  
  <profiles>
    <profile>
      <id>dev</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <properties>
        <profile>dev</profile>
      </properties>
    </profile>
    <profile>
      <id>local</id>
      <properties>
        <profile>local</profile>
      </properties>
    </profile>
    <profile>
      <id>prod</id>
        <properties>
          <profile>prod</profile>
      </properties>
    </profile>
  </profiles>

src\main\resources\bluexmas-dev\config\config.properties

username=test
password=test!!

@Configuration 클래스 (PropertyConfig.java)

@Bean(name="config") : Bean 객체 config 이름으로 스프링 컨테이너에 로딩

package com.bluexmas.config;

import java.io.IOException;

import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

@Configuration
public class PropertyConfig {

	@Bean(name="config")
	public static PropertiesFactoryBean config() throws IOException {
		PropertiesFactoryBean pspc = new PropertiesFactoryBean();
		Resource[] resources = new PathMatchingResourcePatternResolver()
				.getResources("classpath:/config/config.properties");
		pspc.setLocations(resources);
		return pspc;
	}
}

Config 값 참조

@Resource(name="config") : config 이름의 Properties 객체 참조
@Value("#{config['username']}") : config 이름의 Properties 객체에서 username 값 참조

package com.bluexmas.controller;

import java.util.Properties;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class SampleController {
	
	@Resource(name="config")
	private Properties config;
	
	@Value("#{config['username']}")
	private String username;
	
	@ResponseBody
	@RequestMapping("/sample")
	public String sample() {
		System.out.println("username.1 = " + config.get("username"));
		System.out.println("username.2 = " + username);
		
		String data = "@ResponseBody 어노테이션을 통해 반환";
		return data;
	}
	
}
728x90
728x90

출처

Maven pom.xml 설정

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>2.1.1</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.6</version>
    </dependency>
    <!-- mybatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.2</version>
    </dependency>
    <!-- mybatis spring -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.4</version>
      <scope>provided</scope>
    </dependency>

application.properties

## MySQL
spring.datasource.driver-class-name=org.gjt.mm.mysql.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test_db?user=user1&useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&useSSL=false
spring.datasource.username=user1
spring.datasource.password=user1!!

# 패키지 result tpye에 명을 생략할 수 있도록 alias 설정
mybatis.type-aliases-package=com.bluexmas.domain

# model 프로퍼티 camel case 설정
# mybatis.configuration.map-underscore-to-camel-case=true

# Mybatis mapper 위치 설정
mybatis.mapper-locations=classpath:/**/**.xml

Domain

package com.bluexmas.domain;

import java.sql.Date;

import lombok.Data;

@Data
public class Notice {
	
	// pk
	private int notice_no;
	
	private String notice_type;
	private String title;
	private String content;
	private int hit;
	private int reg_no;
	private Date reg_dt;
	private Date upt_dt;
	private String del_yn;
	private Date del_dt;
	
}

Persistence

package com.bluexmas.persistence;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Mapper;

import com.bluexmas.domain.Notice;

@Mapper
public interface NoticeMapper {

	public Notice selectNotice(Map<String, Object> params);

	public int insertNotice(Notice notice);

	public int updateNotice(Notice notice);

	public int deleteNotice(Map<String, Object> params);

	public int getCount();

	public List listNotice(Map<String, Object> map);

}

Service

package com.bluexmas.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bluexmas.domain.Notice;
import com.bluexmas.persistence.NoticeMapper;

@Service
public class NoticeService {

	@Autowired
	private NoticeMapper noticeMapper;

	public Notice selectNotice(int noticeNo) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("notice_no",noticeNo);
		return noticeMapper.selectNotice(params);
	}

	public int insertNotice(Notice notice) {
		return noticeMapper.insertNotice(notice);
	}

	public int updateNotice(Notice notice) {
		return noticeMapper.updateNotice(notice);
	}

	public int deleteNotice(int noticeNo) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("notice_no",noticeNo);
		return noticeMapper.deleteNotice(params);
	}

	public int getCount() {
		return noticeMapper.getCount();
	}

	public List listNotice() throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		return noticeMapper.listNotice(params);
	}
}

src\main\mybatis\com\bluexmas\persistence\NoticeMapper.xml

<?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.bluexmas.persistence.NoticeMapper">

	<!-- selectNotice -->
	<select id="selectNotice" parameterType="map" resultType="com.bluexmas.domain.Notice">
		select *
		  from notice
		 where notice_no = #{notice_no}
	</select>

	<!-- insertNotice -->
	<insert id="insertNotice" parameterType="com.bluexmas.domain.Notice" statementType="PREPARED">
		insert into notice(
		    <trim suffixOverrides=",">
		      <if test="notice_type != null">notice_type ,</if>
		      <if test="title != null">title ,</if>
		      <if test="content != null">content ,</if>
		      <if test="hit != null">hit ,</if>
		      <if test="reg_no != null">reg_no ,</if>
		      <if test="reg_dt != null">reg_dt ,</if>
		      <if test="upt_dt != null">upt_dt ,</if>
		      <if test="del_yn != null">del_yn ,</if>
		      <if test="del_dt != null">del_dt ,</if>
		    </trim>
		    ) values (
		    <trim suffixOverrides=",">
		      <if test="notice_type != null">#{notice_type, jdbcType=VARCHAR} ,</if>
		      <if test="title != null">#{title, jdbcType=VARCHAR} ,</if>
		      <if test="content != null">#{content, jdbcType=VARCHAR} ,</if>
		      <if test="hit != null">#{hit, jdbcType=INTEGER} ,</if>
		      <if test="reg_no != null">#{reg_no, jdbcType=INTEGER} ,</if>
		      <if test="reg_dt != null">#{reg_dt, jdbcType=TIMESTAMP} ,</if>
		      <if test="upt_dt != null">#{upt_dt, jdbcType=TIMESTAMP} ,</if>
		      <if test="del_yn != null">#{del_yn, jdbcType=VARCHAR} ,</if>
		      <if test="del_dt != null">#{del_dt, jdbcType=TIMESTAMP} ,</if>
		    </trim>
		)
		<selectKey keyProperty="notice_no" resultType="Integer">
			SELECT LAST_INSERT_ID()
		</selectKey>
	</insert>

	<!-- updateNotice -->
	<update id="updateNotice" parameterType="com.bluexmas.domain.Notice" statementType="PREPARED">
		update notice
		    <trim prefix="SET" suffixOverrides=",">
		      <if test="notice_type != null">notice_type = #{notice_type, jdbcType=VARCHAR} ,</if>
		      <if test="title != null">title = #{title, jdbcType=VARCHAR} ,</if>
		      <if test="content != null">content = #{content, jdbcType=VARCHAR} ,</if>
		      <if test="hit != null">hit = #{hit, jdbcType=INTEGER} ,</if>
		      <if test="reg_no != null">reg_no = #{reg_no, jdbcType=INTEGER} ,</if>
		      <if test="reg_dt != null">reg_dt = #{reg_dt, jdbcType=TIMESTAMP} ,</if>
		      <if test="upt_dt != null">upt_dt = #{upt_dt, jdbcType=TIMESTAMP} ,</if>
		      <if test="del_yn != null">del_yn = #{del_yn, jdbcType=VARCHAR} ,</if>
		      <if test="del_dt != null">del_dt = #{del_dt, jdbcType=TIMESTAMP} ,</if>
		    </trim>
		 where notice_no = #{notice_no}
	</update>

	<!-- deleteNotice -->
	<delete id="deleteNotice" parameterType="map" statementType="PREPARED">
		delete from notice
		 where notice_no = #{notice_no}
	</delete>

	<!-- getCount -->
	<select id="getCount" resultType="int">
		select count(*)
		  from notice
	</select>

	<!-- listNotice -->
	<select id="listNotice" parameterType="map" resultType="com.bluexmas.domain.Notice">
		select a.*
		  FROM notice a
	</select>

</mapper>

Controller 소스

package com.bluexmas.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.bluexmas.domain.Notice;
import com.bluexmas.service.NoticeService;

@Controller
public class NoticeController {

	@Autowired
	private NoticeService noticeService;
	
	@RequestMapping(value="/notice_list.do", method=RequestMethod.GET)
	public @ResponseBody Map<String, Object> notice_list(ModelMap modelMap) throws Exception {
		//
		Map<String, Object> result = new HashMap<> ();
		
		//
		List<Notice> listNotice = noticeService.listNotice();
		result.put("notice_list", listNotice);
		
		//
		return result;
	}
}

실행

728x90
728x90

출처

Maven pom.xml 설정

    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>2.2.4.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-tomcat -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <version>3.1.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-jasper -->
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-jasper</artifactId>
      <version>9.0.31</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

Spring Boot JSP ViewResolver 구성

JSP 파일 위치를 해결하려면 두 가지 방법을 사용할 수 있습니다.

1) application.properties에 항목 추가

#http port
server.port=7070

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

2) JSP 페이지를 제공하도록 InternalResourceViewResolver 구성

package com.bluexmas.config;
 
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
 
@Configuration
@EnableWebMvc
@ComponentScan
public class MvcConfiguration extends WebMvcConfigurerAdapter
{
  @Override
  public void configureViewResolvers(ViewResolverRegistry registry) {
    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    resolver.setPrefix("/WEB-INF/view/");
    resolver.setSuffix(".jsp");
    resolver.setViewClass(JstlView.class);
    registry.viewResolver(resolver);
  }
}

Controller 소스

package com.bluexmas.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class SampleController {
	
	/*
	 * 스프링부트에서의 jsp 호출 테스트
	 */
	@RequestMapping("/jspSample")
	public String jspSample(ModelMap modelMap) throws Exception {
		modelMap.put("name", "홍길동");

		List jspSample = new ArrayList();
		jspSample.add("국어 : 100점");
		jspSample.add("수학 : 90점");
		jspSample.add("영어 : 75점");

		modelMap.put("list", jspSample);
		
		return "jspSample";
	}
}

View(JSP) - src\main\webapp\WEB-INF\jsp\jspSample.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
 
<html>
<head>
<meta charset="UTF-8">
    <title>JSP Sample Page</title>
</head>
    <body>
 
       <div>[${name}]님의 시험성적입니다.</div>
 
        <c:forEach var="item" items="${list}">
         ${item} <br />
        </c:forEach>
 
    </body>
</html>

실행

728x90
728x90

출처

Maven pom.xml 설정

    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>2.2.4.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-tomcat -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <version>3.1.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-jasper -->
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-jasper</artifactId>
      <version>9.0.31</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

Spring Boot main 소스

Spring Boot main 소스 하위 패키지만 자동으로 로딩(Controller, Service)

package com.bluexmas;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
//@ComponentScan(basePackages = {"com.bluexmas.controller"})
public class BluexmasApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(BluexmasApplication.class, args);
    }
    
}

Controller 소스

package com.bluexmas.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class SampleController {
	
	@ResponseBody
	@RequestMapping("/sample")
	public String sample() {
		String data = "@ResponseBody 어노테이션을 통해 반환";
		return data;
	}

}

실행

728x90
728x90

출처

pom.xml

  <dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>2.2.4.RELEASE</version>
    </dependency>
  </dependencies>

SpringBootApplication

package com.bluexmas.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class BluexmasApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(BluexmasApplication.class, args);
    }
    
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        //return super.configure(builder);
        return builder.sources(BluexmasApplication.class);
    }
}

resources\config\application-dev.properties

#http port
server.port=7070

Spring Profile 설정

-Dspring.profiles.active=dev

실행로그

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.4.RELEASE)

2023-06-04 15:34:47.637  INFO 13456 --- [           main] c.bluexmas.example.BluexmasApplication   : Starting BluexmasApplication on DESKTOP-F8HR1P3 with PID 13456 (D:\project2\phEMS\workspace.ems\spring-boot-example1\target\classes started by bluesanta in D:\project2\phEMS\workspace.ems\spring-boot-example1)
2023-06-04 15:34:47.640  INFO 13456 --- [           main] c.bluexmas.example.BluexmasApplication   : The following profiles are active: dev
2023-06-04 15:34:49.054  INFO 13456 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 7070 (http)
2023-06-04 15:34:49.064  INFO 13456 --- [           main] o.apache.catalina.core.StandardService   : 서비스 [Tomcat]을(를) 시작합니다.
2023-06-04 15:34:49.064  INFO 13456 --- [           main] org.apache.catalina.core.StandardEngine  : 서버 엔진을 시작합니다: [Apache Tomcat/9.0.31]
2023-06-04 15:34:49.299  INFO 13456 --- [           main] org.apache.jasper.servlet.TldScanner     : 적어도 하나의 JAR가 TLD들을 찾기 위해 스캔되었으나 아무 것도 찾지 못했습니다. 스캔했으나 TLD가 없는 JAR들의 전체 목록을 보시려면, 로그 레벨을 디버그 레벨로 설정하십시오. 스캔 과정에서 불필요한 JAR들을 건너뛰면, 시스템 시작 시간과 JSP 컴파일 시간을 단축시킬 수 있습니다.
2023-06-04 15:34:49.307  INFO 13456 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-06-04 15:34:49.307  INFO 13456 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1606 ms
2023-06-04 15:34:49.480  INFO 13456 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2023-06-04 15:34:49.644  INFO 13456 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 7070 (http) with context path ''
2023-06-04 15:34:49.648  INFO 13456 --- [           main] c.bluexmas.example.BluexmasApplication   : Started BluexmasApplication in 2.423 seconds (JVM running for 2.838)
728x90
728x90

출처

ChatGPT 플러그인 설치

Repository 정보 입력

Name : OpenAI
Location : https://www.micegroup.it/openai-site/site.xml

OpenAI API 키 입력

https://platform.openai.com/account/api-keys 에서 API Key 생성 하기

API Key 적용

예제 만들기

코드 생성용 질문 만들기

1. 이미지 파일을 파라미터로 입력받고 이 이미지파일의 썸내일 이미지를 생성해서 반환하는 generateThumbnail 함수 작성
2. 파일명을 상수로 사용해서 generateThumbnail 호출하고 BufferedImage로 반환 받아서 파일로 저장하는 main 함수 작성

ChatGPT에 Java 코드 생성 요청

자동으로 생성된 Java 코드

728x90
728x90

Spring MVC : 파일 다운로드

package com.bluexmas.ui.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.bluexmas.util.ConfigUtils;
import com.bluexmas.util.FileUtilsEx;

@Controller
public class ExcelDownloadController {

  private static final Logger logger = LoggerFactory.getLogger(CommonAcountController.class);

  private static final int COMPRESSION_LEVEL = 3;

  private static final int BUFFER_SIZE = 1024 * 2;

  @RequestMapping(value = { "/app/download.do", "/{app}/app/download.do" })
  public void download(HttpServletRequest request, HttpServletResponse response) throws IOException {
    
    // 다운로드 파일명 설정
    this.setDownloadFilename("bluexmas.png", request, response);
    
    InputStream is = null;
    BufferedInputStream fin = null;
    BufferedOutputStream outs = null;

    try {
      File sourceFile = new File(ConfigUtils.getConfigPath(), "bluexmas.png");
      is = new FileInputStream(sourceFile);
      fin = new BufferedInputStream(is);
      outs = new BufferedOutputStream(response.getOutputStream());
      int read = 0;
      
      byte[] buffer = new byte[BUFFER_SIZE];
      while ((read = fin.read(buffer)) != -1) {
        outs.write(buffer, 0, read);
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (outs != null) outs.close();
      if (fin != null) fin.close();
      if (is != null) is.close();
    }
  }

  @RequestMapping(value = { "/app/zip_download.do", "/{app}/app/zip_download.do" })
  public void zip_download(HttpServletRequest request, HttpServletResponse response) throws Exception {
    //
    ZipArchiveOutputStream zos = null;
    
    try {
      zos = new ZipArchiveOutputStream(response.getOutputStream());
      zos.setEncoding("UTF-8");
      zos.setLevel(COMPRESSION_LEVEL); // 압축 레벨 - 최대 압축률은 9, 디폴트 8
      
      String zipName = FileUtilsEx.cleanDirName("bluexmas.zip");
      this.setDownloadFilename(zipName, request, response);
      
      File sourceFile = new File(ConfigUtils.getConfigPath(), "bluexmas.png");
      this.compress(zos, sourceFile, "santa.png");
      
      zos.finish();
      int file_size = (int) zos.getBytesWritten();
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
    }
  }

  // 압축파일에 파일 주가
  private void compress(ZipArchiveOutputStream zos, File sourceFile, String zipName) throws IOException {
    BufferedInputStream bis = null;

    try {
      bis = new BufferedInputStream(new FileInputStream(sourceFile));
      ZipArchiveEntry zentry = new ZipArchiveEntry(zipName);
      
      if (sourceFile != null)
        zentry.setTime(sourceFile.lastModified());
      
      zos.putArchiveEntry(zentry);

      byte[] buffer = new byte[BUFFER_SIZE];
      int cnt = 0;
      while ((cnt = bis.read(buffer, 0, BUFFER_SIZE)) != -1) {
        zos.write(buffer, 0, cnt);
      }
      zos.closeArchiveEntry();

    } catch (Exception e) {
      logger.error(e.getMessage(), e);
    } finally {
      if (bis != null) {
        bis.close();
      }
    }
  }

  // 다운로드 파일명 설정
  private void setDownloadFilename(String fileName, HttpServletRequest request, HttpServletResponse response)
      throws UnsupportedEncodingException {
    String header = getBrowser(request);
    if (header.contains("MSIE")) {
      String docName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
      response.setHeader("Filename-Encoding", "urlencode");
      response.setHeader("Content-Disposition", "attachment;filename=" + docName + ";");
    } else if (header.contains("Firefox")) {
      String docName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
      response.setHeader("Content-Disposition", "attachment; filename=\"" + docName + "\"");
    } else if (header.contains("Opera")) {
      String docName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
      response.setHeader("Content-Disposition", "attachment; filename=\"" + docName + "\"");
    } else if (header.contains("Chrome")) {
      String docName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
      response.setHeader("Content-Disposition", "attachment; filename=\"" + docName + "\"");
    }
    response.setHeader("Content-Type", "application/octet-stream");
    response.setHeader("Content-Transfer-Encoding", "binary;");
    response.setHeader("Pragma", "no-cache;");
    response.setHeader("Expires", "-1;");
    // response.setHeader("filesize", file_size+";");
    response.setHeader("dn_filename", URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20"));
  }

  // 브라우져 확인
  private String getBrowser(HttpServletRequest request) {
    String header = request.getHeader("User-Agent");
    if (header.contains("MSIE") || header.contains("Trident") || header.contains("Dalvik")) {
      return "MSIE";
    } else if (header.contains("Chrome")) {
      return "Chrome";
    } else if (header.contains("Opera")) {
      return "Opera";
    }
    return "Firefox";
  }

}
728x90

+ Recent posts