1. 인덱스로 메뉴 만들기
- layout > header.html 에 메뉴 추가(링크 생성하기)
<!DOCTYPE html>
<html>
<header>
<h1>헤더영역</h1>
<div class="wrap view-size">
<a href="/">HOME</a>
<a href="/board">게시글</a>
<a href="/my-board">마이게시글</a>
<a href="/subway">지하철 엘레베이터</a>
</div>
</header>
</html>
- 해당 위치에 html 생성하기 (myboard > list.html)
<!DOCTYPE html>
<html xmlns:th="//www.thymeleaf.org"
th:replace="layout/layout1 :: layout(~{::head},~{this::main})" >
<head>
</head>
<main>
<h1>메인영역</h1>
<div class="wrap view-size">
<section>
<h1>게시글내용</h1>
<div class="wrap">
<p class="tit">지하철 엘레베이터 정보</p>
</div>
</section>
</div>
</main>
2. 컨트롤러 만들기
- @Controller 어노테이션 적용
- @Getmapping 할 메서드 만들기 :
@GetMapping(어디 주소로 들어오면?)
public String 메서드명(){ return "여기로 이동시켜줘"}
ㅡmodel 메서드 넣기 (추후 인터페이스와 클래스에 값에도 model 넣어주기)
package com.green.nowon.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.green.nowon.service.SubwayElevatorService;
import lombok.RequiredArgsConstructor;
//@RequiredArgsConstructor
@Controller
public class SubwayController {
private final SubwayElevatorService service; //Constructor DI
public SubwayController(SubwayElevatorService service) {
this.service = service;
}
@GetMapping("/subway")
public String subway(Model model) throws Exception {
service.getElevatorInfo(model);
return "subway/list";
}
}
3. 서비스 인터페이스 만들기
- 컨트롤러에 서비스 할 인터페이스 생성하기 :
private final 인터페이스명 service;
- 자동 생성하기
package com.green.nowon.service;
public interface SubwayElevatorService {
}
- 인터페이스 상속받은 클래스 생성하기: @Service 적용해주기
package com.green.nowon.service.impl;
import org.springframework.stereotype.Service;
import com.green.nowon.service.SubwayElevatorService;
@Service
public class SubwayElevatorServiceProcess implements SubwayElevatorService{
}
4. 생성자 초기화 해주기
방법 1> 클래스에 @RequiredArgsConstructor 적용하기
package com.green.nowon.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import com.green.nowon.service.SubwayElevatorService;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Controller
public class SubwayController {
private final SubwayElevatorService service; //Constructor DI
@GetMapping("/subway")
public String subway() {
return "subway/list";
}
}
방법 2> public 컨트롤러이름(서비스명 변수){ this.변수 = 변수};
package com.green.nowon.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import com.green.nowon.service.SubwayElevatorService;
import lombok.RequiredArgsConstructor;
@Controller
public class SubwayController {
private final SubwayElevatorService service; //Constructor DI
public SubwayController(SubwayElevatorService service) {
this.service = service;
}
@GetMapping("/subway")
public String subway() {
return "subway/list";
}
}
- subway 메서드에 가지고올 정보의 메서드 넣기 예> service.getElevatorInfo();
package com.green.nowon.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import com.green.nowon.service.SubwayElevatorService;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Controller
public class SubwayController {
private final SubwayElevatorService service; //Constructor DI
/*
* public SubwayController(SubwayElevatorService service) { this.service =
* service; }
*/
@GetMapping("/subway")
public String subway() {
service.getElevatorInfo();
return "subway/list";
}
}
- 자동으로 메서드와 오버라이드 생성
package com.green.nowon.service;
public interface SubwayElevatorService {
void getElevatorInfo();
}
package com.green.nowon.service.impl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.green.nowon.service.SubwayElevatorService;
@Service
public class SubwayElevatorServiceProcess implements SubwayElevatorService{
@Override
public void getElevatorInfo() {
// TODO Auto-generated method stub
}
}
5. 키 정보 가지고 오기
https://data.seoul.go.kr/dataList/OA-15514/S/1/datasetView.do
열린데이터광장 메인
데이터분류,데이터검색,데이터활용
data.seoul.go.kr
- 서울시 장애인 편의시설 정보에서 open API 에 인증키 신청 후 키발급
-> 불러올 데이터의 키값의 변수 선언 private String 변수명
-> @Value("${seoul.key}") 후 git config server 에 업데이트 또는 Value(키값)
@Value("${seoul.key}")
private String seoulKey;
- api 이용안내 클릭 후 복사 붙여넣기 - 예외처리 및 내 data 형식과 맞게 수정해주기
* 컨트롤러 서비스까지 Exception 으로 예외처리 해주기
- 가이드를 따라 내 프로젝트에 맞게 수정해주기
-> sample 이나 데이터 타입 등
package com.green.nowon.service.impl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.green.nowon.service.SubwayElevatorService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class SubwayElevatorServiceProcess implements SubwayElevatorService{
@Value("${seoul.key}")
private String seoulKey;
@Override
public void getElevatorInfo() throws Exception {
StringBuilder urlBuilder = new StringBuilder("http://openapi.seoul.go.kr:8088"); /*URL*/
urlBuilder.append("/" + URLEncoder.encode(seoulKey,"UTF-8") );
urlBuilder.append("/" + URLEncoder.encode("json","UTF-8") ); /*요청파일타입 (xml,xmlf,xls,json) */
urlBuilder.append("/" + URLEncoder.encode("subwayTourInfo","UTF-8")); /*서비스명 (대소문자 구분 필수입니다.)*/
urlBuilder.append("/" + URLEncoder.encode("1","UTF-8")); /*요청시작위치 (sample인증키 사용시 5이내 숫자)*/
urlBuilder.append("/" + URLEncoder.encode("5","UTF-8")); /*요청종료위치(sample인증키 사용시 5이상 숫자 선택 안 됨)*/
// 상위 5개는 필수적으로 순서바꾸지 않고 호출해야 합니다.
// 서비스별 추가 요청 인자이며 자세한 내용은 각 서비스별 '요청인자'부분에 자세히 나와 있습니다.
//urlBuilder.append("/" + URLEncoder.encode("20220301","UTF-8")); /* 서비스별 추가 요청인자들*/
String apiURL=urlBuilder.toString();
System.out.println(apiURL); // URL 정보 가지고 오기
URL url = new URL(apiURL);
//접속 확인하기
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
//conn.setRequestProperty("Content-type", "application/json"); //데이터값 변경
int responseCode = conn.getResponseCode(); /* 연결 자체에 대한 확인이 필요하므로 추가합니다.*/
String responseJSONData=null;
6. 데이터 값 불러오기
- 먼저 연결 성공/ 실패 값 불러오기
int responseCode = conn.getResponseCode(); /* 연결 자체에 대한 확인이 필요하므로 추가합니다.*/
String responseJSONData=null;
//apiUrl주소에 정상적으로 접속헀을때
if(responseCode == HttpURLConnection.HTTP_OK) {
responseJSONData=readBody(conn.getInputStream());
log.debug("-------> JSON-DATA READ SUCCESS!!!!");
}else { //접속 실패 시
responseJSONData=readBody(conn.getErrorStream());
log.debug("-------> JSON-DATA READ ERROR!!!!");
}
System.out.println(responseJSONData);
conn.disconnect();
- 데이터 값 가지고 오기
위에서 만들어진 readbody 메서드 안에 넣기
//////////////////////////
//대소문자 구분하지 않는 맵핑
// JSONSTRING -> java Obj 맵핑
//ObjectMapper mapper=new ObjectMapper()
ObjectMapper mapper = JsonMapper.builder()
.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
.build();
//responseJSONData 데이터를 최상위 데이타에 맵핑해줄게용
ResponseData result = mapper.readValue(responseJSONData, ResponseData.class);
System.out.println(result); // 결과 확인
}
//응답데이터를 스트림을 통해서 한줄씩 읽어서 문자열로 리턴해주는 메서드
private String readBody(InputStream inputStream) throws IOException {
InputStreamReader isr=new InputStreamReader(inputStream) ;
BufferedReader lineReader = new BufferedReader(isr);
StringBuilder responseBody = new StringBuilder(); // return할 데이터를 읽어온다
String data; // return할 데이터
while ( (data = lineReader.readLine()) != null/* 한줄씩 읽어오고, 없을때 그만한다 */) {
responseBody.append(data);
}
lineReader.close(); //예외 발생
isr.close(); //예외 발생
return responseBody.toString();
}
}
>> 5~6번 완성
package com.green.nowon.service.impl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.green.nowon.openapi.seoul.ResponseData;
import com.green.nowon.service.SubwayElevatorService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class SubwayElevatorServiceProcess implements SubwayElevatorService{
@Value("${seoul.key}")
private String seoulKey;
@Override
public void getElevatorInfo() throws Exception {
StringBuilder urlBuilder = new StringBuilder("http://openapi.seoul.go.kr:8088"); /*URL*/
urlBuilder.append("/" + URLEncoder.encode(seoulKey,"UTF-8") );
urlBuilder.append("/" + URLEncoder.encode("json","UTF-8") ); /*요청파일타입 (xml,xmlf,xls,json) */
urlBuilder.append("/" + URLEncoder.encode("subwayTourInfo","UTF-8")); /*서비스명 (대소문자 구분 필수입니다.)*/
urlBuilder.append("/" + URLEncoder.encode("1","UTF-8")); /*요청시작위치 (sample인증키 사용시 5이내 숫자)*/
urlBuilder.append("/" + URLEncoder.encode("5","UTF-8")); /*요청종료위치(sample인증키 사용시 5이상 숫자 선택 안 됨)*/
// 상위 5개는 필수적으로 순서바꾸지 않고 호출해야 합니다.
// 서비스별 추가 요청 인자이며 자세한 내용은 각 서비스별 '요청인자'부분에 자세히 나와 있습니다.
//urlBuilder.append("/" + URLEncoder.encode("20220301","UTF-8")); /* 서비스별 추가 요청인자들*/
String apiURL=urlBuilder.toString();
System.out.println(apiURL); // URL 정보 가지고 오기
URL url = new URL(apiURL);
//접속 확인하기
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
//conn.setRequestProperty("Content-type", "application/json"); //데이터값 변경
int responseCode = conn.getResponseCode(); /* 연결 자체에 대한 확인이 필요하므로 추가합니다.*/
String responseJSONData=null;
//apiUrl주소에 정상적으로 접속헀을때
if(responseCode == HttpURLConnection.HTTP_OK) {
responseJSONData=readBody(conn.getInputStream());
log.debug("-------> JSON-DATA READ SUCCESS!!!!");
}else { //접속 실패 시
responseJSONData=readBody(conn.getErrorStream());
log.debug("-------> JSON-DATA READ ERROR!!!!");
}
//System.out.println(responseJSONData);
conn.disconnect();
//////////////////////////
//대소문자 구분하지 않는 맵핑
// JSONSTRING -> java Obj 맵핑
//ObjectMapper mapper=new ObjectMapper()
ObjectMapper mapper = JsonMapper.builder()
.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
.build();
//responseJSONData 데이터를 최상위 데이타에 맵핑해줄게용
ResponseData result = mapper.readValue(responseJSONData, ResponseData.class);
System.out.println(result); // 결과 확인
}
//응답데이터를 스트림을 통해서 한줄씩 읽어서 문자열로 리턴해주는 메서드
private String readBody(InputStream inputStream) throws IOException {
InputStreamReader isr=new InputStreamReader(inputStream) ;
BufferedReader lineReader = new BufferedReader(isr);
StringBuilder responseBody = new StringBuilder(); // return할 데이터를 읽어온다
String data; // return할 데이터
while ( (data = lineReader.readLine()) != null/* 한줄씩 읽어오고, 없을때 그만한다 */) {
responseBody.append(data);
}
lineReader.close(); //예외 발생
isr.close(); //예외 발생
return responseBody.toString();
}
}
-- 잘 Run 되고 메뉴 눌렀을때 info 가 나오면 여기까지 잘 성공한겨 --
7. 맵핑하기
(1) data 클래스 생성 후 아래 api 참고하여 클래스 추가 생성하기
- ResounseData 클래스 생성하여 아래 SubwayTourInfo 클래스 생성 // 자동생성
- list 와 Result 클래스 생성하기
package com.green.nowon.openapi.seoul;
import lombok.Data;
@Data
public class ResponseData {
private SubwayTourInfo subwayTourInfo; //클래스 만들기, api 참고하여 클래스명 생성
}
package com.green.nowon.openapi.seoul;
import java.util.List;
import lombok.Data;
@Data
public class SubwayTourInfo {
private int list_total_count;
private RESULT result; // 클래스 생성
private List<item> row; //배열이기에 list 로 선언 //이름이 별도 없어서 item //클래스 생성
}
package com.green.nowon.openapi.seoul;
import lombok.Data;
@Data
public class RESULT {
private String CODE;
private String MESSAGE;
}
(2) item 클래스에 샘플코드 넣어주기
- Crtl +f 후 " 는 지워주고 : 는 ; // 로 바꿔주기
- 후 private String 넣어주기
package com.green.nowon.openapi.seoul;
import lombok.Data;
@Data
public class item { //18개 필드 필요
private String NO; // 173
private String LINE; // 4,
private String LINE_NAME; // 4호선,
private String STATION; // 노원,
private String STATION_IMAGE; // <img src=\https; ////wis.eseoul.go.kr/images/disable/subway/4_173_M.jpg\ alt=\노원 이미지\ NAME=\stationImg\ ID=\stationImg\/>,
private String COURSE1; // 당고개,
private String COURSE2; // 오이도,
private String ELEVATER; // http; ////wis.seoul.go.kr/rest/file/thumbnail/fb1h26s5y0znrfth8e9tpq9z8c6u3hx2/1,
private String ELEVATER_TXT; // 승강기 위치는 9번 출구쪽에 있습니다\r\r\r\n\r\r\r\n승강기를 이용하여 2층 대합실로 올라가십시오.\r\r\r\n\r\r\r\n좌측 방향으로 이동하여 우측 개찰구를 통과하십시오.\r\r\r\n\r\r\r\n승강기를 이용하여 승강장으로 올라가십시오.,
private String STATION_IMAGE2; // <img src=\https; ////wis.eseoul.go.kr/images/disable/subway/20130228180252.jpg\ alt=\노원 이미지\ NAME=\stationBigImg\ ID=\stationBigImg\/>,
private String USEYN; // Y,
private String ICON_PATH; // <img src=\http; ////wis.seoul.go.kr/images/disable/subway/20081021143442.jpg\ alt=\에스켈레이터 이미지\ />,<img src=\http; ////wis.seoul.go.kr/images/disable/subway/20081021143830.jpg\ alt=\엘리베이터 이미지\ />,<img src=\http; ////wis.seoul.go.kr/images/disable/subway/20081021143901.jpg\ alt=\화장실 이미지\ />,<img src=\http; ////wis.seoul.go.kr/images/disable/subway/20081021143945.jpg\ alt=\휠체어리프트 이미지\ />,
private String EXIT_INFO; // ||1@상계6.7동 주민센터, 상계7동 치안센터, 상계중학교, 상계 119안전센터, 성민복지관||,||2@노원구청, 신상중학교, 상수초등학교, 한국성서대학교, 상계주공아파트 1-6단지, 기업은행 노원역지점, KDB산업은행, 한국전력공사북부지점, 노원 헌혈의 집||,||3@운전면허시험장,용화여고,||,||4@수협,기업은행,상계초등교,국민은행,||,||9@상계동, 창동지하철차량기지, 도봉운전면허시험장, 용화여고, 상월초등학교, 대림.현대아파트, 상계주공아파트||,||10@상계2동주민센터, 상계10동우체국, 상계초등학교, 온곡중학교, 우성아파트, 동양메이저아파트||,
private String TELNO_INFO; // 긴급전화(역무실) ; // 02-6110-4111,
private String TIME_INFO1; // 노원 ; // 06시04분,
private String TIME_INFO2; // 노원 ; // 24시59분,
private String TIME_INFO3; // 노원 ; // 05시30분,
private String TIME_INFO4; // 노원 ; // 23시12분
}
-- Run 후 목록 눌렀을때, 콘솔에 내용이 나오면 성공 --
(3) model 넣어주기
package com.green.nowon.service;
import org.springframework.ui.Model;
public interface SubwayElevatorService {
void getElevatorInfo(Model model) throws Exception;
}
package com.green.nowon.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.green.nowon.service.SubwayElevatorService;
import lombok.RequiredArgsConstructor;
//@RequiredArgsConstructor
@Controller
public class SubwayController {
private final SubwayElevatorService service; //Constructor DI
public SubwayController(SubwayElevatorService service) {
this.service = service;
}
@GetMapping("/subway")
public String subway(Model model) throws Exception {
service.getElevatorInfo(model);
return "subway/list";
}
}
- getElevatorInfo 메서드안에 model 데이터값 넣어주기
model.addAttribute("list", result.getSubwayTourInfo().getRow()); //row 의 데이터
package com.green.nowon.service.impl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.green.nowon.openapi.seoul.ResponseData;
import com.green.nowon.service.SubwayElevatorService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class SubwayElevatorServiceProcess implements SubwayElevatorService{
@Value("${seoul.key}")
private String seoulKey;
@Override
public void getElevatorInfo(Model model) throws Exception {
StringBuilder urlBuilder = new StringBuilder("http://openapi.seoul.go.kr:8088"); /*URL*/
urlBuilder.append("/" + URLEncoder.encode(seoulKey,"UTF-8") );
urlBuilder.append("/" + URLEncoder.encode("json","UTF-8") ); /*요청파일타입 (xml,xmlf,xls,json) */
urlBuilder.append("/" + URLEncoder.encode("subwayTourInfo","UTF-8")); /*서비스명 (대소문자 구분 필수입니다.)*/
urlBuilder.append("/" + URLEncoder.encode("1","UTF-8")); /*요청시작위치 (sample인증키 사용시 5이내 숫자)*/
urlBuilder.append("/" + URLEncoder.encode("30","UTF-8")); /*요청종료위치(sample인증키 사용시 5이상 숫자 선택 안 됨)*/
// 상위 5개는 필수적으로 순서바꾸지 않고 호출해야 합니다.
// 서비스별 추가 요청 인자이며 자세한 내용은 각 서비스별 '요청인자'부분에 자세히 나와 있습니다.
//urlBuilder.append("/" + URLEncoder.encode("20220301","UTF-8")); /* 서비스별 추가 요청인자들*/
String apiURL=urlBuilder.toString();
System.out.println(apiURL); // URL 정보 가지고 오기
URL url = new URL(apiURL);
//접속 확인하기
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
//conn.setRequestProperty("Content-type", "application/json"); //데이터값 변경
int responseCode = conn.getResponseCode(); /* 연결 자체에 대한 확인이 필요하므로 추가합니다.*/
String responseJSONData=null;
//apiUrl주소에 정상적으로 접속헀을때
if(responseCode == HttpURLConnection.HTTP_OK) {
responseJSONData=readBody(conn.getInputStream());
log.debug("-------> JSON-DATA READ SUCCESS!!!!");
}else { //접속 실패 시
responseJSONData=readBody(conn.getErrorStream());
log.debug("-------> JSON-DATA READ ERROR!!!!");
}
//System.out.println(responseJSONData);
conn.disconnect();
//////////////////////////
// JSONSTRING -> java Obj 맵핑
//ObjectMapper mapper=new ObjectMapper()
//대소문자 구분하지 않는 맵핑
ObjectMapper mapper = JsonMapper.builder()
.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
.build();
//responseJSONData 데이터를 최상위 데이타에 맵핑해줄게용
ResponseData result = mapper.readValue(responseJSONData, ResponseData.class);
System.out.println(result); // 결과 확인
model.addAttribute("list", result.getSubwayTourInfo().getRow()); //row 의 데이터
}
//응답데이터를 스트림을 통해서 한줄씩 읽어서 문자열로 리턴해주는 메서드
private String readBody(InputStream inputStream) throws IOException {
InputStreamReader isr=new InputStreamReader(inputStream) ;
BufferedReader lineReader = new BufferedReader(isr);
StringBuilder responseBody = new StringBuilder(); // return할 데이터를 읽어온다
String data; // return할 데이터 /* 한줄씩 읽어오고, 없을때 그만한다 */
while ( (data = lineReader.readLine()) != null) {
responseBody.append(data);
}
lineReader.close(); //예외 발생
isr.close(); //예외 발생
return responseBody.toString();
}
}
8. 데이터 뿌리기
- 테이블 생성
- thbody에 th each 연결 (원하는 태그만) item.java보고 연결하기
- 더 많은 값을 보고 싶으면 SubWayElevatorServiceProcess 의 urlBuilder.append 의 마지막 줄을 5-> 원하는 수만큼 숫자로 변경
- 정렬이 되어있지 않기에, serviceprocess에 넣었던 model 을 아래와 같이 변경
model.addAttribute("list", result.getSubwayTourInfo().getRow().stream()
.sorted(Comparator.comparing(item::getLINE_NAME))
.filter(item->item.getLINE().equals("1"))
.collect(Collectors.toList())); //row 의 데이터 //호선별로 정렬 //1호선만
<!DOCTYPE html>
<html xmlns:th="//www.thymeleaf.org"
th:replace="layout/layout1 :: layout(~{::head},~{this::main})" >
<head>
<style type="text/css">
td{width: 80px; height:28px; border-bottom: 1px solid #a9a9a9;}
td:nth-of-type(6){width: 100px;}
td:last-child{width:300px;}
</style>
</head>
<main>
<h1>메인영역</h1>
<div class="wrap view-size">
<section>
<h1>게시글내용</h1>
<div class="wrap">
<p class="tit">지하철 엘레베이터 정보</p>
<table>
<thead>
<tr>
<td>고유번호</td>
<td>노선</td>
<td>역명칭</td>
<td>운행방향1</td>
<td>운행방향2</td>
<td>편의시설</td>
<td>연락처</td>
</tr>
</thead>
<tbody>
<tr th:each="dto:${list}">
<td th:text="${dto.NO}">고유번호</td>
<td th:text="${dto.LINE_NAME}">노선</td>
<td th:text="${dto.STATION}">역명칭</td>
<td>
<div th:text="${dto.COURSE1}"> 운행방향1 </div>
</td>
<td>
<div th:text="${dto.COURSE2}"> 운행방향2 </div>
</td>
<td th:utext="${dto.ICON_PATH}">편의시설</td> <!-- 아이콘이라 u -->
<td th:text="${dto.TELNO_INFO}">연락처</td>
</tr>
</tbody>
</table>
</div>
</section>
</div>
</main>
</html>
>>>>>> 완료!!
** 다른 데이터 추가해보기!
1. 메뉴 추가 하기
<!DOCTYPE html>
<html>
<header>
<h1>헤더영역</h1>
<div class="wrap view-size">
<a href="/">HOME</a>
<a href="/board">게시글</a>
<a href="/my-board">마이게시글</a>
<a href="/subway">지하철 엘레베이터</a>
<a href="/bus">버스정류장</a>
</div>
</header>
</html>
2. 컨트롤러 위에 이미 만든 것 아래에 추가하기
package com.green.nowon.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.green.nowon.service.SeoulAPIService;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Controller
public class SeoulAPIController {
private final SeoulAPIService service; //Constructor DI
@GetMapping("/subway")
public String subway(Model model) throws Exception {
service.getElevatorInfo(model);
return "seoulapi/subway-list";
}
@GetMapping("/bus")
public String bus(Model model) throws Exception {
service.getbusStopLocationXyInfo(model);
return "seoulapi/bus-list";
}
}
3. 이미 만들었던 인터페이스 안에 메서드 추가하기
package com.green.nowon.service;
import org.springframework.ui.Model;
public interface SeoulAPIService {
void getElevatorInfo(Model model) throws Exception;
void getbusStopLocationXyInfo(Model model)throws Exception;
}
4. 이미 만들었던 서비스 process 안에 메서드 추가하기 (오버라이드)
- 똑같은 샘플 코드 넣어주고 맞게 수정하기
- 접속 확인 코드 넣기
- 맵핑코드 넣어주기
- 뿌리는 태그 넣기
@Override
public void getbusStopLocationXyInfo(Model model) throws Exception {
StringBuilder urlBuilder = new StringBuilder("http://openapi.seoul.go.kr:8088"); /*URL*/
urlBuilder.append("/" + URLEncoder.encode(seoulKey,"UTF-8") ); /*인증키 (sample사용시에는 호출시 제한됩니다.)*/
urlBuilder.append("/" + URLEncoder.encode("json","UTF-8") ); /*요청파일타입 (xml,xmlf,xls,json) */
urlBuilder.append("/" + URLEncoder.encode("busStopLocationXyInfo","UTF-8")); /*서비스명 (대소문자 구분 필수입니다.)*/
urlBuilder.append("/" + URLEncoder.encode("1","UTF-8")); /*요청시작위치 (sample인증키 사용시 5이내 숫자)*/
urlBuilder.append("/" + URLEncoder.encode("5","UTF-8")); /*요청종료위치(sample인증키 사용시 5이상 숫자 선택 안 됨)*/
String apiURL=urlBuilder.toString();
System.out.println(apiURL); // URL 정보 가지고 오기
URL url = new URL(apiURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.disconnect();
int responseCode = conn.getResponseCode(); /* 연결 자체에 대한 확인이 필요하므로 추가합니다.*/
String responseJSONData=null;
//apiUrl주소에 정상적으로 접속헀을때
if(responseCode == HttpURLConnection.HTTP_OK) {
responseJSONData=readBody(conn.getInputStream());
log.debug("-------> JSON-DATA READ SUCCESS!!!!");
}else { //접속 실패 시
responseJSONData=readBody(conn.getErrorStream());
log.debug("-------> JSON-DATA READ ERROR!!!!");
}
System.out.println(responseJSONData);
ObjectMapper mapper = new ObjectMapper();
ResponseBusData result= mapper.readValue(responseJSONData, ResponseBusData.class);
System.out.println(result);
// 뿌리는 태그
model.addAttribute("list",result.getBusStopLocationXyInfo().getRow()); //row 의 데이터 //호선별로 정렬 //1호선만
}
>> 완성
package com.green.nowon.service.impl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Comparator;
import java.util.stream.Collectors;
import org.hibernate.cache.spi.support.AbstractReadWriteAccess.Item;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.green.nowon.openapi.bus.ResponseBusData;
import com.green.nowon.openapi.seoul.ResponseData;
import com.green.nowon.openapi.seoul.item;
import com.green.nowon.service.SeoulAPIService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class SeoulAPIServiceProcess implements SeoulAPIService{
@Value("${seoul.key}")
private String seoulKey;
@Override
public void getbusStopLocationXyInfo(Model model) throws Exception {
StringBuilder urlBuilder = new StringBuilder("http://openapi.seoul.go.kr:8088"); /*URL*/
urlBuilder.append("/" + URLEncoder.encode(seoulKey,"UTF-8") ); /*인증키 (sample사용시에는 호출시 제한됩니다.)*/
urlBuilder.append("/" + URLEncoder.encode("json","UTF-8") ); /*요청파일타입 (xml,xmlf,xls,json) */
urlBuilder.append("/" + URLEncoder.encode("busStopLocationXyInfo","UTF-8")); /*서비스명 (대소문자 구분 필수입니다.)*/
urlBuilder.append("/" + URLEncoder.encode("1","UTF-8")); /*요청시작위치 (sample인증키 사용시 5이내 숫자)*/
urlBuilder.append("/" + URLEncoder.encode("5","UTF-8")); /*요청종료위치(sample인증키 사용시 5이상 숫자 선택 안 됨)*/
String apiURL=urlBuilder.toString();
System.out.println(apiURL); // URL 정보 가지고 오기
URL url = new URL(apiURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.disconnect();
int responseCode = conn.getResponseCode(); /* 연결 자체에 대한 확인이 필요하므로 추가합니다.*/
String responseJSONData=null;
//apiUrl주소에 정상적으로 접속헀을때
if(responseCode == HttpURLConnection.HTTP_OK) {
responseJSONData=readBody(conn.getInputStream());
log.debug("-------> JSON-DATA READ SUCCESS!!!!");
}else { //접속 실패 시
responseJSONData=readBody(conn.getErrorStream());
log.debug("-------> JSON-DATA READ ERROR!!!!");
}
System.out.println(responseJSONData);
ObjectMapper mapper = new ObjectMapper();
ResponseBusData result= mapper.readValue(responseJSONData, ResponseBusData.class);
System.out.println(result);
// 뿌리는 태그
model.addAttribute("list",result.getBusStopLocationXyInfo().getRow()); //row 의 데이터 //호선별로 정렬 //1호선만
}
@Override
public void getElevatorInfo(Model model) throws Exception {
StringBuilder urlBuilder = new StringBuilder("http://openapi.seoul.go.kr:8088"); /*URL*/
urlBuilder.append("/" + URLEncoder.encode(seoulKey,"UTF-8") );
urlBuilder.append("/" + URLEncoder.encode("json","UTF-8") ); /*요청파일타입 (xml,xmlf,xls,json) */
urlBuilder.append("/" + URLEncoder.encode("subwayTourInfo","UTF-8")); /*서비스명 (대소문자 구분 필수입니다.)*/
urlBuilder.append("/" + URLEncoder.encode("1","UTF-8")); /*요청시작위치 (sample인증키 사용시 5이내 숫자)*/
urlBuilder.append("/" + URLEncoder.encode("100","UTF-8")); /*요청종료위치(sample인증키 사용시 5이상 숫자 선택 안 됨)*/
// 상위 5개는 필수적으로 순서바꾸지 않고 호출해야 합니다.
// 서비스별 추가 요청 인자이며 자세한 내용은 각 서비스별 '요청인자'부분에 자세히 나와 있습니다.
//urlBuilder.append("/" + URLEncoder.encode("20220301","UTF-8")); /* 서비스별 추가 요청인자들*/
String apiURL=urlBuilder.toString();
System.out.println(apiURL); // URL 정보 가지고 오기
URL url = new URL(apiURL);
//접속 확인하기
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
//conn.setRequestProperty("Content-type", "application/json"); //데이터값 변경
int responseCode = conn.getResponseCode(); /* 연결 자체에 대한 확인이 필요하므로 추가합니다.*/
String responseJSONData=null;
//apiUrl주소에 정상적으로 접속헀을때
if(responseCode == HttpURLConnection.HTTP_OK) {
responseJSONData=readBody(conn.getInputStream());
log.debug("-------> JSON-DATA READ SUCCESS!!!!");
}else { //접속 실패 시
responseJSONData=readBody(conn.getErrorStream());
log.debug("-------> JSON-DATA READ ERROR!!!!");
}
//System.out.println(responseJSONData);
conn.disconnect();
//////////////////////////
// JSONSTRING -> java Obj 맵핑
//ObjectMapper mapper=new ObjectMapper()
//대소문자 구분하지 않는 맵핑
ObjectMapper mapper = JsonMapper.builder()
.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
.build();
//responseJSONData 데이터를 최상위 데이타에 맵핑해줄게용
ResponseData result = mapper.readValue(responseJSONData, ResponseData.class);
System.out.println(result); // 결과 확인
model.addAttribute("list", result.getSubwayTourInfo().getRow().stream()
.sorted(Comparator.comparing(item::getLINE_NAME))
.filter(item->item.getLINE().equals("1"))
.collect(Collectors.toList())); //row 의 데이터 //호선별로 정렬 //1호선만
}
//응답데이터를 스트림을 통해서 한줄씩 읽어서 문자열로 리턴해주는 메서드
private String readBody(InputStream inputStream) throws IOException {
InputStreamReader isr=new InputStreamReader(inputStream) ;
BufferedReader lineReader = new BufferedReader(isr);
StringBuilder responseBody = new StringBuilder(); // return할 데이터를 읽어온다
String data; // return할 데이터 /* 한줄씩 읽어오고, 없을때 그만한다 */
while ( (data = lineReader.readLine()) != null) {
responseBody.append(data);
}
lineReader.close(); //예외 발생
isr.close(); //예외 발생
return responseBody.toString();
}
}
5. 데이터 태그 맵핑하기 api 코드와 동일하게
-@JsonProperty 는 대소문자 구분때문에...
package com.green.nowon.openapi.bus;
import lombok.Data;
@Data
public class ResponseBusData {
private BusStopLocationXyInfo busStopLocationXyInfo;
}
package com.green.nowon.openapi.bus;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class BusStopLocationXyInfo {
@JsonProperty("list_total_count")
private int listTotalCount;
@JsonProperty("RESULT")
private Result result;
private List<busitem> row;
}
package com.green.nowon.openapi.bus;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class Result {
@JsonProperty("CODE")
private String code;
@JsonProperty("MESSAGE")
private String message;
}
package com.green.nowon.openapi.bus;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class busitem {
@JsonProperty("STOP_NO")
private String STOP_NO;// 01001,
@JsonProperty("STOP_NM")
private String STOP_NM;// 종로2가사거리,
@JsonProperty("XCODE")
private String XCODE;// 126.9877498816,
@JsonProperty("YCODE")
private String YCODE;// 37.5697651251
}
5. bus Html 수정하기
<!DOCTYPE html>
<html xmlns:th="//www.thymeleaf.org"
th:replace="layout/layout1 :: layout(~{::head},~{this::main})" >
<head>
<style type="text/css">
td{width: 200px; height:28px; border-bottom: 1px solid #a9a9a9; text-align: center;}
td:nth-of-type(2){width: 300px;}
</style>
</head>
<main>
<h1>메인영역</h1>
<div class="wrap view-size">
<section>
<h1>게시글내용</h1>
<div class="wrap">
<p class="tit">버스 정류장 정보</p>
<table>
<thead>
<tr>
<td>고유번호</td>
<td>정류장이름</td>
<td>X좌표</td>
<td>Y좌표</td>
</tr>
</thead>
<tbody>
<tr th:each="dto:${list}">
<td th:text="${dto.STOP_NO}">고유번호</td>
<td th:text="${dto.STOP_NM}">정류장이름</td>
<td th:text="${dto.XCODE}">X좌표</td>
<td th:text="${dto.YCODE}">Y좌표</td>
</tr>
</tbody>
</table>
</div>
</section>
</div>
</main>
</html>
'Spring' 카테고리의 다른 글
[SpringBoot] JSP 구조(기초 구조 생성하기) (0) | 2023.05.16 |
---|---|
[Spring] 웹페이지에 파일 업로드하도록 개발하기(CRUD) - 1편 (0) | 2023.05.08 |
[Spring] MyBatis Query 연동, 구축, 맵핑, 쿼리날리기 (0) | 2023.04.25 |
[Spring] DB -스프링 웹 MVC 개념 (0) | 2023.04.24 |
[Spring] DB 연결 하기 (2) AWS -EC2 : 배포방법 (0) | 2023.04.18 |