Ajax 통신 시 로딩바를 구현하는 방법은 여러 많은 블로그에서 확인할 수 있다.

여기서는 submit이나 location.href와 같은 페이지 이동 시 로딩바를 구현하는 방법에 대해 알아보자

 

1. 로딩바 gif 파일 다운로드

loadingbar.gif

 

 

2. 프로젝트 이미지 폴더 안에 로딩바 gif 파일 넣기 (ex : img src='/images/loadingbar.gif')

 

 

3. script 태그 안 submit or location.href 전에 로딩바와 로딩 시 보여줄 배경 추가 후 보여주기

<script type="text/javascript">

	function save() {
		var backHeight = $(document).height(); // 로딩 시 보여줄 배경 높이
	   	var backWidth = window.document.body.clientWidth; // 로딩 시 보여줄 배경 너비
	   	var backGroundCover = "<div id='back'></div>";
	   	var loadingBarImage = "";
	   	loadingBarImage += "<div id='loadingBar'>";
		loadingBarImage += "     <img src='/images/loadingbar.gif' width='100' height='100'/>"; // 로딩바 이미지
		loadingBarImage += "</div>";
		$('body').append(backGroundCover).append(loadingBarImage);
		$('#back').css({ 'width':backWidth, 'height':backHeight, 'opacity':'0.3' });
		$('#back').show();
		$('#loadingBar').show();
		
		// 1. submit
		$('#saveForm').attr('method', 'POST');
		$('#saveForm').attr('action', '/save');
		$('#saveForm').submit();
		
		// 2. location.href
		var url = '/save'; 
		location.href = url;
	}
    
</script>

 

 

4. style 태그 안 코드 추가

<style type="text/css">

	#back {
		position:absolute;
		z-index:100;
		background-color:#000000;
		display:none;
		left:0;
		top:0;
	}
    
	#loadingBar { 
		position:absolute;
		left:50%;
		top:40%;
		display:none;
		z-index:200;
	}
    
</style>

 

 

Ajax 통신 시 complete 시점에서 아래 코드가 필요하지만 submit or location.href의 경우 페이지 이동에 의해

로딩바와 로딩 시 보여준 배경이 자동으로 숨김 및 제거된다.

$('#back, #loadingBar').hide();
$('#back, #loadingBar').remove();

 

<MySQL>

SHOW CREATE FUNCTION 함수명;

SHOW CREATE PROCEDURE 프로시저명;

SHOW CREATE TRIGGER 트리거명;

SHOW CREATE SEQUENCE 시퀀스명;

SHOW CREATE VIEW 뷰명;

<Oracle>

SELECT DBMS_METADATA.GET_DDL('FUNCTION', '함수명') AS FUNCTION_SRC
FROM DUAL;

SELECT DBMS_METADATA.GET_DDL('PROCEDURE', '프로시저명') AS FUNCTION_SRC
FROM DUAL;

SELECT DBMS_METADATA.GET_DDL('TRIGGER', '트리거명') AS FUNCTION_SRC
FROM DUAL;

SELECT DBMS_METADATA.GET_DDL('SEQUENCE', '시퀀스명') AS FUNCTION_SRC
FROM DUAL;

SELECT DBMS_METADATA.GET_DDL('VIEW', '뷰명') AS FUNCTION_SRC
FROM DUAL;

Web Server

Web Browser로부터 HTTP 요청을 받아 HTML 문서와 같은 정적 콘텐츠를 제공하기 위한 서버

(정적 콘텐츠 : HTML, CSS, IMAGE 등 어느 사용자의 요청이든 항상 동일한 콘텐츠)

 

Web Server는 Client로부터의 HTTP 요청을 받아 그 요청에 맞게 두 가지 중 하나를 선택하여 제공할 수 있다.

 

[Web Server의 기능]

정적인 콘텐츠 요청 시 : 정적 콘텐츠(HTML, CSS, IMAGE 등)를 제공할 수 있다.(WAS를 거치지 않고 바로 자원 제공)
동적인 콘텐츠 요청 시 : Client의 요청을 WAS(Web Application Server)로 보내고 WAS가 처리한 결과를 Client에게 전달하여 제공할 수 있다.

 

[Web Server의 예]

Apache, Nginx 등

 

WAS(Web Application Server)

DB 조회나 다양한 로직 처리를 요구하는 동적인 콘텐츠를 제공하기 위한 서버

 

HTTP를 통해 컴퓨터나 장치에 Application을 수행해 주는 미들웨어(소프트웨어 엔진)로

'웹 컨테이너(Web Container)' 또는 '서블릿 컨테이너(Servlet Container)'라고도 불린다.
(WAS = Web Server + Web Container)

 

[WAS의 기능]

Client로부터 HTTP 요청을 받을 수 있다.
요청에 맞는 정적 콘텐츠를 제공할 수 있다.
DB 조회나 다양한 로직 처리를 통해 동적 콘텐츠를 제공할 수 있다.
Web Server 기능들을 구조적으로 분리해 처리하고자 하는 목적으로 제시되었다.
(분산 트랜잭션, 보안, 메시징, 스레드 처리 등의 기능을 처리하는 분산 환경에서 사용 & 주로 DB 서버와 같이 수행)

 

[WAS의 예]

Tomcat, Jeus, JBoss, Web Sphere 등

 

[Web Server가 필요한 이유]

IMAGE 파일과 같은 정적인 파일들은 웹 문서(HTML 문서)가 Client로 보내질 때 함께 가는 것이 아니다.
Client는 HTML 문서를 먼저 받고 그에 맞게 필요한 IMAGE 파일들을 다시 서버로 요청하면 그제야 IMAGE 파일들을 받아오는 것이다.
Web Server를 통해 정적인 파일들은 WAS까지 가지 않고 앞단에서 빠르게 보내줄 수 있다.

 

[WAS가 필요한 이유]

웹 페이지에는 정적 콘텐츠와 동적 콘텐츠가 모두 존재한다.

이때, 사용자의 요청에 맞는 적절한 동적 콘텐츠를 제공할 수 있어야 하는데 Web Server만을 이용하여 제공하고자 한다면 사용자의 요청에 대한 결과값을 모두 미리 알고, 정적 콘텐츠를 만들어 놓은 상태에서 제공해야 하며 이는 사실상 불가능한 일이다. 따라서 WAS를 통해 요청에 맞는 데이터를 DB로부터 가져오고 비즈니스 로직에 따라 그때그때 결과를 만들어서 제공하는 것으로 자원을 효율적으로 사용할 수 있다.

 

[결론]

Web Server를 별도로 운영하는 이유는 WAS의 부담을 줄여주기 위함이다. HTML, CSS, IMAGE 등 정적인 파일들을 굳이 동적인 처리까지 담당하는 WAS까지 가지 않고 앞단에서 빠르게 보내어 서버의 부담을 줄이는 것이다.
따라서 Web Server를 통해 정적 콘텐츠만 처리하도록 기능을 분배하여 WAS의 부담을 줄일 수 있다.

 

[웹 서비스의 다양한 아키텍처 구조]

Client -> Web Server -> DB
Client -> WAS -> DB
Client -> Web Server -> WAS -> DB
Client -> Web Server -> 여러 개의 WAS -> DB

 

Web Server를 WAS 앞에 두고, 필요한 WAS들을 Web Server에 플러그인 형태로 설정하면 효율적인 분산 처리가 가능하다.

컬럼1, 컬럼2가 PK일 때

 

<MySQL>

INSERT INTO 테이블명
(
    컬럼1
  , 컬럼2
  , 컬럼3
  , 컬럼4
  , 컬럼5
)
VALUES
(
    값1
  , 값2
  , 값3
  , 값4
  , 값5
)
ON DUPLICATE KEY UPDATE
(
    컬럼3 = 값3
  , 컬럼4 = 값4
  , 컬럼5 = 값5
);

<Oracle>

MERGE INTO 테이블명
USING DUAL ON (컬럼1 = 값1 AND 컬럼2 = 값2)
WHEN MATCHED THEN
UPDATE SET
(
    컬럼3 = 값3
  , 컬럼4 = 값4
  , 컬럼5 = 값5
)
WHEN NOT MATCHED THEN
INSERT
(
    컬럼1
  , 컬럼2
  , 컬럼3
  , 컬럼4
  , 컬럼5
)
VALUES
(
    값1
  , 값2
  , 값3
  , 값4
  , 값5
);

서버의 구동 시간이 톰캣의 기본 설정 시간제한인 45초보다 길어서 발생한 오류이다.

 

 

1. Servers 탭에서 해당 서버 더블 클릭

2. Tomcat 서버 Overview에서 Timeouts 메뉴 찾아서 펼치기

3. Start (in seconds) 수정하기

 

모바일 서비스의 4가지 대표 개발 방식에는

네이티브 앱(Native App), 하이브리드 앱(Hybrid App), 웹 앱(Web App), 모바일 웹(Mobile Web)이 있다.

각각의 특징 및 장단점에 대해 알아보자.

 

네이티브 앱(Native App) : 모바일 기기에 최적화된 네이티브 언어로 개발된 앱(App)

특징 : 개발 - 해당 운영체제에 최적화되어 있는 개발 도구로 제작

          실행 - 구글 플레이스토어, 앱스토어에서 다운 설치

          안드로이드 SDK - Kotlin / Java

          IOS SDK - Swift / Objective C

장점 : 높은 퍼포먼스, 더 많은 디바이스 접근 권한, 빠른 속도와 안정성

단점 : 각 운영체제마다 개발 및 유지 보수 필요 -> 운영체제별 개발 인력 필요

          높은 개발 & 운영 비용, 심사과정 필요, 업데이트할 때마다 플레이스토어, 앱스토어를 통해야 함

(고성능의 그래픽 처리가 가능해서  2D 및 3D 게임이나 증강현실과 같은 앱 개발을 할 수 있음, 모바일의 고유 정보 이용 & 하드웨어 제어 가능)

 

하이브리드 앱(Hybrid App) : 웹 앱과 네이티브 앱의 기능을 결합하여 개발된 앱(App)으로 하나의 코드 베이스로

IOS, Android에서 모두 작동

특징 : 개발 - 모바일 웹 앱을 모바일 운영체제로 패키징(내부는 모바일 웹 앱 / 외부는 네이티브 모습)

          실행 - 구글 플레이스토어, 앱스토어에서 다운 설치

          웹 브라우저로 접속한 것과 차이 없음 But QR 코드 리더, 음성 인식 등 지원

장점 : 네이티브 API와 브라우저 API를 이용해 다양한 개발 가능

          개발 비용 & 시간 절감(네이티브 앱에 비해), 쉬운 유지 보수(네이티브 앱에 비해)

          모바일 웹보다 빠른 속도, 디바이스 고유 정보 접근 가능

단점 : 제한적 기능, 네이티브 앱보다 느린 속도, 네이티브 앱 개발 지식 필요, 심사과정 필요

          브라우저 성능에 따라 앱 성능에 영향

(웹 앱의 단점을 보완, 앱의 기반이 되는 콘텐츠 영역은 HTML 기반의 웹 앱으로 제작, 최종 앱 배포에 필요한 패키징 처리만 Android, IOS 플랫폼 안에서 처리, 모바일의 고유 정보 이용 & 하드웨어 제어 가능)

 

웹 앱(Web App) : 모바일 웹과 비슷하지만 구동 방식이 앱처럼 보이게 한 앱(App)

특징 : 개발 - 웹 개발 방식과 동일(HTML, CSS, JavaScript 등)

          실행 - 웹 브라우저(단일 페이지 방식)

          겉모습과 구동 방식이 마치 네이티브 같은 웹 페이지(모바일 웹보다 모바일 최적화)

장점 : 운영체제별로 개발할 필요가 없음 -> 비용 & 시간 절감, 심사과정 불필요

단점 : 디바이스 접근 권한 제한, 웹 브라우저에서 검색하거나 URL로 접근해야 함

(모바일 웹과 네이티브 앱을 결합한 것으로 모바일 웹의 특징을 가지면서 네이티브 앱의 일부 장점도 가짐, 모바일의 고유 정보 이용 불가 & 하드웨어 제어 불가)

 

모바일 웹(Mobile Web) : 모바일 화면에 맞게 구성한 웹(Web)

특징 : 개발 - 웹 개발 방식과 동일(HTML, CSS, JavaScript 등)

          실행 - 웹 브라우저(풀 브라우저 방식)

           PC 웹 페이지를 모바일에 맞게 줄인 모습

장점 : 운영체제별로 개발할 필요가 없음 -> 비용 & 시간 절감, 심사과정 불필요

단점 : 디바이스 접근 권한 제한, 웹 브라우저에서 검색하거나 URL로 접근해야 함

(데스크탑 브라우저에서 실행되는 웹 애플리케이션을 모바일 스크린 크기로 줄여 놓은 것, 모바일의 고유 정보 이용 불가 & 하드웨어 제어 불가)

 

모바일 웹과 웹 앱을 비교해 보면 둘은 웹 개발과 동일하게 만들어지기 때문에 모바일 운영체제별로 개발할

필요가 없기 때문에 시간과 비용 측면에서 효과적이다. 하지만 접속하기 위해선 브라우저를 이용해야 하므로

직접 검색하거나 URL로 접근해야 한다. 이처럼 더 많은 단계를 거치고, 직접 입력해야 하는 노력이 필요하다는 점에서

접근성이 좋지 않다는 단점이 있다.

 

모바일 웹과 웹 앱의 실행 방식 차이

 

모바일 웹(풀 브라우저 방식 Full Browsing) : 화면 일부분이 변경될 때 화면 전체 내용을 서버에서 새로 받아오는

방식으로 페이지 Reload를 할 경우 속도가 느리다는 단점이 있다. 또한 모바일 기기 특성상 이동 중에 서버 접속 장애가

발생할 위험이 있다.

 

웹 앱(단일 페이지 방식 SPA) : 브라우저에 최초 한 번 페이지 전체를 받아오고, 화면 일부분이 변경, 요청될 때

해당 부분만 Ajax를 통해 데이터를 바인딩 하는 방식이다.

 

모바일 웹은 풀 브라우저 방식으로 실행 속도가 느린 반면, 웹 앱은 단일 페이지 방식으로 실행 속도가 빠르다.

점차 모바일 환경이 발달하면서 PC 기반으로 개발된 웹 페이지들이 모바일 환경으로 적응하게 되었고,

이 과정에서 모바일 최적화를 위한 다양한 방법들이 등장했다. 반응형과 적응형도 이 과정에서 등장했다.

한 개의 URL로 다양한 디바이스 사이즈에 맞게 변동하는 반응형 웹(Responsive Web)과 각 디바이스 별

템플릿을 만들어 접근한 디바이스에 따라 알맞은 템플릿을 제공하는 적응형 웹(Adaptive Web)이 대표적이다.

Spring Tools for Eclipse 기준 설명

1. https://spring.io/tools 접속하여 STS(for Eclipse) 설치 후 실행
2. 상단 Quick Access에 Git Repositories 검색 후 클릭
3. Git Repositories 탭으로 가서 Clone a Git repository
4. gitlab 사이트 Import 하려는 프로젝트로 들어가서 Clone -> Clone with HTTPS 부분 복사
5. STS로 돌아가서 URL 부분에 붙여넣기 하면 세부 항목까지 자동 입력(Port는 빈칸)
6. master 브랜치 체크 후 Next & Finish
7. Git Repositories 탭의 프로젝트 우클릭 후 Import Projects
8. Package Explorer에 받아진 프로젝트 확인
9. Window > Preferences > Server > Runtime Environments > 우측 Add > Tomcat 버전 선택 > Browse...
   클릭 후 다운로드한 Tomcat 폴더 선택 > Finish > Apply and Close

   (Tomcat 다운로드 https://tomcat.apache.org)
10. 상단 Quick Access에 Servers 검색 후 클릭
11. Servers 탭에서 우클릭 > New > Server > Tomcat 버전 선택 > Available 부분에 있는 항목 선택 후 Add > Finish
12. Project는 우클릭 후 Maven > Update Project...와 최상단 탭 Project > Clean...

13. x 표시가 사라지지 않는다면 설치되지 않은 플러그인이 있는지 확인

     - Lombok을 사용하는 경우 -

     Eclipse의 경우 Maven / Gradle에 Lombok Dependency가 추가되어 있어도 Lombok을 따로 설치해 줘야 한다.

     https://projectlombok.org/download 접속하여 다운로드한다.

     다운로드한 lombok.jar 파일을 STS 실행파일이 있는 위치로 옮긴다.

     명령 프롬프트(CMD)를 관리자 권한으로 실행시킨 후 lombok.jar 파일이 위치한 폴더로 이동한다.

      lombok.jar 파일이 C:\STS\contents\stsRELEASE  폴더 안에 있다면

      cd C:\STS\contents\stsRELEASE 명령어로 이동 후 java -jar lombok.jar

      Lombok을 설치할 IDE를 체크한 후 Install / Update 버튼을 클릭, 설치가 끝났다면 실행 중인 STS를 재실행

      STS 실행파일 위치에 실행파일명.ini 파일 열어보면 -javaagent: 부분에 lombok.jar 경로가 추가된 것 확인

14. 13번에서 추가로 설치한 플러그인이 있다면 12번으로 간다.
15. Servers 탭의 Tomcat 더블클릭 후 Overview 탭 Ports의 HTTP 부분 옆 Port Number 변경

     & Modules 탭의 Path를 / 로 변경
16. Servers 탭의 Tomcat 우클릭 > Clean...

17. Start the server 후 브라우저 실행하여 localhost:8080 입력 (Port Number가 8080일 경우)

import java.util.Arrays;

public class Solution {
	
	// 요격 시스템
	
	public static int solution(int[][] targets) {
		int answer = 0;
		
		// 개구간 (s, e)로 표현되는 폭격 미사일을 s와 e에서 발사하는 요격 미사일로는 요격할 수 없기 때문에 각각의 원소에 10을 곱한 후
		// 첫 번째 원소에서는 +1을, 두 번째 원소에서는 -1을 하여 폐구간 [r, f]을 만든 후 [Java] 프로그래머스 [Level-3] 단속카메라 문제처럼 풀도록 한다.
		int[][] tempTargets = new int[targets.length][targets[0].length];
		
		for (int i = 0; i < targets.length; i++) {
			tempTargets[i][0] = targets[i][0] * 10 + 1;
			tempTargets[i][1] = targets[i][1] * 10 - 1;
		}
		
		// int[][] targets = {{4, 5}, {4, 8}, {10, 14}, {11, 13}, {5, 12}, {3, 7}, {1, 4}};
		// int[][] tempTargets = {{41, 49}, {41, 79}, {101, 139}, {111, 129}, {51, 119}, {31, 69}, {11, 39}};
		
		// 이차원 배열 tempTargets 정렬
		Arrays.sort(tempTargets, (o1, o2) -> {
			if (o1[1] == o2[1]) { // 뒤 원소가 같을 경우
				return o1[0] - o2[0]; // 앞 원소 기준 오름차순
			} else { // 뒤 원소가 같지 않을 경우
				return o1[1] - o2[1]; // 뒤 원소 기준 오름차순
			}
		});
		
		// int[][] tempTargets = {{11, 39}, {41, 49}, {31, 69}, {41, 79}, {51, 119}, {111, 129}, {101, 139}};
		
		int missilePoint = tempTargets[0][0] - 1; // 10 // 정렬 후 첫 번째 첫 원소보다 작은 값을 넣기 위해 -1 => 최초 무조건 아래 if문에 걸리게 됨
		
		for (int i = 0; i < tempTargets.length; i++) {
			
			if (missilePoint < tempTargets[i][0]) {
				missilePoint = tempTargets[i][1];
				System.out.println(missilePoint + "번 위치에 미사일 설치");
				answer++;
			}
		}
		
		return answer;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[][] targets = {{4, 5}, {4, 8}, {10, 14}, {11, 13}, {5, 12}, {3, 7}, {1, 4}};
		
		System.out.println(solution(targets)); // 3
	}
}

프로그래머스 요격 시스템 문제 풀이 Java

+ Recent posts