스프링 프로젝트 여행 웹사이트 만들기(1)

노건우·2023년 11월 2일
0

스프링 프로젝트

목록 보기
1/6

🖊️여행 웹사이트이기에 api를 가져온다.

관광지 게시판 목록 페이지

📜TouristController.java

@Controller
@RequestMapping("/tourist")
@RequiredArgsConstructor
public class TouristController {

   // Integer area : 지역 코드
   // Integer contentTypeId : 관광지 타입
   // String keyword : 검색어
   // Integer pageNo : 요청한 페이지 번호
   @GetMapping("/list/{pageNo}")
   public String touristList(
         @RequestParam(required = false) Integer area,
         @RequestParam(required = false) Integer contentTypeId ,
         @RequestParam(required = false) String keyword,
         @PathVariable(required = false) Integer pageNo,
         Model model) throws IOException {
      
      TouristListDTO board = dataPortalService.findAll(area, contentTypeId, keyword, pageNo);

      List<TouristItemDTO> items = board.getList();

      //.. 페이징 처리를 위한 과정 - 코드 생략

      model.addAttribute("items", items);
      return "tourist/touristList";
   }
}

📜DataPortalService.java

@Service
@RequiredArgsConstructor
public class DataPortalService {
   public TouristListDTO findAll(Integer area, Integer contentTypeId , String keyword, Integer pageNo) throws IOException{
      return dataPortalRequest.searchKeyword(area, contentTypeId ,keyword, pageNo);
   }
}

공공데이터 포털 요청하기

📜application.properties

공공데이터 포털의 URL 주소와 인증 키를 설정 파일에 저장한다.

public-data.korservice.key.encoding=ke9Ra%...
public-data.korservice.url.keyword=https://apis.data.go.kr/B551011/KorService1/searchKeyword1

📜DataPortalRequest.java

// `@Value`은 `String` 멤버 변수 위에 선언하여 설정 파일에 저장된 값을 멤버 변수에 할당시킨다.
@Value("${public-data.korservice.key.encoding}")
private String serviceKey;

@Value("${public-data.korservice.url.keyword}")
private String searchKeywordURL;

@Component
public class DataPortalRequest {
   public TouristListDTO searchKeyword(Integer area, Integer contentTypeId ,String keyword, int pageNo) throws IOException{
      // UriComponentsBuilder URI의 쿼리 스트링을 구성해주는 객체이다.
      UriComponentsBuilder uriBuilder = UriComponentsBuilder
         .fromUriString(searchKeywordURL)
            .queryParam("serviceKey", serviceKey)
            .queryParam("keyword", keyword)
            .queryParam("MobileOS", "ETC")
            .queryParam("MobileApp", "AppTest")
            .queryParam("_type", "json")
            .queryParam("numOfRows", numOfRows)
            .queryParam("pageNo", pageNo)
      ;

      if(area != null) uriBuilder.queryParam("areaCode", area); // 지역 코드
      if(contentTypeId != null) uriBuilder.queryParam("contentTypeId", contentTypeId); // 관광 코드

      /* HttpURLConnection 공공데이터 포털에 요청(Request)할 수 있는 객체.
       * openConnection() 메서드로 공공 데이터에 요청을 보낸다.
       */
      URL url = new URL(uriBuilder.build().toUriString())
      HttpURLConnection conn = (HttpURLConnection) url.openConnection();

      // conn.getInputStream() 메서드를 호출하고 Response 결과 값을 스트림으로 읽어내고 스프링 빌더로 문자열로 담아내는 과정이 필요. - 코드는 생략됨.
      String responseBody = stringBuilder.toString();

      // ObjectMapper 객체를 Json 형식으로 또는 Json을 객체로 변환해주는 객체.
      ObjectMapper mapper = new ObjectMapper();
      String findInfo = mapper.readTree(responseBody).findPath("body").toString();

      // Json 형식으로 된 문자열을 객체로 변환해주는 메소드
      return mapper.readValue(findInfo, TouristListDTO.class); // 변환된 객체의 타입 TouristListDTO
   }
}

## 📜`TouristListDTO.java`
```java
// DataPortalRequest.java에서 Json에서 자바 객체로 변환된 객체.
@JsonIgnoreProperties(ignoreUnknown = true)
@Getter @ToString @NoArgsConstructor
public class TouristListDTO {
   // 페이징 처리 시 필요한 멤버 변수
   private int numOfRows;
   private int pageNo;
   private int totalCount;

   /* 관광지 게시판 목록
    파싱하기 위해 내부 클래스를 선언함.
   */
   @JsonProperty(value = "items")
   @Getter(lombok.AccessLevel.NONE)
   private TouristItems items;

   @JsonIgnoreProperties(ignoreUnknown = true)
   @Getter @ToString @NoArgsConstructor
   class TouristItems{
      @JsonProperty(value = "item")
      private List<TouristItemDTO> list;
   }

   public List<TouristItemDTO> getList(){
      return items.getList();
   }
}

관광지 상세 게시판 페이지

📜TouristController.java

public class TouristController {
   @GetMapping("/detail/{contentId}")
   public String touristDetail(@PathVariable("contentId") Long contentId, Model model,
         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : #this") MemberDetails memberDetails)
         throws IOException {
      // contentId : 공공 데이터 관광지의 고유 번호(ID)
      // 공공데이터 포털에서 상세 내용 요청 
      TouristDTO touristDTO = dataPortalService.findOne(contentId);
      // DB 처리 - 저장또는 조회
      // 공공데이터의 모든 데이터를 전부 db에 넣을 수 없기 때문에, 얼마나 있는 지 모르고 너무 많기 때문..
      Board board = boardService.findOne(contentId, touristDTO);
      
      // 좋아요 처리
      // 북마크 처리
      // 댓글

      model.addAttribute("item", touristDTO);
      return "tourist/touristDetail";
   }
}

📜BoardService.java

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class BoardService {
   @Transactional
	public Board findOne(Long contentId, TouristDTO touristDTO) {
		Board board = findOne(contentId);
      // 조회가 되면 그대로 쓰고, 조회가 안되면 새로 만든다.
      // 댓글과 좋아요, 북마크와 연관 짓기 위해서..
		if(board == null){
         board = new Board();
         Tourist tourist = Tourist.builder()
            .contentId(contentId)
            .title(touristDTO.getTitle())
            .address(touristDTO.getAddress1())
            .image(touristDTO.getImage1())
            .build();
         board.setTourist(tourist);
         boarderRepository.save(board);
      }
		return boarderRepository.findByContentId(contentId);
	}
}

📜BoarderRepository.java

public interface BoarderRepository extends JpaRepository<Board, Long> {

	@Query("SELECT b FROM Board b WHERE b.tourist.contentId = :contentId")
	public Board findByContentId(@Param("contentId") Long contentId);
	public Board findBoardById(Long contentId);
}


이런 형태로 가져와봤다.

profile
초보 개발자 이야기

0개의 댓글