[java] [jackson] Map - JSON간 변환

Map - JSON간 변환

 

writeValueAsString()

writeValueAsString( value ) 

  • value: String 타입으로 변환할 대상

 

readValue()

readValue( arg, type )

  • arg: 지정된 타입으로 변환할 대상
  • type: 대상을 어떤 타입으로 변환할것인지 클래스를 명시한다. Class객체, TypeReference객체가 올 수 있다.

ex)

mapper.readValue(arg, ArrayList.class);
mapper.readValue(arg, new ArrayList<HashMap<StringString>>().getClass());
mapper.readValue(arg, new TypeReference<ArrayList<HashMap<StringString>>>(){});
cs

 

map

맵 타입이 JSON 형식의 String 타입으로 변환된다. 자바스크립트에 JSON을 넘겨줄 때 유용하다. 

import com.fasterxml.jackson.databind.ObjectMapper;
 
public class Test2 {
    public static void main(String[] args) throws Exception {
 
        ObjectMapper mapper = new ObjectMapper();
 
        HashMap<StringString> map = new HashMap<StringString>();
        map.put("name""steave");
        map.put("age""32");
        map.put("job""baker");
 
        System.out.println(map);
        System.out.println(mapper.writeValueAsString(map));
    }
}
 
// {age=32, name=steave, job=baker}
// {"age":"32","name":"steave","job":"baker"}
cs

위와 반대로 JSON을 맵 타입으로 변환하려면 다음처럼 작성한다:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
 
public class Test2 {
    public static void main(String[] args) throws Exception {
 
        ObjectMapper mapper = new ObjectMapper();
        HashMap<StringString> map = new HashMap<StringString>();
 
        String jsn = "{\"age\":\"32\",\"name\":\"steave\",\"job\":\"baker\"}";
        
        map = mapper.readValue(jsn, 
                new TypeReference<HashMap<StringString>>() {});        
        
        System.out.println(map);
    }
}
 
// {name=steave, age=32, job=baker}
cs

 

List<Map>

다음은 view에 전달할 model이 List<map<?, ?>> 타입일 때 이를 JSON으로 변환하는 방법이다. 사용방법은 크게 다르지 않고 writeValueAsString, readValue 메서드를 사용하되 타입 명시만 달리한다.

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
 
public class Test2 {
    public static void main(String[] args) throws Exception {
 
        ObjectMapper mapper = new ObjectMapper();
 
        // map -> json
        ArrayList<HashMap<StringString>> list 
                = new ArrayList<HashMap<String,String>>(); 
        
        HashMap<StringString> map = new HashMap<StringString>();
        map.put("name""steave");
        map.put("age""32");
        map.put("job""baker");
        list.add(map);
        
        map = new HashMap<StringString>();
        map.put("name""matt");
        map.put("age""25");
        map.put("job""soldier");
        list.add(map);
        
        System.out.println(mapper.writeValueAsString(list));
        
        // json -> map
        String jsn = "[{\"age\":\"32\",\"name\":\"steave\",\"job\":\"baker\"},"
                + "{\"age\":\"25\",\"name\":\"matt\",\"job\":\"soldier\"}]";
        list = mapper.readValue(jsn, 
                new TypeReference<ArrayList<HashMap<StringString>>>() {});        
        
        System.out.println(list);
    }
}
 
 
// [{"age":"32","name":"steave","job":"baker"},{"age":"25","name":"matt","job":"soldier"}]
// [{name=steave, age=32, job=baker}, {name=matt, age=25, job=soldier}]
cs

 

----------------------------------------------------------------------------------------------------------------------------------------------

 

 

Jackson 은 자바용 json 라이브러리로 잘 알려져 있지만 Json 뿐만 아니라 XML/YAML/CSV 등 다양한 형식의 데이타를 지원하는 data-processing 툴이다.

스트림 방식이므로 속도가 빠르며 유연하며 다양한 third party 데이타 타입을 지원하며 annotation 방식으로 메타 데이타를 기술할 수 있으므로 JSON 의 약점중 하나인 문서화와 데이타 validation 문제를 해결할 수 있다.

구성

core module

사용

maven 설정

databind 는 jackson-core, jackson-annotation 에 의존성이 있으므로 pom 파일에는 databind 모듈만 기술해주면 된다.

<properties>
    <jackson.version>2.4.4</jackson.version>
</properties>
  
<dependencies>       
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
</dependencies>

 

POJO 와 사용

https://github.com/FasterXML/jackson-databind/

// getter/setter 를 만들지 않기 위해 public 으로 선언
// lombok 을 사용하면 간편
public class MyValue {
  public String name;
  public int age; 
}

 

com.fasterxml.jackson.databind.ObjectMapper 인스턴스 생성

ObjectMapper mapper = new ObjectMapper(); // create once, reuse

 

json 데이타를 java object 로 변환

data.json
{
    "name""Bob",
    "age"13
}

 

File, URL, String 방식으로 데이타를 읽어올 수 있음.

MyValue value = mapper.readValue(new File("data.json"), MyValue.class);
//  URL 에서 읽기
value = mapper.readValue(new URL("http://some.com/api/entry.json"), MyValue.class);
// String 으로 읽기
value = mapper.readValue("{\"name\":\"Bob\", \"age\":13}", MyValue.class);

java object 를 json 으로 변환

MyValue  myResultObject = new MyValue();
myResultObject.name = "MyName";
myResultObject.age= 11;
  
// result.json 파일로 저장
mapper.writeValue(new File("result.json"), myResultObject);
// byte[] 로 저장
byte[] jsonBytes = mapper.writeValueAsBytes(myResultObject);
// string 으로 저장
String jsonString = mapper.writeValueAsString(myResultObject);

 

json 으로 변환시 개행하여 포맷팅

{"string":"foo","number":5,"array":[1,2,3],"object":{"property":"value","subobj":{"arr":["foo","ha"],"numero":1}}}

위와 같은 json 데이타를 다음처럼 보기 좋게 출력하려면 ObjectMapper.writerWithDefaultPrettyPrinter를 사용하면 된다.

 여기를 클릭하여 펼치기...
// 포맷팅하여 스트링으로 변환
String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(myResultObject);
  
// 포맷팅하여 파일로 저장
mapper.writerWithDefaultPrettyPrinter().writeValue(new File("output.json"), myResultObject);

 

Generic Collation/Tree Model 로 사용

  

 

Configurator

 

 

Annotation

@JsonIgnoreProperties

크게 2가지 용도가 있으며 첫 번째는 Serializer/Deserialize 시 제외시킬 프로퍼티를 지정한다. 다음과 같이 지정하면 foo, bar는 제외된다. 개별 프로퍼티를 제외하려면 

@JsonIgnore annotation을 프로퍼티에 적용하면 된다.

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

@JsonIgnoreProperties({ "foo""bar" })
public class MyBean
{
   //아래 두 개는 제외됨.
   public String foo;
   public String bar;
 
   // will not be written as JSON; nor assigned from JSON:
   @JsonIgnore
   public String internal;
 
   // no annotation, public field is read/written normally
   public String external;
    
   @JsonIgnore
   public void setCode(int c) { _code = c; }
 
   // note: will also be ignored because setter has annotation!
   public int getCode() { return _code; }
}

 

@JsonProperty

getter/setter 의 이름을 property 와 다른 이름을 사용할 수 있도록 설정한다. Database 를 자바 클래스로 매핑하는데 DB의 컬럼명이 알기 어려울 경우등에 유용하게 사용할 수 있다.

다음과 같은 테이블이 있을 경우

CREATE TABLE Users (
  INT NOT NULL,
  INT NOT NULL,
  VARCHAR(80) NOT NULL
);

다음과 같이 JsonProperty 를 사용하면 DB 의 컬럼명을 변경하지 않아도 가독성을 높일 수 있다.

public class User
{
    @JsonProperty("userId");
    public Integer u;
  
    @JsonProperty("age");
    public Integer a;
  
    @JsonProperty("email");
    public String e;
}

json 으로 변환된 결과

{
    "userId"1,
    "age"13,
    "email""user@host.com"
}

 

@JsonInclude

Serialize 시 동작을 지정한다. 기본적으로 잭슨은 값의 유무와 상관없이 무조건 serialize 하게 되지만 다음과 같이 설정할 경우 not null 이거나 none empty 일 경우에만 serialize 된다.

public class User
{
    public Integer u;
     
    @JsonInclude(Include.NON_NULL)
    public Integer age;
 
 
    @JsonInclude(Include.NON_EMPTY)
    public String email;
}

 

 

 

https://www.lesstif.com/pages/viewpage.action?pageId=24445183#JavaJsonlibraryjackson사용법-json데이타를javaobject로변환

 

 


 

Spring에서 Json으로의 입출력 정리

Java/spring 2014.05.17 17:13 Posted by MADNIX
이번에 프로젝트를 진행하면서 Spring에서 사용하는 Jackson Json 라이브러리를 조금 디테일하게 이용해야 하는 상황이 생겨서 이에 대한 내용을 정리하고자 한다.
일단 Json과 관련되어 작업의 내용은..
  1. Java 객체에 저장된 값을 Json 형태로 변환하여 Request Body에 실어서 보내야 한다(이때 String 형 변수가 아닌 다른 형(ex : int 형)을 String 형태(쌍따옴표로 감싼 형태 : "123")로 보내야 한다.
  2. Java 객체에 저장된 값을 Json 형태로 변환하여 보낼때 선별적으로 보낼수 있어야 한다. (무슨뜻이냐면 Json으로 보낼때 모든 필드를 다 사용하는것이 아니라 특정 필드는 제외해서 사용할 수 있어야...)
  3.  Request의 Body로 온 Json 내용을 Java 객체로 매핑해서 이용한다.

 

이제 이 부분을 Spring과 연관지어 정리해보도록 하겠다.
 
일상적으로 프로젝트를 진행하면서 JSON 문자열을 만드는 방법은 여러가지 방법이 있다.
JSON 문법을 아는 사람이라면 아예 String 변수에 JSON 문법 형태가 적용된 문자열을 만들어서 넣는 아주 로우레벨 스타일도 있을수 있고..
나같이 문법을 잘 몰라서 라이브러리 도움을 받아야 하는 사람이라면 JSON 문자열로 표현할 내용을 담은 VO에 JSON 관련 어노테이션들을 붙여서 이를 통해 JSON 문자열을 만드는 방법도 있을 것이다..
일단 나는 후자의 방법을 선택했다..
그리고 이렇게 만든 문자열을 java의 HttpUrlConnection을 이용해서 보냈다.
여기서는 HttpUrlConnection에 대한 얘기는 하지 않을 것이다. JSON 문자열을 만드는 방법과 JSON 문자열을 객체로 받는 법에 대해서만 얘기할 것이다
 
일단 다음의 예시 VO를 보자..
다음의 VO는 내가 JSON으로 보내고자 하는 내용을 담은 객체에 JSON 처리 관련 어노테이션이 붙은 것이다..
JSON 관련 어노테이션을 빼고 본다면 우리가 Spring에서 다루는 일반적인 VO와 차이가 없다..
 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@JsonAutoDetect(fieldVisibility=Visibility.NONE,
                getterVisibility = Visibility.NONE,
                setterVisibility = Visibility.NONE)
@JsonPropertyOrder({"unit_id", "unit_code", "lvl", "name",
                    "regDate", "orders", "imgPath", "status"})
public class UnitVO extends CommonVO implements Cloneable {
 
     @JsonProperty("unitID") @JsonSerialize(using = ToStringSerializer.class)
     int unit_id;                  
     @JsonProperty("unitCode")
     String unit_code;             
     @JsonProperty("lvl") @JsonSerialize(using = ToStringSerializer.class)
     int lvl;                       
     @JsonProperty("name")
     String name;                  
     @JsonProperty("regDate")
     String reg_date;             
     @JsonProperty("orders") @JsonSerialize(using = ToStringSerializer.class)
     int orders;                       
     @JsonProperty("imgPath")
     String img_path;             
     @JsonProperty("status") @JsonSerialize(using = ToStringSerializer.class)
     int status;                       
     
     int apistatus;                  
     
     String upper_unit_code;        
     int subcnt;                       
     String statusdesc;             
     String loginid;                  
      
     /* getter와 setter는 생략 */
}

 

@JsonPropertyOrder는 Json 문자열로 표현할때 표현되는 멤버필드의 순서를 정하는 것이다.
위의 예제대로 한다면 Json 문자열로 표현할때 unit_id, unit_code, lvl ... 순으로 Json 문자열을 만들것이다.
이때 주의할 점은 @JsonPropertyOrder에 넣어야 할 값들은 @JsonProperty 어노테이션으로 설정되는 Json 필드명이 아니라... 클래스의 필드명으로 주어야 한다는 것이다.
 
@JsonProperty 어노테이션이 가장 핵심적인 역할을 한다. 이 어노테이션이 붙은 멤버필드, getter, setter에만 JSON 관련 작업을 하게 되는 것이다. 즉 JSON 문자열로 출력하거나 또는 JSON 문자열에서 읽어들이는 것이다.
 
예를 들어 @JsonProperty("unitID") 라고 멤버필드에 붙이면 unitID란 Key로 해당 필드의 값을 JSON으로 출력하거나 또는 JSON 문자열에서 unitID란 Key에 해당되는 값을 읽어 멤버 필드에 넣게 된다. 멤버 필드에서 설정하게 되면 JSON 문자열로 읽고 쓰는 작업 모두를 할수 있으며 getter 함수에 붙인다면 JSON 문자열로 출력하는 작업만 가능하며, setter 함수에 붙인다면 JSON 문자열에서 읽어들이는 작업만 가능하게 된다.  지금의 예에서는 @JsonProperty("unitID")라고 설정해서 필드 변수명과 Json Key 이름을 달리 주었으나 이 Key를 생략하면 필드 변수명 동일하게 Json Key 이름을 사용하게 된다.
 
@JsonSerializer는 Json 문자열로 출력할때 특별한 작업을 할 상황이 있을 경우org.codehaus.jackson.map.JsonSerializer 클래스를 상속받아 관련 기능을 구현하면 된다. 
자바 객체에서 JSON 문자열로 만드는 것을 Serialize, JSON 문자열에서 자바 객체로 만드는 것을 Deserialize라고 한다. 
그래서 org.codehaus.jackson.map.JsonDeserializer 라는 클래스도 존재한다.
(물론 기능은 JsonSerializer 클래스가 하는 것과는 정반대의 역할일것이다)
 
암튼 정리하자면 Json 문자열로 출력할때 특별한 작업을 할 상황이 있다면 JsonSerialize 클래스를 상속받은 클래스를 만들어서 관련 기능을 구현한뒤 이를 @JsonSerializer 어노테이션의 using 속성에 관련 클래스 이름을  명시해주면 된다. 이걸 쓴 이유는 위에서 얘기했을때 String 변수가 아닌 자료형일 경우 강제로 String 형으로 만들어서 JSON 문자열에서 표현한다고 했었다. 그 기능을 하기 위해 JsonSerializer 클래스를 상속받은 별도 클래스를 만든 것이다.
 
다음의 코드를 보면 좀더 이해가 될 것이다.

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.io.IOException;
 
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
 
public class ToStringSerializer extends JsonSerializer<Object> {
 
    @Override
    public void serialize(Object value, JsonGenerator jgen,
         SerializerProvider provider) throws IOException,
         JsonProcessingException {
             jgen.writeObject(value.toString());
      }
}

 

value 란 변수에는 우리가 VO의 필드멤버에서 읽은 값이 들어오게 된다. 이를 toString 함수를 이용해서 String 문자열로 변환된 값을 읽은후 writeObject를 이용해서 JSON 문자열로로 출력하게 된다. 그러면 int 형이래도 (ex : 3333) String 형으로 (ex : "3333") 출력시켜주는 것이다
 
이렇게 JSON으로 변환한 문자열을 HttpUrlConnection 클래스를 이용해 Body에 실어보내면 그걸 받는 Spring 쪽에서는 어떻게 할 것인가????...  의외로 간단하다.
 
다음의 코드는 Spring의 Controller에서 JSON 문자열을 받아서 이를 객체에 넣는  함수이다.

 

 

 

1
2
3
4
5
6
7
8
9
  @RequestMapping(value="/group/{groupId}", method=RequestMethod.POST)
  public ResultVO myUnit(
      @PathVariable("groupId")
      String unitCode,
     @RequestBody UnitVO objUnit,
      HttpServletRequest request
      ) throws Exception {
   ....
}

 

위의 코드를 보면 @RequestBody 란 어노테이션이 있다. 이 어노테이션은 Http Request Body에 있는 내용을 @RequestBody 어노테이션 다음에 명시하는 클래스에 매핑해주게 된다. 
만약 @RequestBody String strBody 요래버리면 Request Body에 있는 문자열을 그대로 String에 담아주게 된다. 
그러면 String이 아닌 UnitVO와 같은 사용자 클래스라면? 
그렇다면 그 클래스의 내부 구성에 맞춰서 매핑시켜주게 된다. 그 근거는 클래스 내부에 선언한 어노테이션 내용을 보고 매핑하게 된다. 지금의 상황은 Request Body가 Json이라서 자동으로 Json을 파싱해서 매핑해주는게 아니다. Spring 스스로는 이 문자열이 Json인지 XML 인지 알길이 없다. 그걸 판단하는 근거는 Http Header값을 읽어보고 그거에 따라 매핑할 방법을 결정하는 것이다.
 
이제 마지막으로 JSON 문자열을 만들때 선별적으로 만드는 방법에 대해 설명하고자 한다.
요청받은것중에 특정 필드는 JSON 문자열을 만들때 제외하고 싶다는 것이 있었다. 즉 상황에 따라 유동적으로 출력 필드를 제어하고 싶은 것이었다.
 
위에서 언급했던 UnitVO 클래스의 예를 들어 다시 설명하겠다.
이 클래스에 name 필드가 있다. 이 필드에는 @JsonProperty("name") 어노테이션이 붙어있기 때문에 name 필드 값을 JSON의 name이란 key 값으로 출력하거나 읽어들일 수 있다. 근데 상황에 따라 UnitVO를 이용해서 JSON 문자열을 만들때 name 필드를 제외하고 싶을수가 있다. 이럴 때 하는 방법에 대한 얘기를 하고자 한다.
 
JacksonJson 라이브러리에서는 이런 작업때문에 Filter 개념이 도입되는데... 먼저 다음과 같은 Dummy 클래스를 하나 만든다.

 

 

 

1
2
3
4
5
import org.codehaus.jackson.map.annotate.JsonFilter;
 
@JsonFilter("filter properties by name")
public class PropertyFilterMixIn {
}

 

@JsonFilter 어노테이션만 붙어 있고 안에는 아무런 내용이 없어서 Dummy 클래스라고 표현했다.
@JsonFilter 란 어노테이션을 사용하여 일종의 이름을 부여하게 된다. 여기서는 filter properties by name 이란 이름을 부여했다.
 
그럼 이것을 어떻게 사용하는지 보자.
 
 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;
import org.codehaus.jackson.map.ser.FilterProvider;
import org.codehaus.jackson.map.ser.impl.SimpleBeanPropertyFilter;
import org.codehaus.jackson.map.ser.impl.SimpleFilterProvider;
 
UnitVO obj = service.getUnitVO();
String [] excludeFieldNames = {"name"};
ObjectMapper mapper = new ObjectMapper();
ObjectWriter writer = null;
    if(excludeFieldNames != null){
         mapper.getSerializationConfig().addMixInAnnotations(Object.class, PropertyFilterMixIn.class);   
         FilterProvider filters = new SimpleFilterProvider().addFilter("filter properties by name", SimpleBeanPropertyFilter.serializeAllExcept(excludeFieldNames)); 
     writer = mapper.writer(filters);
}else{
     writer = mapper.writer();
}
String jsonString = writer.writeValueAsString(obj);

 

참조할 수 있도록 사용하는 클래스의 package를 넣었다.
소스 설명을 하자면..Json으로 변환하고자 하는 객체(obj)가 있다. 그리고 여기서 json 출력에서 제외하고 싶은 필드인 name을 String 배열에 넣는다. 그런 다음 ObjectMapper 객체를 만든뒤에 
출력에서 제외하고 싶은 필드 이름이 들어가 있는 배열(excludeFieldNames)이 null이 아니면 addMixInAnnotations 함수에 위에서 만든 Dummy Filter 클래스를 등록시켜준다.
등록된 Filter에 excludeFieldNames 을 설정해서 ObjectWriter 객체를 만들어준뒤 이 ObjectWriter 객체에 JSON으로 변환하고자 하는 객체를 넣어서 JSON문자열을 출력하면 excludeFieldNames 배열에 들어가 있는 필드명의 값을 제외한 나머지 JSON으로 출력할수 있는 것들은 출력해주게 된다.
 

[출처] https://engaspect.tistory.com/27

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
161 [Java 자료구조] JPA와 Spring Data JPA의 차이 file 졸리운_곰 2022.09.09 28
160 [java 자료구조] 하이버네이트 쉽게 입문하기 (기초)-환경설정,입력조회 개발 file 졸리운_곰 2022.09.09 21
159 [Java 자료구조] JPA, Hibernate, 그리고 Spring Data JPA의 차이점 졸리운_곰 2022.09.09 21
158 [Java][MyBatisc] myBatis에서 null과 nullString을 체크할 때 졸리운_곰 2021.09.13 32
157 [MongoDB/Java] MongoDB에 JSON 형식 데이터 삽입하기 file 졸리운_곰 2021.07.13 26
156 [Java, MongoDB] mongodb java driver 3.0: how to store JSON document 졸리운_곰 2021.07.13 29
155 [Java 자료구조] [Java] 문자열의 첫 글자 제거 졸리운_곰 2021.05.24 401
154 [Java 자료구조] [java] 특정 문자열 사이의 문자열 추출하기, 정규식 졸리운_곰 2021.05.24 1875
153 [Java 자료구조] [JAVA] Java언어로 JSON 생성, 파싱 예제 file 졸리운_곰 2021.05.17 19
152 [Java 자료구조] [Java] Immutable Class (불변 클래스) file 졸리운_곰 2021.03.07 26
151 [Java 자료구조] 불변 객체란? Java Immutable Object file 졸리운_곰 2021.03.07 48
150 [Java 자료구조] [Java] Immutable Object(불변객체) 졸리운_곰 2021.03.07 44
149 [java 자료구조] Oracle + Mybatis 환경에서의 Date 다루기 졸리운_곰 2021.02.25 55
148 Java JSON library Jackson Date Date Json 시리얼라이즈/디씨리얼라이즈 file 졸리운_곰 2021.02.25 28
147 [Java, JSON, jackson] Ignoring new fields on JSON objects using Jackson 졸리운_곰 2021.02.19 16
146 [Java] [Jackson] JsonInclude 속성에 대해 알아보자. 졸리운_곰 2021.02.03 592
» [java] [jackson] Map - JSON간 변환 졸리운_곰 2021.02.02 41
144 [java] [자료구조] Remove null values from json using jackson 졸리운_곰 2021.02.02 78
143 자바 인코딩 관련 문제 종합 정리 file 졸리운_곰 2021.01.29 40
142 [Java 디자인패턴] [JAVA 디자인 패턴] static을 응용한 싱글톤 패턴(Singleton Pattern) 구현 졸리운_곰 2021.01.22 20
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED