스프링과 안드로이드 연동3 : ( 서버에서 XML로 반환해 가져오기 )

by 조쉬 posted Jul 04, 2018
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

크게 작게 위로 아래로 댓글로 가기 인쇄

먼저, 이 작업을 하기 위해서 Spring 프로젝트에서 pom.xml에 3가지 라이브러리를 추가해주어야 한다.

[필요 라이브러리]


1.org.jdom을 mvnrepoisitory에서 검색해 dependency를 pom.xml에 추가한다.

-> 자바 객체를 가지고 xml을 생성해주는 라이브러리


2.json-simple 도 추가

-> json 객체를 생성


3.jackson-databind 추가

-> 스프링 컨트롤러에서 @ResponseBody로 json으로 전송하기 위해 사용



3개의 라이브러리를 pom.xml에 추가했으면 다음으로 스프링 컨트롤러에서


XML로 보낼 데이터를 구성해 전달하는 코드를 작성해 주어야 한다.

(mvnrepository에서 검색해서 추가하자.)


그 다음 아래는 서버쪽 컨트롤러 코드에 대한 부분이다.


bookService.bookList()를 통해서 db에서 BookDTO 객체를 갖는 List를 반환받아서 이 List 정보를 XML 형태로 만들어서

return하는 내용의 코드이다. XML을 구성하는 부분은 주석으로 남겨 놓았다.


List<BookDTO> 를 가지고 구성할 XML 의 구성은 아래와 같다.


<books>
<book>
<book_code>1</book_code>
<book_name>자바</book_name>
<press>출판사</press>
</book>
</books>

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
34
35
36
37
38
39
40
41
42
43
44
@ResponseBody // 리턴 자료형을 xml or json으로 반환
     @RequestMapping(value="xml.do",produces="application/json;charset=utf-8")
     //    json으로 만들고 utf-8 인코딩을 적용(한글깨지는 것 방지)
     public String xml(){
          List<BookDTO> items = bookService.bookList();
       //  org.jdom2 패키지
       //  root 노드(태그)
         Element root = new Element("books");
       //   xml 문서 객체
         Document doc = new Document(root);
       //  xml 문서에 root 노드 설정, detach() : 새로운 문서를 만들기 전에 클리어(초기화)시킴
         doc.setRootElement(root.detach());
          String result = "";
         for(BookDTO dto : items){
        //      태그 생성 : <book>텍스트</book>
              Element data = new Element("book");
              Element book_code = new Element("book_code");
              book_code.setText(dto.getBook_code()+"");
              Element book_name = new Element("book_name");
              book_name.setText(dto.getBook_name());
              Element press = new Element("press");
              press.setText(dto.getPress());
              Element price = new Element("price");
              price.setText(dto.getPrice());
              Element amount = new Element("amount");
              amount.setText(dto.getAmount()+"");
              data.addContent(book_code);
              data.addContent(book_name);
              data.addContent(press);
              data.addContent(price);
              data.addContent(amount);
         }
         //Document 타입을 스트링으로 변환
         // xml 출력을 위한 객체
         XMLOutputter xout = new XMLOutputter();
          Format f = xout.getFormat(); // org.jdom2 xml 문서의 포맷설정
          f.setEncoding("utf-8"); //  인코딩 방식 설정
          f.setIndent("\t");  // 들여쓰기 문자
          f.setLineSeparator("\r\n"); // 줄바꿈 문자
          f.setTextMode(Format.textMode.TRIM);    // 공백제거
          xout.setFormat(f);  // 문서 포맷 적용
          result = xout.outputString(doc);    // 문자열로 변환
        return result;
     }



여기까지 했으면 스프링 프로젝트에서 필요한 부분은 끝이났다.

이제 안드로이드에서 스프링에서 던진 데이터를 저장하기 위한 BookDTO 클래스를 만들자



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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package com.example.kscs.androidspringconnection1.dto;
 
/**
 * Created by kscs on 2017-06-04.
 */
 
public class BookDTO {
    private int book_code;
    private String book_name;
    private String press;
    private int price;
    private int amount;
    // getter setter
 
    public int getBook_code() {
        return book_code;
    }
 
    public String getBook_name() {
        return book_name;
    }
 
    public String getPress() {
        return press;
    }
 
    public int getPrice() {
        return price;
    }
 
    public int getAmount() {
        return amount;
    }
 
    public void setBook_code(int book_code) {
        this.book_code = book_code;
    }
 
    public void setBook_name(String book_name) {
        this.book_name = book_name;
    }
 
    public void setPress(String press) {
        this.press = press;
    }
 
    public void setPrice(int price) {
        this.price = price;
    }
 
    public void setAmount(int amount) {
        this.amount = amount;
    }
 
    @Override
    public String toString() {
        return "BookDTO{" +
                "book_code=" + book_code +
                ", book_name='" + book_name + '\'' +
                ", press='" + press + '\'' +
                ", price=" + price +
                ", amount=" + amount +
                '}';
    }
}


그리고 마지막으로 안드로이드에 관련된 작업이다.

역시 네트워크 작업임으로 앞에서 한 예제에서 주의해야하는 3가지 사항을 지켜주어야 한다.

1. 네트워크 작업임으로 백그라운드 스레드로 동작시켜야한다.

2. 네트워크 접근이 필요함으로 인터넷 권한을 주어야한다.

3. 백그라운드 스레드에서 메인 뷰에 접근할 수 없음으로 핸들러를 통해 처리해야한다.


위 사항을 기반으로해서 XMLPullparser를 이용해 데이터를 끄집어 내 핸들러를 통해 안드로이드에 출력해주면 된다.

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package com.example.kscs.androidspringconnection1;
 
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.ListViewCompat;
import android.widget.ArrayAdapter;
import android.widget.ListView;
 
import com.example.kscs.androidspringconnection1.dto.BookDTO;
 
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
 
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
 
public class XmlActivity extends AppCompatActivity implements Runnable
{
 
    // 1. 변수 선언
    ListView list1;
    List<BookDTO> items;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_xml);
 
        // 2. 위젯 연결
        list1 = (ListView)findViewById(R.id.listView1);
        items = new ArrayList<>();
 
 
        // 3. 스레드 객체 생성
        Thread th = new Thread(this);
        th.start();
    }
 
    // 네트워크 작업임으로 백그라운드 스레드로 동작
    @Override
    public void run() {
        // 네트워크에 접속, xml 리턴
        try{
            // 스프링 컨트롤러에서 xml로 만든 json을 리턴하는 RequestMapping url
            URL url = new URL("http://192.168.0.9/spring01/xml.do");
            // xml 분석기 객체 생성
            XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
            // 스트림 생성
            InputStream is = url.openStream();
            // xml 분석기에 스트림을 입력
            parser.setInput(is,"utf-8");
            // xml 문서의 이벤트(태그의 시작, 끝 등)
            int eventType = parser.getEventType();
            String tag;
            BookDTO dto =  null;
            while( eventType != XmlPullParser.END_DOCUMENT ){
                switch (eventType){
                    case XmlPullParser.START_TAG: // 시작 태그
                        tag = parser.getName(); // 태그의 이름
                        if ( tag.equals("book_name")){
                            dto = new BookDTO();
                            // 태그의 text를 가져와 세팅
                            dto.setBook_name(parser.nextText());
                        }
                        // <press>영진</press>
                        if(tag.equals("press")){
                            dto.setPress(parser.nextText());
                        }
                        break;
                    // </book>
                    case XmlPullParser.END_TAG:
                        tag = parser.getName();
                        if(tag.equals("book")){
                            items.add(dto);
                            dto = null;
                        }
                        break;
                }
                eventType = parser.next(); // 다음으로 이동
            }
            // 여기까지 수행하면 xml분석해서 List에 추가가 완료!
        }catch (Exception e){
            e.printStackTrace();
        }
        // 핸들러에게 메시지 호출(리스트뷰 갱신처리)
        // handlerMessage()가 호출됨
        handler.sendEmptyMessage(1);
    }
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            // 리스트뷰에 출력
            String[] books = new String[items.size()];
            for(int i=0; i<books.length; i++){
                BookDTO dto = items.get(i);
                books[i] = dto.getBook_name() + "(" + dto.getPress() + ")";
            }
            // 어댑터 생성
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(XmlActivity.this,android.R.layout.simple_list_item_1,books);
            // 어댑터와 데이터 바인딩
            list1.setAdapter(adapter);
        }
    };
}


Articles

1 2