반응형

환경 : SpringBoot 2.7, Intellij

목표 : profile 환경 변수를 기준으로 서로 다른 Property 를 적용

 

1. spring.config.activate.on-profile 을 사용하여 적용될 profile 을 명시

 

application.yml

default:
  string: default

custom:
  string: noProfile

application-custom.yml

custom:
  string: custom

spring:
  config:
    activate:
      on-profile: custom

application-local.yml

spring:
  config:
    activate:
      on-profile: local

 

 

 

2. 적용할 profile 환경 변수 설정

 

Edit Configurations -> Active profiles 설정

 

 

 

3. 결과

 

3.1) profile 설정 X

default.string = default

custm.string = noProfile

 

3.2) profile : local

default.string = default

custm.string = noProfile

 

3.3) profile : custom

default.string = default

custm.string = custom

 

 

반응형

'Java' 카테고리의 다른 글

[SpringBoot] Gradle 변수 Property 활용  (0) 2022.05.30
[MyBatis] List 형식 멤버 변수 조회  (0) 2021.02.12
[Spring] Web Cache 적용  (0) 2020.12.19
[SpringBoot] H2 연동  (0) 2020.07.21
[Spring] App 구동 후 자동 작업 실행  (0) 2020.02.23
반응형

작성일자 : 2022.05.29

환경 : SpringBoot, Gradle

시나리오 : Gradle 에서 할당한 변수를 서버 사이드에서 Property 로 활용

 

 

1. Gradle 설정 추가

build.gradle

...

processResources {
	filesMatching('**/application.properties') {
		expand(project.properties)
	}
}

...

해당 설정 추가 이후 gradle build 에 processResources 작업이 추가된다.

 

 

2. 변수 선언

build.gradle

...

version = '0.0.1-SNAPSHOT'
ext {
	index = '1'
	string = "gradleString"
}

...

 

 

3. property 설정

application.properties

...

version=${version}
gradleIndex=${ext.index}
gradleString=${ext.string}

...

build.gradle 에서 선언한 processResources 작업에서 알맞은 Property 에 Gradle 변수를 할당

 

 

4. 확인

In controller

@Value("${version}")
private String version;
@Value("${gradleIndex}")
private Integer gradleIndex;
@Value("${gradleString}")
private String gradleString;

...

System.out.println(version);
System.out.println(gradleIndex);
System.out.println(gradleString);

...

 

 

반응형

'Java' 카테고리의 다른 글

[Spring] Profile 기준 Property 구분 적용  (0) 2023.06.28
[MyBatis] List 형식 멤버 변수 조회  (0) 2021.02.12
[Spring] Web Cache 적용  (0) 2020.12.19
[SpringBoot] H2 연동  (0) 2020.07.21
[Spring] App 구동 후 자동 작업 실행  (0) 2020.02.23
반응형

작성일자 : 2021.03.06

환경 : Spring Boot 2.1.6, Gradle

 

 

1. 의존성 추가

 

build.gradle

implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'

 

 

2. jsp 설정 추가

 

application.properties

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

 

 

3. Controller 생성

 

JspController.java

@Controller
public class JspController {
    @GetMapping("/index")
    public String getIndex(){
        return "index";
    }
}

 

 

4. jsp 파일 생성

 

생성 경로 : src/main/webapp/WEB-INF/jsp/

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <div>JSP</div>
    </body>
</html>




5. 확인

 

 

반응형

'Java > 예제코드' 카테고리의 다른 글

[java] 소수점 표현 예제  (0) 2021.02.27
[Spring] 파일 업/다운로드 예제 코드  (0) 2021.02.20
반응형

Servlet

클라이언트의 요청을 처리하고 그 결과를 반환하는 자바 웹 프로그래밍 기술로 Servlet 클래스로 구현되어있다.

 

Servlet Container (Web Container)

Servlet, JSP 를 실행할 수 있는 소프트웨어 (Tomcat 등)을 의미함. 요청이 들어올 때마다 새로운 자바 스레드를 만들고 HttpServletRequest 와 HttpServletResponse 객체를 생성해 관리하며 알맞은 JSP 파일을 서블릿 파일로 변환한 뒤 컴파일하여 이것을 실행한 결과를 반환한다.

반응형

'Java > Basic' 카테고리의 다른 글

String / StringBuffer / StringBuilder  (0) 2020.10.02
다형성 / 오버로딩 / 오버라이딩  (0) 2020.10.02
추상클래스 / 인터페이스  (0) 2020.09.30
클래스 / 오브젝트 / 인스턴스  (0) 2020.09.26
반응형
System.out.println(a);                              
// 결과 : 0.987654321

System.out.println(Math.ceil(a * 100) / 100.0);     
// 결과 : 0.99

System.out.println(Math.round(a * 100) / 100.0);    
// 결과 : 0.

System.out.println(Math.floor(a * 100) / 100.0);    
// 결과 : 0.98

System.out.println(String.format("%.3f", a));       
// 결과 : 0.988

 

반응형

'Java > 예제코드' 카테고리의 다른 글

[Spring] JSP 설정  (0) 2021.03.06
[Spring] 파일 업/다운로드 예제 코드  (0) 2021.02.20
반응형

작성일자 : 2021.02.20

환경 : 자바8, Spring Boot 2, Chrome

1. 파일 업로드

 

HTML Code

...
  <form method="post" action="/uploadFile" enctype="multipart/form-data">
      <input type="file" name="file">
      <input type="submit">
  </form>
...

 

* submit 대신 Javascript 를 활용할 경우

 

...
	<form method="post" action="/uploadFile" enctype="multipart/form-data">
		<input type="file" name="file">
	</form>
	<button onclick="sendFile()">button</button>
...

<script>
    const sendFile = () => {
        const formElement = document.querySelector("form");
        const request = new XMLHttpRequest();
        request.open("POST", "/uploadFile");
        request.send(new FormData(formElement));
    }
</script>

 

 

Java code

@PostMapping("/uploadFile")
public void uploadFile(@RequestParam("file") MultipartFile file){
    // 파일 기본 정보
    System.out.println("file name : " + file.getOriginalFilename());
    System.out.println("file size : " + file.getSize());

    try(
    	// 프로젝트 폴더에 temp.jpg 이름으로 파일 생성
        FileOutputStream fos = new FileOutputStream("./temp.jpg"); 
        InputStream is = file.getInputStream()
    ){
        int readCount;
        byte[] buffer = new byte[1024];
        
        // 데이터 쓰기
        while((readCount = is.read(buffer)) != -1){
            fos.write(buffer, 0, readCount);
        }
    }catch(Exception e){
        e.printStackTrace();
    }
}

 

 

2. 파일 다운로드

Java code

@GetMapping("/downloadFile")
public void downloadFile(HttpServletResponse response) {

	// 프로젝트 폴더의 temp.jpg 파일 로드
	String fileName = "temp.jpg";
	File file = new File("./" + fileName);

	// 클라이언트에서 아래의 이름으로 파일이 받아진다.
	String newFileName = "newTemp.jpg";

    try (
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(fis);
        OutputStream out = response.getOutputStream()
    ){
    	// 응답이 파일 타입이라는 것을 명시
        response.addHeader("Content-Disposition", "attachment;filename=\""+newFileName+"\"");
        // 응답 크기 명시
        response.setContentLength((int)file.length());

        int read = 0;
        
        // 실제 데이터 전송
        // OutputStream 의 Deafult 버퍼 사이즈는 8192 Byte
        // 이 루프를 8000 번 정도 돌때마다 약 8KB 정도의 데이터가 전송 
        while((read = bis.read()) != -1) {
            out.write(read);
        }
        
    } catch(IOException e) {
        e.printStackTrace();
    }
}

 

---

 

* HTTP MultiPart 로 파일 전송시 formData 에서 확인이 불가능, 단 파일을 null 로 전달하면 확인 가능 (크롬 기준)

 

* form 에서 지정하는 enctype 속성은 아래 세가지의 값으로 지정될 수 있다.

 

1. application/x-www-form-urlencoded

디폴트 값. 폼데이터는 서버로 전송되기 전에 URL-Encode 됨

 

2. multipart/form-data

파일이나 이미지를 서버로 전송할 경우

 

3. text/plain

인코딩을 하지 않은 문자 상태로 전송

 

반응형

'Java > 예제코드' 카테고리의 다른 글

[Spring] JSP 설정  (0) 2021.03.06
[java] 소수점 표현 예제  (0) 2021.02.27
반응형

작성일자 : 2021.02.12

시나리오 : MyBatis 를 사용하여 DB 데이터를 조회할 때 1:M 관계를 가지는 데이터를 List 형태로 조회

환경 : Spring Boot, mybatis-spring-boot-starter 1.3.2

 

 

1. 조회 데이터 정의

 

Parent(1) : Child(M) 구조의 테이블 정의

 

1개의 Parent 데이터와, Parent 와 식별관계를 가지는 2개의 Child 데이터를 저장. Child 는 Parent 의 id 를 FK 로 가짐

 

 

2. 설정

 

* resultMap 을 활용

In Mapper.xml

<resultMap id="parentResultType" type="com.example.demo.Parent">
    <id column="PK 칼럼명" property="멤버 변수명"/>
    <result column="칼럼명" property="멤버 변수명"/>
    <collection property="childList" resultMap="childList"/>
</resultMap>

<resultMap id="childList" type="com.example.demo.Child>
    <id column="PK 칼럼명" property="멤버 변수명"/>
    <result column="칼럼명" property="멤버 변수명"/>
    <result column="칼럼명" property="멤버 변수명"/>
</resultMap>

<select id="selectId" resultMap="parentResultType">
   ...
</select>

 

Mapper.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.example.demo.TestMapper">
  
  <resultMap id="parentResultType" type="com.example.demo.Parent">
    <id column="parentId" property="id"/>
    <result column="parentValue" property="value"/>
    <collection property="childList" resultMap="childList"/>
  </resultMap>
  
  <resultMap id="childList" type="com.example.demo.Child">
    <id column="childId" property="id"/>
    <result column="parentId" property="parentId"/>
    <result column="childValue" property="value"/>
  </resultMap>

  <select id="selectParentList" resultMap="parentResultType">
    SELECT
      t1.id AS parentId
      , t1.value AS parentValue
      , t2.id AS childId
      , t2.value AS childValue
    FROM
      parent t1
    LEFT JOIN child t2
    ON t1.id = t2.parentId
  </select>
  
</mapper>

 

Parent.java

public class Parent {
    String id;
    String value;
    List<Child> childList = new ArrayList<>();
}

 

Child.java

public class Child {
    Integer id;
    Integer parentId;
    String value;
}

 

 

3. 확인

 

Mapper 에서 정의한 selectParentList 쿼리를 사용하여 1. 의 환경의 DB 에서 조회할 경우,

 

- 실제 쿼리 조회 내용

 

- 조회한 데이터 내용

 

중복이 제거되고 childList 형태의 멤버 변수가 조회됌 

반응형

'Java' 카테고리의 다른 글

[Spring] Profile 기준 Property 구분 적용  (0) 2023.06.28
[SpringBoot] Gradle 변수 Property 활용  (0) 2022.05.30
[Spring] Web Cache 적용  (0) 2020.12.19
[SpringBoot] H2 연동  (0) 2020.07.21
[Spring] App 구동 후 자동 작업 실행  (0) 2020.02.23
반응형

작성일자 : 2020.12.20

환경 : Spring Boot, Chrome

 

1. 개요

1.1) Web Cache(HTTP Cache)란? 

 

  • 서버 지연을 줄이는 목적으로 정적 리소스 등의 웹 문서들을 임시 저장하여 재활용하기 위한 기술
  • 어디에 적용하느냐에 따라 Browser Cache, Proxy Cache, Gateway Cache 로 구분지을 수 있음

 

- 웹 캐싱 방법

  • Response 에 Cache-Control Header 사용

 

 

1.2) Cache-Control ?

  • 서버와 브라우저 사이의 캐시 정책. 여러 지시자들을 사용하여 옵션을 설정할 수 있음 

 

크롬 개발자 도구에서 Cache-Control 헤더를 아래와 같이 확인 가능하다.

 

 

 

- Cache-Control 기본 지시자 

  • no-cache : 캐시 데이터가 있어도 무조건 서버로부터 유효성을 재검증함 (캐시를 사용하지 않는게 아님)
  • no-store : 캐시 데이터를 저장하지 않음 (캐시를 사용하지 않음)
  • max-age=[sec] : 캐시 데이터가 유효한 시간을 설정. 해당 시간이후에 캐시 데이터가 만료 
  • must-revalidate : 만료된 캐시 데이터를 무조건 서버로부터 유효성을 재검증함

 

- 캐싱 데이터 유효성 검증 방법 (ETag 활용)

  1. 브라우저가 서버로 첫 요청시, 서버는 응답에 해당하는 데이터와과 함께 Etag 를 반환 (이 떄 응답 데이터, Etag 는 캐싱)
  2. 브라우저가 서버로 재요청시, If-None-Match 헤더에 캐싱된 Etag 를 담아서 요청 전송
  3. 서버는 신규 요청에 의해 만들어진 Etag 와 If-None-Match  헤더에 담긴 Etag 를 비교하여, 다르면 새로운 Etag 와 함께 응답 반환. 동일하면 304(Not Modified) Return Code 를 반환

  4. 브라우저는 304(Not Modified) Return Code 반환 시 기존 캐싱 데이터를 활용하며, 200 Return Code 로 반환 시, 1. 으로 돌아감

 

 

1.3)  ETag(Entity Tag) ?

  • 웹 리소스의 특정버전에 할당한 식별자

 

- ETag 사용 예시 :

etag 구현체를 필터로 등록하여 사용. 해당 구현체가 필터에 등록되어 Request, Response 에 etag 를 부여/검증한다.

 

@Bean
public FilterRegistrationBean shallowEtagHeaderFilter() {
    FilterRegistrationBean frb = new FilterRegistrationBean();
    frb.setFilter(new ShallowEtagHeaderFilter());
    frb.addUrlPatterns("MY_PATH/*");
    return frb;
}

 

위처럼 ShallowEtagHeaderFilter 를 등록 시 Etag 를 생성 및 검증해주며, Etag 가 존재하면 동일 URI 재요청 시 자동으로 If-None-Match 헤더에 ETag 가 추가해준다.

 

 

2. 적용 예시

 

2.1 Cache Control 활용

 

* WebMvcConfigurer 를 활용하여 정적 리소스 경로를 설정하였다 가정

 

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        CacheControl cacheControl = CacheControl 
                .maxAge(60, TimeUnit.SECONDS) 
                .mustRevalidate();

        registry.addResourceHandler("**/*.js") 
                .addResourceLocations("classpath:/static/")
                .setCacheControl(cacheControl) 
                ;
    }
}

 

: 위 설정 이후, **/*.js 의 요청은 Cache 이 설정됨

 

 

index.html

 

<script src ="http://localhost:8080/test.js"></script>

 

 

- http://localhost:8080/ 첫 요청 시

 

index.html 반환 및 index.html 에 의해 test.js 요청

 

200 응답코드와 함께 설정한 Cache-Control 반환되며 해당 응답은 캐싱된다

 

 

 

- http://localhost:8080/ 두번째 요청 시

 

index.html 반환 및 index.html 에 의해 test.js 요청

 

요청이 캐싱 이후 60초 이내일 경우(max-age=60) 해당 캐시는 유효하다 판단하며 캐싱 데이터를 재사용한다

 

* 이 경우 서버와 통신하지 않기 때문에 데이터가 변경되더라도 브라우저에서는 알 수없음 

* 단 브라우저 URL 입력창에 직접 호출하는 경우, 무조건 서버와 통신하여 변경 여부를 체크 (Chrome)

* from memory cache, from disk cache 두 종류가 있는데, 일반적인 memory, disk 차이와 비슷하다 어디에 저장할지는 Chrome 이 결정 

 

 

 

2.2 Etag 활용

 

shallowEtagHeaderFilter 필터 설정

 

@Bean
public FilterRegistrationBean shallowEtagHeaderFilter() {
    FilterRegistrationBean frb = new FilterRegistrationBean();
    frb.setFilter(new ShallowEtagHeaderFilter());
    frb.addUrlPatterns("/*");
    return frb;
}

 

: 위 설정 이후, /* 의 요청은 Etag 가 설정됨

 

 

Cache-Control 설정

 

@RequestMapping("/")

public void getIndexPage(... HttpServletResponse response)
{

   ...

   response.setHeader("Cache-Control","no-cache");

   ...

}

 

 

 

 

- http://localhost:8080/ 첫 요청 시

 

Etag 와 함께 응답 반환

 

 

 

- http://localhost:8080/ 두번 째 요청 시

 

Request 에  Etag 를 함께 전송

 

 

 

Etag 검증 후 Not Modified(304) 반환

 

 

반응형

'Java' 카테고리의 다른 글

[SpringBoot] Gradle 변수 Property 활용  (0) 2022.05.30
[MyBatis] List 형식 멤버 변수 조회  (0) 2021.02.12
[SpringBoot] H2 연동  (0) 2020.07.21
[Spring] App 구동 후 자동 작업 실행  (0) 2020.02.23
Stream Example  (0) 2020.01.05
반응형

String 

- 불변

- 생성, 조회 가장 빠름

- Thread-safe(Immutable하기 때문)

- 데이터 변경 시 메모리를 새로 할당하여 참조

 

 

StringBuilder

- 가변

- 생성, 조회 String 보다 느림

- No Thread-safe

 

 

StringBuffer

- 가변

- 생성, 조회 StringBuilder 보다 느림

- Thread-safe(동기화 키워드 지원)

 

 

 

요약 : 

문자열 변경/연산이 잦을경우 -> StringBuffer, StringBuilder

단순 참조(조회)가 잦을경우 -> String

Multi-Thread 환경에서 사용할 경우 -> String, StringBuffer

반응형

'Java > Basic' 카테고리의 다른 글

Servlet / Servlet Container(Web Container)  (0) 2021.03.06
다형성 / 오버로딩 / 오버라이딩  (0) 2020.10.02
추상클래스 / 인터페이스  (0) 2020.09.30
클래스 / 오브젝트 / 인스턴스  (0) 2020.09.26
반응형

다형성(polymorphism)

객체지향개념에서의 다형성이란 '여러 가지 형태를 가질 수 있는 능력' 을 의미. 자바에서는 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 함으로써 다형성을 프로그램적으로 구현.

 

다형성 예시

- 조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 함 ( ex: List list = new ArrayList(); )

- 오버로딩을 통해 하나의 메서드가 인자에 따라 다른 역할을 수행

- 오버라이딩을 통해 하나의 메서드가 상속클래스와 자손클래스에서 각각 다른 역할을 수행

 

 

 

오버로딩이란?

한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것

 

ex)

void println(int x);

void println(long x);

 

 

 

오버라이딩이란?

부모클래스에서 정의한 메서드를 자식클래스에서 재정의하는 것

 

ex)

class A extends B {

   @Override

   BClassMethod(){

      ...

   }

}

반응형

'Java > Basic' 카테고리의 다른 글

Servlet / Servlet Container(Web Container)  (0) 2021.03.06
String / StringBuffer / StringBuilder  (0) 2020.10.02
추상클래스 / 인터페이스  (0) 2020.09.30
클래스 / 오브젝트 / 인스턴스  (0) 2020.09.26

+ Recent posts