본문 바로가기

Spring

240312 스프링 부트

API 받기

https://www.data.go.kr

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr

 

로그인 > 원하는 API 사용 신청 > 바로 승인됨

 

한번 진행해보기

@Controller
public class APIController {

  @GetMapping("/airKorea")
  public String airKorea(Model model) throws Exception {
    // URL 주소
    StringBuilder urlBuilder = new StringBuilder("[요청주소]");
    // 서비스 키 주소
    urlBuilder.append("?serviceKey=[서비스 키]");
    // 반환 타입, xml or json
    urlBuilder.append("&returnType=xml");
    // 한 페이지 결과 수 (조회 날짜로 검색 시 사용 안함)
    urlBuilder.append("&numOfRows=100");
    // 페이지 번호 (조회 날짜로 검색 시 사용 안함)
    urlBuilder.append("&pageNo=1");
    // 날짜 검색
    urlBuilder.append("&searchDate=2024-03-10");
    // 원하는 곳 코드 검색
    urlBuilder.append("&InformCode=PM10");

    URL url = new URL(urlBuilder.toString());
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setRequestProperty("Content-type", "application/json");
    // 응답 결과가 200 번 대 숫자여야 정상 응답
    System.out.println("Response code: " + conn.getResponseCode());

    BufferedReader rd;
    if (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
      rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    } else {
      rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
    }
    StringBuilder sb = new StringBuilder();
    String line;
    while ((line = rd.readLine()) != null) {
      sb.append(line);
    }
    rd.close();
    conn.disconnect();
    System.out.println(sb.toString());

    return "airKorea";
  }
}

 

https://www.whatap.io/ko/blog/40/

 

HTTP 상태 코드 정리 | 와탭 블로그

HTTP 상태(응답) 코드 정리하기

www.whatap.io

 

240313 이어서 진행

문자열을 반환하면 볼 순 있지만, 사용할 수는 없어 JSON 형태로 반환해보기

// json -> 자바 형태로 코드 변경하여 출력하기
JSONParser parser = new JSONParser();
JSONObject jsonObj = (JSONObject) parser.parse(new InputStreamReader(url.openStream()));
System.out.println("toJSONString()");
System.out.println(jsonObj.toJSONString());
System.out.println("toString()");
System.out.println(jsonObj.toString());

// response 안의 모든 값들이 들어감
Map<String, Object> map = (Map<String, Object>) jsonObj.get("response");
System.out.println(map);
Map<String, Object> body = (Map<String, Object>) map.get("body");
// response > body 안의 모든 값이 들어감
System.out.println(body);
// response > body > items 값들이 들어감, 값이 여러개라 배열 형태로 저장
// List<Map<String, Object>> items = (List<Map<String, Object>>) body.get("items");
JSONArray items = (JSONArray) body.get("items");
System.out.println(items);

 

jsonObj.get("response"); 와 다른 줄에도 밑줄이 생기는데 SuppressWarnings 을 넣으라고 한다

https://www.ibm.com/docs/ko/radfws/9.6.1?topic=code-excluding-warnings

 

@SuppressWarnings를 사용하여 경고 제외

Java 5.0부터 java.lang.SuppressWarning 어노테이션을 사용하여 컴파일 단위의 서브세트와 관련된 컴파일 경고를 사용하지 않도록 설정할 수 있습니다. 어노테이션이 없으면 컴파일러에서 로컬 변수 s를

www.ibm.com

https://haranglog.tistory.com/3 

 

JAVA Spring의 @SuppressWarnings 어노테이션

✔ @SuppressWarnings 이란? @SuppressWarnings 어노테이션은 컴파일 경고를 사용하지 않도록 설정해주는 것으로 한마디로 이클립스에서 노란색 표시줄이 나타내는 것 즉, 경고를 제외시킬 때 사용한다.

haranglog.tistory.com

 

SuppressWarnings 는 오류를 지워주는 어노테이션인데 해당 line 혹은 메소드 전체에 추가할 수 있음

 

파싱한 json 데이터 추가해보기

<table>
  <thead>
    <tr>
      <th>informCause</th>
      <th>imageUrl4</th>
      <th>informData</th>
      <th>imageUrl5</th>
      <th>informGrade</th>
      <th>imageUrl6</th>
      <th>informCode</th>
      <th>informOverall</th>
      <th>dataTime</th>
      <th>imageUrl1</th>
      <th>imageUrl2</th>
      <th>imageUrl3</th>
      <th>actionKnack</th>
    </tr>
  </thead>
  <tbody>
    <tr th:each="air : ${air}">
      <td th:text="${air.informCause}">informCause</td>
      <td><img th:src="${air.imageUrl4}"></td>
      <td th:text="${air.informData}">informData</td>
      <td><img th:src="${air.imageUrl5}"></td>
      <td th:text="${air.informGrade}">informGrade</td>
      <td><img th:src="${air.imageUrl6}"></td>
      <td th:text="${air.informCode}">informCode</td>
      <td th:text="${air.informOverall}">informOverall</td>
      <td th:text="${air.dataTime}">dataTime</td>
      <td><img th:src="${air.imageUrl1}"></td>
      <td><img th:src="${air.imageUrl2}"></td>
      <td><img th:src="${air.imageUrl3}"></td>
      <td th:text="${air.actionKnack}">actionKnack</td>
    </tr>
  </tbody>
</table>

 

XML 으로도 진행해보기

// 기존에 있던 아래 명령어 이후로 진행
System.out.println("Response code: " + conn.getResponseCode());

// 파싱할 수 있는 공장 생성
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 공장에서 빌더 생성
DocumentBuilder docBuilder = factory.newDocumentBuilder();
// 생성된 빌더에서 파싱하기
Document doc = docBuilder.parse(conn.getInputStream());
doc.getDocumentElement().normalize();

// 첫 태그의 이름 출력
System.out.println(doc.getDocumentElement().getNodeName());
// 다음 태그 찾기
Document nodeList = (Document) doc.getChildNodes();
System.out.println(nodeList.getDocumentElement().getNodeName());

// body
NodeList list = (NodeList) doc.getDocumentElement().getChildNodes().item(3);
System.out.println(list.getLength());

// items 출력
System.out.println(list.item(1).getNodeName());
// items List 로 받기
NodeList list2 = list.item(1).getChildNodes();
// System.out.println("items :: " + list2.getLength());
// System.out.println("items :: " + list2.item(0).getNodeName());

for (int i = 0; i < list2.getLength(); i++) {
  // item == 13개
  NodeList list3 = list2.item(i).getChildNodes();

  for (int j = 1; j < list3.getLength(); j++) {
    Node node = list3.item(j);
    if (node.getNodeType() == Node.ELEMENT_NODE) {
      System.out.println(j + " : " + list3.item(j).getNodeName());
      System.out.println(j + " : " + list3.item(j).getTextContent());
    }
  }
}

Index 번호와 해당하는 Key, Value 값들이 나옴


파일 업로드 해보기

Controller 에 fileUp 이라는 메소드 생성

@GetMapping("/fileUp")
public String fileUp(Model model) {
  model.addAttribute("catename", "UPLOAD");
  return "fileUp";
}

 

fileUp.html 생성 > 기존 login 복사해서 만들기

<form action="/fileUp" method="post" enctype="multipart/form-data">
  <input type="file" name="fileUp"/>
  <button class="btn btn-dark" type="submit">업로드</button>
</form>

 

post 로 파일 받기

@PostMapping("fileUp")
public String fileUp(@RequestParam("fileUp") MultipartFile file) {
  System.out.println("name : " + file.getName()); // input name
  System.out.println("size : " + file.getSize()); // 파일 사이즈
  System.out.println("originalFileName : " + file.getOriginalFilename()); // 파일 이름
  return "redirect:/fileUp";
}

 

다운로드.jpg 라는 파일을 전송 시 뜨는 내용

다운로드.jpg 를 올려보자

 

input 의 name, 파일의 byte 기준 사이즈, 파일의 원래 이름이 나오는 모습

 

파일의 속성으로 본 원래 크기

 

여기를 참고해보자

https://spring.io/guides/gs/uploading-files

 

Getting Started | Uploading Files

To start a Spring Boot MVC application, you first need a starter. In this sample, spring-boot-starter-thymeleaf and spring-boot-starter-web are already added as dependencies. To upload files with Servlet containers, you need to register a MultipartConfigEl

spring.io

 

파일 저장하기

// public HttpServletRequest req() {
//   ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
//   HttpServletRequest request = sra.getRequest(); 
//   return request;
// }

String url = util.req().getServletContext().getRealPath("/upload");
System.out.println(url);
// C:\Users\ppj21\AppData\Local\Temp\tomcat-docbase.80.11809951382106430929\upload
File upFileName = new File(new File(url), file.getOriginalFilename());
		
try {
  file.transferTo(upFileName);
} catch (IllegalStateException | IOException e) {
  e.printStackTrace();
}

 

현재는 해당 경로의 디렉토리가 없어서 디렉토리 만들기

// String url = util.req().getServletContext().getRealPath("/upload");
File url = new File(util.req().getServletContext().getRealPath("/upload"));
url.mkdirs(); // 해당 url 의 위치까지 dir 만들기
File upFileName = new File(url, file.getOriginalFilename());

 

중복 방지를 위해 랜덤 코드들을 만들어보기 (UUID 와 시간)

// UUID 만들어보기
  public void makeUUID() {
  UUID uuid = UUID.randomUUID();
}
  
// 날짜를 뽑아보기
public String makeDateID() {
  LocalDateTime ldt = LocalDateTime.now();
  String ldtFormat = ldt.format(DateTimeFormatter.ofPattern("YYYYMMddHHmmSS"));
  return ldtFormat;
}

 

시간 + OriginalFileName 을 합쳐서 저장해보기

시간으로는 이름이 겹칠 수도 있어보여서 추가적인 방법이 필요할 듯 함, UUID 가 더 좋을듯

File upFileName = new File(url, util.makeDateID() + file.getOriginalFilename());

 

제대로 저장되는 모습

 

파일 저장해보기 (다운 받기)

파일을 받을 수 있게 html 에 태그 추가

<button onclick="location.href='/downFile@다운로드.jpg'">다운로드</button>
<img alt=".." src="img/다운로드.jpg" />

 

Controller 에서 파일 다운로드 받아보기

@ResponseBody
@GetMapping("/downFile@{file}")
public void downFile(@PathVariable("file") String file, 
                    HttpServletRequest request,
                    HttpServletResponse response) {
  System.out.println("파일 명 : " + file);
  // String url = "C:/eGovFrameDev-4.1.0-64bit/workspace/web/src/main/resources/static/img/" + file;
  // File serverFile = new File(url);
  File url = new File(util.req().getServletContext().getRealPath("/upload"));
  File serverFile = new File(url, file);

  try {
    byte[] fileArr = FileCopyUtils.copyToByteArray(serverFile);
    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition", "attachment; fileName=\"" + URLEncoder.encode(url+file, "UTF-8") + "\";" );
    response.setHeader("Content-Transfer-Encoding", "binary");
    response.getOutputStream().write(fileArr);
    response.getOutputStream().flush();
    response.getOutputStream().close();
  } catch (IOException e) {
    e.printStackTrace();
  }
}

 

jar 파일로 만들어서 직접 실행해보기

Gradle Tasks > build > bootjar 우클릭 Run

Run 하면 실행 가능한 .jar 파일이 생성

 

이클립스 workspace > 프로젝트명 > build > libs 에 생성된 .jar 파일 확인

 

CMD 로 해당 위치로 이동해 아래 명령 입력하기

java -jar [파일명]

 

기존 이클립스에서 실행된 것과 동일하게 프로그램을 실행할 수 있음

 

리눅스 서버에 jar 파일 넣어보기

먼저 리눅스 깔기, 컴퓨터를 노트북으로 바꿔서 새로 설치했음

https://han-s-coding.tistory.com/72

 

240201 HTML 홈페이지 만들기

오늘은 미디어쿼리 해보기 미디어쿼리는 화면 해상도에 따라 반응형 웹을 만드는 것 잘 설명되어 있는 블로그 [CSS3강좌] 35강 반응형웹을 위한 미디어쿼리(@media screen{ }) ** 동영상으로 배우고 싶

han-s-coding.tistory.com

 

Java 설치하기

headless 는 GUI 환경이 제거된 환경

sudo apt install openjdk-17-jre-headless

 

아까 만든 .jar 파일 집어넣기

아래 명령어를 입력하여 나오는 폴더에 .jar 파일 넣기

explorer.exe .

 

아래 명령어로 .jar 파일 실행해보기

sudo java -jar web-0.0.1-SNAPSHOT.jar

실행되는 모습, Ctrl + Z 키를 눌러 취소할 수 있음

 

Swagger

스웨거가 무엇인지 알아보자

... 하다가 부트 버전과 안맞아서 오류 발생.. 다음에..

public class SwaggerConfig {
  private static final String API_NAME = "Spring boot API";
  private static final String API_VERSION = "1.0";
  private static final String API_DESCRIPTION = "스프링 부트 API 명세서";
	
  @Bean
  public Docket api() {
    Parameter parameter = new ParameterBuilder() // API 에 전역 파라미터를 설정
			      .name(HttpHeaders.AUTHORIZATION)
			      .description("token")
			      .modelRef(new ModelRef("model"))
			      .parameterType("")
			      .required(false)
			      .build();
		
    List<Parameter> paramList = new ArrayList<>();
    paramList.add(parameter);
		
    return new Docket(DocumentationType.SWAGGER_2)
		.globalOperationParameters(paramList)
		.apiInfo(apiInfo()) // API 이름을 아래 메소드에서 설정 = 정보
		.select()
		.apis(RequestHandlerSelectors.basePackage("com.solbum.web")) // 스웨거를 적용할 클래스 패키지
		.paths(PathSelectors.any()) // 위 패키지 하위에 모든 패키지를 적용
		.build();
  } // end api()
	
  public ApiInfo apiInfo() {
    return new ApiInfoBuilder()
              .title(API_NAME)
              .version(API_VERSION)
              .description(API_DESCRIPTION).build();
  }
}

 

'Spring' 카테고리의 다른 글

240314 스프링 부트  (2) 2024.03.14
240313 스프링 부트  (1) 2024.03.13
240311 스프링 부트  (0) 2024.03.11
240308 스프링 부트  (1) 2024.03.08
240307 스프링 부트  (0) 2024.03.07