728x90
반응형
리플렉션(reflection)은 기본적으로 Java에서 클래스의 정보를 효율적으로
얻기 위해 개발된 기법입니다. 클래스의 정보를 얻는 방법부터 알아 
보겠습니다. 다음의 예제들을 살펴보겠습니다.


▶ 클래스 정보를 관리하는 도구의 종류

/* 클래스 정보를 다루는 도구 얻기 */
public class Test01 {

  public static void main(String[] args) throws Exception {
    // 1) 인스턴스를 통해서 얻기
    String obj = new String("Hello");
    Class<?> c1 = obj.getClass(); // <?> : 어떤 종류의 클래스든 다 얻어올 수 있다는 의미
    // => 인스턴스만 있으면 그 인스턴스가 어떤 클래스의 객체인지 쉽게 알아낼 수 있다.
    
    
    // 2) class.forName() 메서드를 통해서 얻기
    Class<?> c2 = Class.forName("java.lang.String"); 
    // => 아규먼트가 가리키는 문자열이 없을 수 있기 때문에 예외처리가 필요하다.
    // => 클래스 이름을 문자열로 받을 수 있기 때문에 유지보수가 쉽다.
        
    // 3) 모든 클래스에 내장된 "class" 스태틱 변수를 통해서 얻기
    Class<?> c3 = String.class;
    // => 코딩이 간편하다. 그러나 클래스 이름을 코드로 명시하기 때문에 유지보수가 어렵다.
  }

}


▶ Class 도구를 이용해 클래스의 이름 알아내기


/* Class 도구 사용법 : 클래스 이름 알아내기 */
public class Test02 {

  public static void main(String[] args) throws Exception {
    Class<?> c1 = String.class;
    
    System.out.println(c1.getName());
    System.out.println(c1.getSimpleName());
    System.out.println(c1.getCanonicalName());
  }
}

실행 결과 : java.lang.String String java.lang.String



▶ Class 도구를 이용해 특정 메서드의 리턴 타입 알아내기


/* Class 도구 사용법 : 메서드의 리턴 타입 알아내기 */
import java.lang.reflect.Method;
public class Test05 {

  public static void main(String[] args) throws Exception {
    Class<?> clazz = Math.class;
    
    Method m = clazz.getMethod("sin", double.class);
    System.out.println(m);
    
    Class<?> returnType = m.getReturnType();
    System.out.println(returnType.getName());
  }
}

/*
실행 결과 : 
public static double java.lang.Math.sin(double)
double
*/



▶ Class 도구를 이용해 특정 메서드의 파라미터 타입 알아내기


/* Class 도구 사용법 : 메서드의 파라미터 타입 알아내기 */
import java.lang.reflect.Method;
public class Test06 {

  public static void main(String[] args) throws Exception {
    Class<?> clazz = Math.class;
    
    Method[] methodList = clazz.getMethods();
    for (Method m : methodList) {
      System.out.printf("%s\n", m.getName());
      Class<?>[] paramTypes = m.getParameterTypes();
      for (Class<?> paramType : paramTypes) {
        System.out.printf("--> %s \n", paramType.getName());
      }
      System.out.println();
    }
  }
}



▶ Class 도구를 이용해 메서드 호출하기


/* Class 도구 사용법 : 메서드 호출하기 import java.lang.reflect.Method; public class Test07 { public static void main(String[] args) throws Exception { // 1) 인스턴스 메서드 호출하기 String str = new String("Hello"); Class<?> clazz = String.class; Method m = clazz.getMethod("replace", char.class, char.class); Object returnValue = m.invoke(str, 'l', 'x'); System.out.println(returnValue); // 2) 클래스 메서드 호출하기 clazz = Math.class; m = clazz.getMethod("abs", int.class); returnValue = m.invoke(null, -100); // 스태틱 메서드를 호출할 때는 인스턴스를 null로 설정하라 System.out.println(returnValue); } }



▶ Class 도구를 이용해 인스턴스 생성하기

/* Class 도구 사용법 : 인스턴스 생성하기 */
import java.lang.reflect.Method;
import java.util.Date;
public class Test08 {

  public static void main(String[] args) throws Exception {
    // Class<?> clazz = Date.class;
    Class<?> clazz = Class.forName("java.util.Date");
    Date obj = (Date)clazz.newInstance();
    System.out.println(obj);
  }
}


▶ Class 도구를 이용해 nested class 로딩하기

/* Class 도구 사용법 : nested class 로딩 */
import java.lang.reflect.Method;
import java.util.Date;
public class Test09 {

  static class My {}
  
  public static void main(String[] args) throws Exception {
    Class<?> c1 = My.class;
    Class<?> c2 = step26.Test09.My.class;
    Class<?> c3 = Class.forName("step26.Test09$My");
    
    System.out.println(c1);
    System.out.println(c2);
    System.out.println(c3);
  }
}

/*
실행 결과 :
class step26.Test09$My
class step26.Test09$My
*/


Step 1. MySuper 클래스를 정의하기

──────────────────────────────────────

public class MySuper {
  public int superPublicVar;
  String superDefaulttVar;
  protected boolean superProtectedVar;
  private float superPrivateVar;
  
  public void superPublicM() {}
  void superDefaultM() {}
  protected void superProtectedM() {}
  private void superPrivateM() {}
}



Step 2. MySuper 클래스를 상속한 MyClass 클래스 정의하기

──────────────────────────────────────

public class MyClass extends MySuper {
  public int publicVar;
  String defaultVar;
  protected boolean protectedVar;
  private float privateVar;
  
  public MyClass() {}
  public MyClass(int p1) {}
  public MyClass(String p1, int p2) {}
  
  public void publicM() {}
  void defaultM() {}
  protected void protectedM() {}
  private void privateM() {}
  
  public void m1() {}
  public void m2(int v1) {}
  public void m3(String p1, int p2) {}
}




Step 3. MyClass 클래스의 메서드를 알아내기

──────────────────────────────────────

* Class 도구 사용법 : 클래스의 메서드 알아내기 */
import java.lang.reflect.Method;
public class Test03 {

  public static void main(String[] args) throws Exception {
  // static 환경에서는 this가 없다.  
  test1();
  test2();  
  }
  
  private static void test1() throws Exception {
    Class<?> clazz = MyClass.class;
    
    Method[] methodList = clazz.getMethods(); 
    // 상속 받은 메서드를 포함하여 모든 public 메서드만 추출한다.
    for (Method m : methodList) {
      System.out.println(m.getName());
    }
  }
  
  private static void test2() throws Exception {
    Class<?> clazz = MyClass.class;
    
    Method[] methodList = clazz.getDeclaredMethods(); 
    // 해당 클래스에 선언된 모든 메서드를 추출한다. 
    for (Method m : methodList) {
      System.out.println(m.getName());
    }
  }
  
}




Step 4. MyClass 클래스의 특정 메서드만 추출하기

──────────────────────────────────────


/* Class 도구 사용법 : 클래스의 특정 메서드만 추출하기 */
import java.lang.reflect.Method;
public class Test04 {

  public static void main(String[] args) throws Exception {
    Class<?> clazz = MyClass.class;
    
    Method m = clazz.getMethod("m1");
    System.out.println(m.getName());
    
    // 일치하는 메서드를 찾지 못했을 때? null을 리턴하는 것이 아니라 예외가 발생한다.
    // m = clazz.getMethod("m1", String.class);
    // System.out.println(m);
    
    Method m2 = clazz.getMethod("m2", int.class);
    System.out.println(m2);
    
    Method m3 = clazz.getMethod("m3", String.class, int.class);
    System.out.println(m3);
  }
}
/*
실행 결과 : 
m1
public void step26.MyClass.m2(int)
public void step26.MyClass.m3(java.lang.String,int)
*/


728x90
반응형

'Web Programming > java-jsp' 카테고리의 다른 글

java Generic  (0) 2018.09.05
TDD 테스트 주도 개발방법론  (0) 2018.09.04
JSTL에서 LIST Size  (0) 2018.09.04
For input string: ""  (0) 2018.09.04
Jsoup parser 크롤링  (0) 2018.08.30
728x90
반응형

strlen 함수

PHP 함수인 strlen 함수에 대해 php.net 에서는 아래와 같이 설명하고 있습니다.

문자열 길이를 얻습니다. 

그렇지만, 해당 함수는 영문 문자열이 몇 바이트(Byte)인지를 가져오는 함수입니다.
영문은 1 Byte로 계산하지만,
UTF-8 문서에 경우 각 문자를 1~4Byte까지 사용하므로, 한글은 한 글자당 1~4Byte에 길이가 반환되어 정확한 문자열의 길이를 알 수 없습니다.
그렇기 때문에 우리는 이를 해결 할 수 있는 함수인 mb_strlen 에 대해서도 함께 알아보겠습니다.

mb_strlen 함수

PHP 함수인 mb_strlen 은 php.net 에서 strlen과 동일한 설명을 가지고 있습니다.

문자열 길이를 얻습니다. 

그러면 무엇이 틀린 걸까요?
그건 바로 사용하는 인수 값이 틀립니다.

strlen은 문자열 하나만을 인수로 사용하지만,
mb_strlen은 문자열과 현재 파일의 인코딩(= 문자셋 혹은 charset )을 인수로 사용합니다.
mb_strlen 함수를 이용하면 한글 문자열 길이도 문제없이 가져올 수 있습니다.

▶사용법


강조 처리된 부분만 필수 입력 사항입니다.

strlen( 문자열 )


mb_strlen( 문자열 ,   인코딩 =  mb_internal_encoding() )


* 인코딩 : 값을 입력하지 않으면, 기본 문자 인코딩에서 사용되는 문자 인코딩을 가져옵니다. [참고 ]


▶strlen 함수 예제



코드

1
2
3
4
<?php
echo "영어 : ". strlen("Edward").'<br/>';
echo "한글 : ". strlen("반갑수");
?>


결과

영어 : 6
한글 : 9


▶mb_strlen 함수 예제


파일 인코딩이 UTF-8인 경우에 대한 예제입니다. (다른 인코딩이면 어딜 변경해야할지 아실거라 생각합니다.)

코드

1
2
3
4
<?php
echo "영어 : ". mb_strlen("Edward", "UTF-8").'<br/>';
echo "한글 : ". mb_strlen("반갑수", "UTF-8");
?>


결과

영어 : 6
한글 : 3



출처: http://extbrain.tistory.com/entry/PHP-문자열-길이-가져오기-strlen-mbstrlen-함수 [확장형 뇌 저장소]

728x90
반응형

'Web Programming > php' 카테고리의 다른 글

php $_GET $_POST  (0) 2018.09.05
php new line to br nl2br()  (0) 2018.09.05
php data types  (0) 2018.09.04
php include, require  (0) 2018.09.03
php 배열  (0) 2018.09.03
728x90
반응형

Spring 에서 restful 하게 작성하기 위해 @Controller 내에 @ResponseBody 사용하거나 혹은 @RestController 을 사용할 수 있습니다.


스프링 MVC 프레임 워크와 REST


일반적인 Spring MVC 컨트롤러와 RESTful 웹 서비스 컨트롤러의 주요 차이점은 HTTP 응답 바디가 생성되는 방식이다. 일반적인 MVC 컨트롤러는 View 기술을 사용하지만, RESTful 웹 서비스 컨트롤러는 객체를 반환하기 만하면(!) 객체 데이터는 JSON / XML 형식의 HTTP 응답에 직접 작성되게 됩니다.


▲ 일반적인 Spring MVC 흐름



@ResponseBody 와 @RestController 두가지 차이점을 알아보기 전에 우선 스프링에서 REST하게 데이터가 송수신 되는 과정은 다음과 같다.


  1. 클라이언트에서 웹서비스에 요청을 보냄.
  2. Handler Mapping과 그 타입을 찾는 Dispatcher Servlet에 의해 요청이 가로채짐.
  3. 요청은 Controller에 의해 처리되고 응답은 Dispatcher Servlet으로 반환되고 Dispatcher Servlet은 다시 View로 보내게 됩니다.

@ResponseBody

메소드에서 @ResponseBody 어노테이션을 사용하면 Spring은 반환 값을 변환하여 HTTP Response 에 자동으로 씁니다. Controller 클래스의 각 메소드에는 @ResponseBody 어노테이션이 있어야합니다.





@RestController


Spring 4.0은 @Controller와 @ResponseBody 을 합쳐놓은것 이상의 역할을 수행하는@RestController를 추가했습니다. 컨트롤러 클래스에 @RestController 어노테이션을 작성함으로써 더 이상 @ResponseBody를 모든 요청 매핑 메소드에 추가 할 필요가 없습니다. @ResponseBody 어노테이션은 이제 기본으로 작동..!




결론


스프링을 restful하게 만들 때, 앞으로는 스프링 4.0 부터 추가된 @RestController을 활용하므로써 기존의 @ResponseBody in @Controller 방식을 벗어나 좀 더 쉽게 restful한 코드를 작성할 수 있습니다.



출처: http://highcode.tistory.com/24 [HighCode]

728x90
반응형

'Web Programming > spring' 카테고리의 다른 글

Spring RestTemplate Get 요청  (0) 2018.09.05
spring resttemplate timeout  (0) 2018.09.05
No mapping found for HTTP request with URI  (0) 2018.09.04
BeanCreationException  (0) 2018.09.04
스프링 프레임워크 (Spring Framework)란?  (0) 2018.08.29
728x90
반응형

* Ajax 란?

 - 비동기 JavaScript 와 XML 을 말한다. 간단히 말하면, 서버측 Scripts 와 통신하기 위한 XMLHttpRequest 객체를 사용하는 것을 말한다

서버측으로 다양한 형식(JSON, XML, HTML 및 일반 텍스트 형식들)의 정보를 주고 받을 수 있다. 

비동기성을 통해 페이지 전체를 리프레쉬 하지 않고 사용자의 Event가 있으면 전체 페이지가 아닌 일부분만을 업데이트 할 수 있다.

서버로부터 받은 데이터로 작업을 한다


* Asynchronous JavaScript And Xml

1) 기존 방식의 사이트

 - 웹 어플리케이션의 기존 구현 방식의 특징

 - 웹브라우저가 웹 서버에 요청을 전송한다

 - 웹서버는 JSP/PHP/ASP 등의 서버측 어플리케이션을 사용해서 사용자의 요청을 처리한 뒤, 처리 결과를 HTML로 생성해서 웹 브라우저에 전송한다.

 - 웹 브라우저는 응답으로 받은 HTML을 분석한 뒤 그 내용을 화면에 그려준다.

 - 웹 브라우저가 웹 서버와 통신을 하고, 요청 결과는 HTML로 생성되고, 사용자의 입장에서는 페이지 이동이 발생하게 된다.

2) Ajax 방식의 사이트

 - 제시어 기능이 있다. 이는 '사용자에게 즉각적인 반응과 풍부한 UI 경험을 제공'한다는 것이다.

 - Ajax 는 ActiveX 와 같이 특정한 웹 브라우저에서만 제공하는 기능에 의존하지 않는다. 어떤 브라우저를 사용하든지 상관없이 웹 어플리케이션을 사용할 수 있게 된다.

3) Ajax 의 주요 구성요소

 - XMLHttpRequest : 웹 서버와 통신을 담당한다. 사용자의 요청을 웹 서버에 전송하고, 웹 서버로부터 받은 결과를 웹 브라우저에 전달한다.

 - DOM : 문서의 구조를 나타낸다. 폼 등의 정보나 화면 구성을 조작할 때 사용한다.

 - CSS : 글자색, 배경색, 위치, 투명도 등 UI 와 관련된 부분을 담당한다.

 - JavaScript : 사용자가 마우스를 드래그하거나 버튼을 클릭하면, XMLHttpReqeust 객체를 사용해서 웹 서버에 요청을 전송한다. 

또한, XMLHttpRequest 객체로부터 응답이 오면 DOM, CSS 등을 사용해서 화면을 조작한다.

4) 이벤트 발생 과정

 - 사용자가 이벤트를 발생시키면 JavaScript는 DOM을 사용해서 필요한 정보를 구한 뒤, XMLHttpRequest 객체를 통해서 웹 서버에 요청을 전달한다.

 - 웹 서버는 XMLHttpRequest로부터의 요청을 알맞게 처리한 뒤, 그 결과를 XML 이나 단순 텍스트로 생성해서 XMLHttpRequest 에 전송한다.

 - 서버로부터 응답이 도착하면 XMLHttpRequest 객체는 JavaScript에 도착 사실을 알리게 되고, JavaScript는 응답 데이터와 DOM을 조작해서 사용자 화면에 반영한다

5) Ajax 가 기존과 다른 차이점

 - 웹 브라우저가 아닌 XMLHttpRequest 객체가 웹 서버와 통신한다.

 - 웹 서버의 응답 결과가 HTML이 아닌 XML 또는 단순 text이다

 - 페이지 이동 없이 결과가 화면에 반영된다.


* 서버로의 비동기 통신 기술과 동적 클라이언트 스크립팅 기법을 하나로 묶은 것.

* 웹 브라우저가 직접 웹 서버와 통신하며 데이터를 주고 받는 것과 다르게 자바스크립트가 DOM을 이용해서 XMLHttpRequest 객체를 통해서 웹 서버에게 요청을 전달한다. 웹 서버는 요청을 처리하고 그 결과를 XML 이나 text로 생성해서 다시 XMLHttpRequest에게 넘긴다.그리고 그 결과는 다시 자바스크립트가 받아서 DOM을 이용해 조작해서 화면에 반응한다.



출처: http://smiler.tistory.com/entry/Ajax란?category=615519 [아직은 내가 쓴 글보다 퍼온 글이 훨씬 많음]

728x90
반응형

'Web Programming > front-end' 카테고리의 다른 글

jQuery input 배열 값 가져오기  (0) 2018.08.30
오른쪽 마우스 금지 소스 / 드래그 금지 소스  (1) 2014.04.09
<thead><tbody>  (0) 2013.09.30
<colgroup>  (0) 2013.09.25
<div>코딩  (0) 2013.09.25
728x90
반응형

◼︎ 슬랙의 장점



1. 파일공유 


메신저로 협업 커뮤니케이션 시 가장 어려운점은 메신저에서 공유한 파일을 다시 찾는 것. 

이 부분을 쉽게 해결해 준 점이 슬랙의 가장 큰 장점이다. 

파일을 쉽게 공유하고, 그 파일에 대한 커뮤니케이션도 별도로 가능하게 했다.







2. 기존에 사용 중인 서비스의 알림 통합


메신저 뿐이었다면 이렇게 전 세계적인 열풍이 일진 않았을 것이다. 

슬랙의 열풍은 기존에 사용 중이던 도구들을 버리지 않고, 그대로 사용하면서 각 도구들의 알림을 통합해 준 부분이 Killing Spec 이었다.

국내 서비스들 중에서는 적용할 수 있는 서비스가 많지 않지만, 그럼에도 많이 사용하고 있는 Mailchimp, Github, JIRA, Asana, Trello 등의 알림을 슬랙에서 받아볼 수 있다. 






3. 개발자들이 원하는 서비스로의 확장


그 외에도, 슬랙은 파워풀한 API를 제공한다. 

이 API를 통해, 전 세계의 개발자들은 본인이 원하는 정보를 슬랙을 통해 알림을 받을 수 있도록 자기만의 서비스를 개발한다. 

Slack API는 귀찮았던 부분들을 조금의 노력을 들여 쉽게 해결할 수 있어, 개발자들에게 더 없이 좋은 도구가 되었다, 







◼︎ 슬랙의 불편한 점


이렇게 큰 장점을 가지고 있음에도 불구하고 슬랙만으로는 협업 커뮤니케이션에 어려움을 느낀다.

많은 슬랙 사용자들은 슬랙과 히스토리를 정리하기 위한 도구, 메일을 함께 사용한다. 



1. 메신저 플랫폼의 한계


메신저는 <대화 상대>와 <대화 창>을 통해 커뮤니케이션 하는 플랫폼이다. 

모든 정보의 전달은 대화상대가 있어야 하며, 주제와 관련없이 대화창을 통해 정보가 구분된다. 



이슈(주제)가 아닌 대화창(대화상대)으로 정보를 구분

사람들은 자료를 찾을 때 머리 속에, 파일의 제목이나 이미지, 이슈 자체, 혹은 내가 했던 일이나 의사결정 중 하나를 먼저 떠올리게 된다. 

떠올렸던 정보를 기준으로 연관된 자료를 찾는다.

메신저는 대화상대를 기준으로 대화창을 열어 자료를 찾을 수 밖에 없다보니, 지난 히스토리나 정보를 찾는데 한계가 있다. 

다행히 슬랙은 "파일"에 있어서는 따로 모아주지만, 파일이 아닌 정보의 전달이나 의사결정 과정 등은 여전히 한계를 가진다. 







이슈의 혼재 + 일상대화까지 혼재

또한, 대화창을 기준으로 모든 대화가 오가다 보니, 하나의 대화창 안에서 너무 많은 주제로 대화하게 된다. 

중요한 정보와 일상적인 대화가 섞여 결국 원하는 내용을 찾으려면 대화내용을 모두 읽을 수 밖에 없다.





슬랙에서는 검색을 통해 이 부분을 해결한다고 하지만, text 검색의 한계는 극복하기 어려운 것이 사실이다.

같은 맥락을 가진 내용도 사람마다 다른 단어를 사용하게 되는데, 자유도가 높은 메신저 대화에서는 단어 사용의 자유도 역시 높아 검색이 쉽지 않다. 

가령, 팀내 대화에서도, '콜라비 리뉴얼 버전'을 누군가는 "서비스"라고 칭하고, 또 다른 사람들은 "제품", "리뉴얼", "PC버전", "데스크탑", "PC웹" 등 너무 많은 단어들로 지칭되고 있는 현상을 보였다. 

(이 부분은 메신저 플랫폼의 한계라기 보다, text searching 자체의 한계라고 볼 수 있다.)





2. 실시간 커뮤니케이션의 비효율성


실시간 커뮤니케이션은 즉답을 얻을 수 있다는 큰 효과가 있다.

다만, 말을 거는 사람이 원하는 타이밍에 커뮤니케이션이 시작된다. 

이는 메시지를 받는 사람으로 하여금 집중하던 일에 방해요소가 될 수 있다. 이 부분이 업무 효율을 크게 떨어뜨린다. 

(실시간 커뮤니케이션과 비실시간 커뮤니케이션의 장단점은 별도의 글에서 따로 다룰 예정이다.)


또한, 단체창의 경우 대화에 꼭 필요하지 않은 사람까지 알림을 받게 되고, 이 알림 역시 주제별로 걸러낼 수 없다. 

단체창은 너무 괴롭지만, 혹시 중요한 정보를 놓칠세라 결국 하나하나 다 읽어보게 된다. 

위에서 언급했다시피 메신저는 <대화창>을 기준으로 정보가 전달되고 구분되기 때문이다. 



출처: http://blog.collabee.co.kr/45 [콜라비 블로그 :: 협업툴 collabee]

728x90
반응형

'Web Programming' 카테고리의 다른 글

JAVA SFTP 파일 업로드 다운로드 ( JSCH )  (0) 2023.02.17
MVC Pattern  (0) 2018.09.05
tracert와 traceroute의 차이점  (0) 2018.08.30
프레임워크와 라이브러리의 차이  (0) 2018.08.29
캐시와 쿠키의 차이  (0) 2018.08.29

+ Recent posts