분류 전체보기

반응형

잘못된 예

<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt"%> X


<fmt:formatNumber type="number" maxFractionDigits="2" value="${maxAllowableAmount}" />

 

올바른 예

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> O


<fmt:formatNumber type="number" maxFractionDigits="2" value="${maxAllowableAmount}" />
예시 출처 : stackoverrun.com

 

"value" does not support runtime expressions 메시지에 대한 70% 이상의 원인은

위에 태그라이브러리의 표기를 잘못 작성해서 그렇습니다.

 

위에 태그라이브러리(taglib)를 확인해주세요.

 

JSP - taglib 종류와 설명

http://www.w3big.com/ko/jsp/jsp-jstl.html

반응형
반응형

for each문 , 개선된 for문 , 향상된 for문 다양하게 부르지만 본문에선 개선된 for문이라 명칭 하겠습니다.

 

개선된 for 문

 

조건


1.JDK 1.5 이상

2.사용할 변수는 지역변수로 인식된다. (For문 안에서 사용되기 때문)
3. 대상은 배열 or 여러 원소를 포함한 자료형이어야 한다.

 

 

장점


1.간편한,가독성 좋은 코드
2. 배열 인덱스 문제 해결 (ArrayIndexOutOfBoundsException 예외를 피할 수 있다.)

 

 

단점


1.인덱스를 사용하지 못한다.(일반 for문의 (int i=0;) 할 때 i 같은 인덱스를 말하는 것) 하지만 방법이 있다.
★ 중요 ★
2.배열이나 ArrayList 값을 사용할 순 있지만 절대 수정할 수는 없다.

 

 

사용 이유


배열처럼 여러 원소로 이루어진 집합의 모든 원소에 대해 특정 작업을 반복하기 위해 사용

 

자주 사용되는 상황

1.ArrayList 원소 출력
2.배열 원소 출력

 

 

속도


일반 for문이 더 빠르다는 소문이 있어서 테스트해봤는데, 제가 해본 결과는 일단 같았습니다.

일반 for문 == 개선된 for문

이 부분에 있어서 정확하게 아시는 분은 덧글좀 남겨주세요.

 

문법


for(자료형 변수명 : 배열명){
	문장
}

 

쉽게 설명하면

for(자료형 한 단계 아래의 자료형의 변수명 : 배열명){

}

정확히 말하면 아래의 자료형이 아니지만 이렇게 생각하면 이해가 쉽더라고요.

 

실전 예제 - 일반 배열 원소 추출

String[] arr = {"1-1","1-2","1-3","1-4","1-5"};
 		
for(String s : arr) {
		  
 System.out.println(s);
		  
}

결과

 

 

실전 예제 2 - 이차원 배열 원소 추출

String[][] arr = {{"1-1","1-2","1-3","1-4","1-5"},{"2-1","2-2","2-3","2-4","2-5"}};
 		
for(String[] arrs : arr) {
	for(String s : arrs) {
		System.out.println(s);
	}
}

결과

 

 

실전 예제 3 - 삼차원 배열 원소 추출

String[][][] arr = {{{"1-1","1-2","1-3","1-4","1-5"},{"2-1","2-2","2-3","2-4","2-5"}},
					{{"3-1","3-2","3-3","3-4","3-5"},{"4-1","4-2","4-3","4-4","4-5"}}};
 		
for(String[][] arrtop : arr) {
	for(String[] arrs : arrtop) {
		for(String s : arrs) {
			System.out.println(s);
		}
	}
}

결과

 

 

실전 예제 4 - ArrayList<String> 원소 추출

ArrayList<String> arrlist = new ArrayList<String>();
arrlist.add("1-1");
arrlist.add("1-2");
arrlist.add("1-3");
		
for(String s : arrlist) {
			  
  System.out.println(s);
			  
}

결과

 

 

실전 예제 5 - ArrayList<Class> 원소 추출

public class Ex001 {

	private String a;
	private int b;
	private int c;
	
	public String getA() {
		return a;
	}
	public void setA(String a) {
		this.a = a;
	}
	public int getB() {
		return b;
	}
	public void setB(int b) {
		this.b = b;
	}
	public int getC() {
		return c;
	}
	public void setC(int c) {
		this.c = c;
	}
}
ArrayList<Ex001> arrlist = new ArrayList<Ex001>();

Ex001 ex01 = new Ex001();
ex01.setA("a");
ex01.setB(1);
ex01.setC(2);
arrlist.add(ex01);
		
 for(Ex001 s : arrlist) {
			  
 System.out.println(s.getA());
 System.out.println(s.getB());
 System.out.println(s.getC());
			  
}

결과


 

반응형
  1. 42421 2021.05.10 15:30

    개선된 for문이 더 느리다는 말은 들어본적이 없지만, 그런 소문이 나온 이유를 대강 추측해본다면,

    아마 일반 for문은 미리 컴파일된 조건이나 수식같은 것이 있어서 그것대로만 하면 되지만,
    개선된for문은 실행할 때마다 배열/list 객체의 사이즈를 재고 그것대로 일반 for문에 적용한 다음,
    매번 반복할 때 마다 새로운 변수/객체를 만들어주니까 차이가 생긴다는 것이 아닐까라고 생각합니다.

반응형

1.String to char (String -> char)


1-1.charAt() 이용하기

 

문법

String input = "안녕하세요";
char c = input.charAt(인덱스);

 

실전 예시

String krstr = "안녕하세요";

char c = krstr.charAt(0);

System.out.println(c);

결과 : 안

 

 

실전 예시 2

String enstr = "abcdef";

char c = enstr.charAt(3);

System.out.println(c);

결과 : d

 

 

실전 예시 3 - for문을 이용하여 하나 씩 반복하며 뽑기

String input = "자바킹";

for(int i=0; i<input.length(); i++) {
System.out.println(input.charAt(i));}

결과 :  자

           바

           킹


처음부터 char형으로 쪼개서 넣을 순 없을까?


1-2.toCharArray() 이용하기

 

문법

String input = "안녕하세요";
char[] arrCh = input.toCharArray();

 

실전 예시 - 개선된 for문을 이용하여 하나 씩 반복하며 뽑기

String input = "안녕하세요";
char[] arrCh = input.toCharArray();

for(char c : arrCh) {
System.out.println(c);}

※ 공통 주의할 점

 

1.특수문자, 공백도 인덱스에 포함된다는 점

예시 :

String input = "안녕 하세요";

char c = input.charAt(2);

 

결과 : (공백)

 

2. 인덱스가 0부터 시작한다는 점

예시 :

String input = "안녕하세요";

char c = input.charAt(0);

결과 : 안


2.char to String (char -> String)


2-1.valueOf() 이용하기

 

문법

char c = 'a';

String str = String.valueOf(c);
System.out.println(str);

 

결과 : a (type : String)

 

실전 예시 - char [] array to String 

char[] arrCh = {'a', 'b', 'c' };

String str = String.valueOf(arrCh);
System.out.println(str);

결과 : abc (type : String)


2-2.toString() 이용하기

 

문법

char c = 'a';

String str = Character.toString(c);

결과 : a (type : String)

 

※ 주의할 점: Character.toString() 사용 시 char [] 배열은 변환이 불가능합니다.

char c = 'a'
char[] arrCh = {'a', 'b', 'c' }; 

Character.toString(c) O
Character.toString(arrCh) X

2-3."" 이용하기 (야매식 변환)

 

문법

char c = 'a';

String str = ch + "";

결과 : a (type : String)


마지막으로..

[2-3."" 이용하기] 방법이 가장 편해서 저도 많이 쓰고 있는데요.

실행 속도는 어떨까요? 한번 비교해봤습니다.

 

[2-1.valueOf()] vs [2-3."" 이용하기]

 

실행 속도 비교 코드

public class Ex006 {

	public static void main(String[] args) throws NumberFormatException, IOException {
		
		char ch = 'a';
		
		long startNanoTime = System.nanoTime(); 
        
		int i = 1000000000;
		while(i --> 0) {
        
			String str = String.valueOf(ch); //2-1
			String str = ch+""; //2-3
            //하나씩 넣고 컴파일을 진행하였습니다.
			
		}
		
		long secDiffTime = (System.nanoTime() - startNanoTime) / 1000000000;
		System.out.println(secDiffTime);
		
	}
}

 

[2-1.valueOf()] 속도

 

일반 결과 : 0초

배열 결과 : 5초

 

[2-3."" 이용하기] 속도

 

일반 결과 : 20초

배열 결과 : 74초

 

간단한 코드에 이런 차이면 좀 더 복잡할수록 많이 차이 날 거 같습니다.

되도록이면 valueOf()를 사용하시는 걸 추천드립니다.

 

 

 

반응형
  1. 곰탱 2021.07.07 21:21

    감사합니다

반응형

개념


주로 알고리듬이나 어떠한 기능을 만들 때, while문을 쓰게 되는데요.

 

while문 조건에 자주 나오게 되는 녀석이 바로 while(variable-- > 0)입니다.

 

여기서 '-- >'가 헷갈릴 수도 있는데요.

 

variable--; variable > 0; 이 두 가지를 합쳐놓은 것입니다.

 

0 보다 조건 값을 뺀 값이 클 경우, 즉 -- (증감 연산자)와 > (꺾쇠괄호)를 합쳐 놓은 형태인 거죠.

 

 

예시


int T = 3;
int cnt = 10;
		
while(T-- > 0) {
	System.out.println(cnt--+" 루프 : "+T);
			
}

결과

 

설명

1. 해당 루프에서 T를 1 씩 줄입니다.

    즉, 루프가 돌 때마다 T가 1씩 줄게 되고 줄은 값이 0보다 클 경우에만 돌게 됩니다.

    그러니 T 변수의 값이 3이니 3번 돌고 끝나게 됩니다.

 

 

실전 예제

 

입력 값에 따른 라인 출력

BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		
		int tcode = Integer.parseInt(bf.readLine()); 

		while (tcode-- > 0) {
			String testStr = bf.readLine() + "\n";
		}

 

마지막으로 while 문을 사용할 땐 항상 무한루프에 주의합시다.

반응형
  1. BlogIcon 도날두덱 2021.07.18 01:59 신고

    좋은내용감사합니다

반응형

MD5 (Message-Digest algorithm 5)

코드(소스) 보기

더보기
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Util {

		public static String encrypt(String str){

			String MD5 = ""; 

			try{

				MessageDigest md = MessageDigest.getInstance("MD5"); 

				md.update(str.getBytes()); 

				byte byteData[] = md.digest();

				StringBuffer sb = new StringBuffer(); 

				for(int i = 0 ; i < byteData.length ; i++){

					sb.append(Integer.toString((byteData[i]&0xff) + 0x100, 16).substring(1));

				}

				MD5 = sb.toString();

				

			}catch(NoSuchAlgorithmException e){

				e.printStackTrace(); 

				MD5 = null; 

			}

			return MD5;

		}

}

 

사용법

public String util() {
		String str = "자바킹";
		String md5_en = MD5Util.encrypt(str);

		System.out.println("MD 5 암호화 : "+md5_en);//MD5 암호화
		return str;
}

SHA-256 (Secure Hash Algorithm 256)

코드(소스) 보기

더보기
import java.security.MessageDigest;

public class SHA256Util {

	public static String encrypt(String planText) {
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-256");
			md.update(planText.getBytes());
			byte byteData[] = md.digest();
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < byteData.length; i++) {
				sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
			}
			StringBuffer hexString = new StringBuffer();
			for (int i = 0; i < byteData.length; i++) {
				String hex = Integer.toHexString(0xff & byteData[i]);
				if (hex.length() == 1) {
					hexString.append('0');
				}
				hexString.append(hex);
			}
			return hexString.toString();
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException();
		}
	}
	
}

사용법

public String util() {
		String str = "자바킹";
		String sha256_en = SHA256Util.encrypt(str);

		System.out.println("SHA 256 암호화 : "+sha256_en);
		return str;
}

AES-128 (Advanced Encryption Standard 128)

코드(소스) 보기

더보기
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class AES128Util {

    public static String encrypt(String input, String key) {
        byte[] crypted = null;
        try {
 
            SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
 
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, skey);
            crypted = cipher.doFinal(input.getBytes());
        } catch(Exception e) {
            System.out.println(e.toString());
        }
 
        BASE64Encoder encoder = new BASE64Encoder();
 
        String str = encoder.encode(crypted);
 
        return new String(str);
    }
 
    public static String decrypt(String input, String key) {
        byte[] output = null;
        try {
            BASE64Decoder decoder = new BASE64Decoder();
 
            SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
 
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skey);
            output = cipher.doFinal(decoder.decodeBuffer(input));
 
        } catch(Exception e) {
            System.out.println(e.toString());
        }
        return new String(output);
    }
}

사용법

public String util() {
		String str = "자바킹";
		String aes128key = "123456789abcdefg"; //사용자 지정 생성
		
		String aes_en = AES128Util.encrypt(str,aes128key);
		String aes_de = AES128Util.decrypt(aes_en,aes128key);

		System.out.println("AES 128 암호화 : "+aes_en);//AES128 암호화
		System.out.println("AES 128 복호화 : "+aes_de);//AES128 복호화
		return str;
}

3 DES (Triple Data Encryption Algorithm)

코드(소스) 보기

더보기
import java.security.Key;
import java.security.NoSuchAlgorithmException;
 
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
 
public class DES3Util {
   
   
   private static Key key = null;
     
    static {
     if(key == null) {
      // Key 초기화
     KeyGenerator keyGenerator;
      try {
       keyGenerator = KeyGenerator.getInstance("TripleDES");
       keyGenerator.init(168);
       key = keyGenerator.generateKey();
      } catch (NoSuchAlgorithmException e) {
       e.printStackTrace();
      }
     }
    }
     
    public static String encrypt(String inStr) {
     StringBuffer sb = null;
     try {
      Cipher cipher = Cipher.getInstance("TripleDES/ECB/PKCS5Padding");
      cipher.init(Cipher.ENCRYPT_MODE, key);
      byte[] plaintext = inStr.getBytes("UTF8");
      byte[] ciphertext = cipher.doFinal(plaintext);
       
      sb = new StringBuffer(ciphertext.length * 2);
      for(int i = 0; i < ciphertext.length; i++) {
       String hex = "0" + Integer.toHexString(0xff & ciphertext[i]);
       sb.append(hex.substring(hex.length()-2));
      }
     }catch(Exception e) {
      e.printStackTrace();
     }
     return sb.toString();
    }
     
    public static String decrypt(String inStr) {
     String text = null;
     try {
      byte[] b = new byte[inStr.length()/2];
      Cipher cipher = Cipher.getInstance("TripleDES/ECB/PKCS5Padding");
      cipher.init(Cipher.DECRYPT_MODE, key);
      for(int i = 0; i < b.length; i++) {
       b[i] = (byte)Integer.parseInt(inStr.substring(2*i, 2*i+2), 16);
      }
      byte[] decryptedText = cipher.doFinal(b);
      text = new String(decryptedText,"UTF8");
     }catch(Exception e) {
      e.printStackTrace();
     }
     return text;
    }
   
}

사용법

public String util() {
		String str = "자바킹";
		
        	String des3_en = DES3Util.encrypt(str);
		String des3_de = DES3Util.decrypt(des3_en);

		System.out.println("3DES 암호화 : "+des3_en); //DES3 암호화
		System.out.println("3DES 복호화 : "+des3_de); //DES3 복호화
		return str;
}

"자바킹" 문자열 암호화 종류별 결과

반응형
반응형

<trim>

 

속성


prefix : 실행될 쿼리의 <trim> 문 안에 쿼리 가장 앞에 붙여준다.

UPDATE board <trim prefix="SET"> username=#{username},password=#{password}</trim>

 

prefixOverrides : 실행될 쿼리의 <trim> 문 안에 쿼리 가장 앞에 해당하는 문자들이 있으면 자동으로 지워준다.

SELECT * FROM board WHERE id = #{id} 
<trim prefixOverrides="OR">OR TT LIKE '%' || #{searchContent} || '%' </if> 

 

suffix : 실행 될 쿼리의 <trim> 문 안에 쿼리 가장 뒤에 붙여준다.

<trim suffix=")"></trim>

 

suffixOverrides : 실행될 쿼리의 <trim> 문 안에 쿼리 가장 뒤에 해당하는 문자들이 있으면 자동으로 지워준다.

<trim suffixOverrides=","></trim>

 

 

문법


<select id="test" resultType="user">
SELECT * FROM user WHERE id = #{id}  
<trim prefix="AND (" prefixOverrides="OR" suffix=")">
        <if test="para1 != null">
        OR para1 = #{data1}
        </if>
        <if test="para2 != null">
        OR para2 = #{data2}
        </if>
</trim>
</select>

설명 

0.<trim prefix="AND (" prefixOverrides="OR" suffix=")"> 이 부분을 해석하자면

1. 먼저 prefix 속성이 'AND'로 돼있기 때문에 맨 앞에 'AND'가 붙습니다.

2.prefixOverrides 속성이 쿼리 중에 'OR' 텍스트를 찾고, 찾게 되면 'OR' 텍스트를 제거합니다.

3. 그리고 suffix 속성이 <trim> 문 맨 마지막에 ')'를 닫아줍니다.  

 

실행될 쿼리 (para1, para2 값이 들어올 경우)

SELECT * FROM user WHERE id = '119'
AND para1 = 'java119' OR para2 = 'java119' 

 

 

실전 예제

 

prefix, suffixOverrides 사용 예시
1. 맨 앞에 'SET' 붙이고 맨 끝에 있는 콤마(,)를 제거하기

<update id="updateUser">
UPDATE user
	<trim prefix="SET" suffixOverrides=",">
		<if test="username != null">username=#{username},</if>
		<if test="password != null">password=#{password},</if>
		<if test="email != null">email=#{email},</if>
		<if test="bio != null">bio=#{bio},</if>
	</trim>
WHERE id=#{id}
</update>

 

prefix, prefixOverrides 사용

2. 맨 앞에 있는 연산자를(AND 또는 OR) 제거하는 경우

<select id="selectInfo" resultType="user">
	 SELECT * FROM USER
	 <trim prefix="WHERE" prefixOverrides="AND |OR">
		<if test="username != null">AND username=#{username}</if>
		<if test="password != null">OR password=#{password}</if>
		<if test="email != null">AND email=#{email}</if>
	</trim>
</select>

 

prefix, prefixOverrides, suffixOverrides 사용
3. 맨 앞에 'SET' 붙이고 맨 앞, 맨 끝에 있는 콤마(,)를 제거하기

<update id="updateTable">
	UPDATE TABLE
	<trim prefix="SET" prefixOverrides="," suffixOverrides="," >
		<if test="aFlag != null">
			, A_FLAG = #{aFlag}
		</if>

		<if test="bFlag != null">
			, B_FLAG = #{bFlag}
		</if>

		<if test="cFlag != null">
			, C_FLAG = #{cFlag} ,
		</if>
	</trim>
	WHERE KEY = #{key}
</update>

 

prefix, prefixOverrides, suffix 사용

4. 맨 앞에 'AND (' 붙이고 맨 앞 'OR' 제거하고 맨 끝에 ')' 붙이기 

<select id="searchUser">

<trim prefix="AND (" prefixOverrides="OR" suffix=")">
 <if test="searchCategory0 != null"> 
  OR TT LIKE '%' || #{searchContent} || '%' 
 </if>  
 <if test="searchCategory1 != null"> 
  OR DS LIKE '%' || #{searchContent} || '%' 
  </if>
  <if test="searchCategory2 != null"> 
   OR WRT_MPR_NM LIKE '%' || #{searchContent} || '%' 
  </if>
</trim>
</select>

 

반응형
반응형

<sql>

 

개념


다른 구문에서 재사용하기 위한 SQL 조각

출처 : mybatis 공식 사이트

말 그대롭니다. "재사용성을 높이기 위한 SQL 조각" 아주 정확한 표현입니다.

 

 

조건


1.id 속성 값이 필수입니다.
2.사용하려는 태그보다 먼저 선언되어야 합니다.(위에 존재해야 합니다.)

 

문법


<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>

 

<include> 

<property>

 

개념


<sql> 문을 DML(Data Manipulation Language) 태그에 삽입하는 기술

 

 

문법


<select,insert,update,delete>

<include refid="<sql> id"><property name="<sql> property" value=""/></include>

</select,insert,update,delete>

 

<sql> + <include><property> 설명

//no property 
<sql id="example01">
  FROM
</sql>

//property 한개 작성
<sql id="example02">
  FROM ${alias(별칭)}
</sql>

//property 여러 개 작성
<sql id="example03">
  FROM ${alias(별칭)} WHERE id = ${alias02(별칭)}
</sql>
<select id="selectUser" resultType="User">
SELECT id,name
<include refid="example03">
  <property name="alias" value="tablename"/>
  <property name="alias02" value="119"/>
</include>
</select>

실행될 쿼리

SELECT id,name FROM tablename WHERE id = 119

 

설명

0.<sql> 문에는 parameter를 넘길 수 없으므로 property를 사용한다. ex) ${alias},${tablename}..

1. <sql> id 속성 == <include> refid 속성

2. <sql> ${alias(별칭)} == <property> name 속성  

3. <property> value 속성 : ${alias}에 들어갈 값

 

이 네가지만 기억하시면 됩니다.


<sql> + <include> 실전 예제

 

☞ 참고 : <sql> property는 꼭 $로 작성하셔야 합니다.

☞ 참고 02 : <sql> 문에선 property 를 <if> , <bind> 태그에 변수로 인식하지 못합니다.

 

1.Table 문법 재사용

<sql id="returnTable">
  from ${tableproperty}
</sql>
<include refid="returnTable">
  <property name="tableproperty" value="tablename"/>
</include>

 

2.JOIN문 활용 (MyBatis 공식 사이트 예제)

<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>
<select id="selectUsers" resultType="map">
  select
    <include refid="userColumns"><property name="alias" value="t1"/></include>,
    <include refid="userColumns"><property name="alias" value="t2"/></include>
  from some_table t1
    cross join some_table t2
</select>

 

3.SELECT 칼럼 문법 재사용

<sql id="common_select_table">id, name, age</sql>
<select id="getMemberInfo">
    SELECT
        <include refid="common_select_table" />
    FROM
        TABLE
</select>

 

4.INSERT 문 활용

<sql id="board_columns">
    ${alias}id,
    ${alias}subject,
    ${alias}context,
    ${alias}attachments,
    ${alias}likes,
    ${alias}views,
    ${alias}create_time,
    ${alias}update_time,
    ${alias}writer
</sql>

<insert id="insertBoard">
    INSERT INTO BOARD (
           <include refid="board_columns"><property name="alias" value=""/></include>
         ) VALUES (
          #{id},
          #{subject},
          #{context},
          #{attachments},
          #{likes},
          #{views},
          now(),
          null,
          #{writer} )
</insert>

외부 SQL-Mapper.xml + <include> 사용하기 


board-Mapper.xml 에서 common-Mapper.xml <sql> 사용(접근) 하기

 

common-Mapper.xml

<mapper namespace="mapper.common-Mapper">

<sql id="board_col">
${alias}id,
${alias}subject,
${alias}context
</sql>

</mapper>

board-Mapper.xml

<select id="selectUser">
    SELECT <include refid="mapper.common-Mapper.board_col">
    <property name="alias" value="b."/></include>
      FROM board b
</select>

설명

사용 할 외부 Mapper.xml에 namespace.<sql> id로 가져오면 됩니다.

반응형
반응형

먼저 절대 경로, 상대 경로를 설명하기 전
학창 시절로 가서 절대 평가, 상대 평가를 생각하면서 이 글을 보면 이해가 쉽습니다.

 

절대 경로

 

개념


최초의 시작점으로 경유한 경로를 전부 기입하는 방식

경로의 처음부터 마지막까지 완전히 적힌 경로
어떠한 웹페이지나 파일이 가지고 있는 고유한 경로

최상위 디렉토리가 반드시 포함된 경로

 

 

실전 예시


Browser

http://www.google.com

Windows

C:\chrome\chrome_shutdown_ms.txt

Linux

cd $CATALINA_HOME/bin/

 

윈도(Windows) 절대 경로

 

C:\chrome\


Spring 절대 경로

 

 

servlet-context.xml

<resources mapping="/resources/**" location="/resources/" />

JSP

<img alt="Cat pictures" src="/resources/img/cat01.jpg">

결과

 

 

상대 경로

 

개념


현재 위치한 곳을 기준으로 해서 목표로 하는 (파일이 있는 곳) 위치이다.
상대 경로는 항상 비교할 대상이 있어야 합니다. 결국 내가 어디있냐에 따라 경로가 달라지는 것! 

내 위치와 파일 경로를 비교하는 것! (상대평가처럼)

현재 디렉터리(비교 대상)를 기준으로 작성된 경로

 

 

실전 예시


예시 URL : http://localhost:8080/project 01/abc.jsp

 

 

Spring 상대 경로

 

servlet-context.xml

<resources mapping="/resources/**" location="/resources/" />

 

JSP

${pageContext.request.contextPath} : 내 현재 위치 ( EL(Expression Language) 사용 )

<img src="${pageContext.request.contextPath}/resources/img/cat01.png" />

결과

설명


 ${pageContext.request.contextPath} 사용함으로 써 상대 경로 즉, 내 위치에 따라 값이 변하던 게 고정이 된다.

정확히 말하면 고정이 아니라 알아서 위치를 찾아서 맞춰주는 겁니다. 

예를 들면 부모 폴더에 접근하려면 ../resources/img/cat01.png 이런 식으로 쓰고

소속 폴더에 접근하려면 ./resources/img/cat01.png 써야 하는 걸 알아서 맞춰주는 겁니다.

 

 

그 외 표현식

${pageContext.request.requestURL} : http://localhost:8080/project01/abc.jsp

${pageContext.request.scheme} : http 

${pageContext.request.serverName} : localhost 

${pageContext.request.serverPort} : 8080 

${pageContext.request.requestURI} : /project01/abc.jsp

${pageContext.request.servletPath} : /abc.jsp

 

 

Java

 

HttpServletRequest request

String root = request.getContextPath(); // return 프로젝트 Path

결과 : /project01

String uri = request.getRequestURI(); // return 프로젝트+파일경로

결과 : /project01/abc.jsp

String servlet = request.getServletPath(); // return 파일명

결과 : /abc.jsp

StringBuffer url = request.getRequestURL(); // return 전체 경로

결과 : http://localhost:8080/project01/abc.jsp

 

 

경로 표기법

 

상대 경로

. : 현재 웹페이지가 소속된 폴더
.. : 현재 웹페이지의 부모 폴더

 

절대 경로

 

/ : 루트(root)

./ : 현재 위치

../ : 현재 위치의 상단 폴더

 

반응형

+ Recent posts