반응형
NAVER API 연동하기
NAVER API를 사용하기 위해서는 이용 신청을 해야함
네이버 지역 서비스에 등록된 각 지역별 업체 및 상호 검색 결과를 출력해주는 REST API
GET으로 호출할 때 HTTP Header에 애플리케이션 등록 시 발급받은 Client ID와 Client Secret값을 전송
<예시>
curl "https://openapi.naver.com/v1/search/local.xml?query=%EC%A3%BC%EC%8B%9D&display=10&start=1&sort=random" \
-H "X-Naver-Client-Id: {애플리케이션 등록 시 발급받은 client id 값}" \
-H "X-Naver-Client-Secret: {애플리케이션 등록 시 발급받은 client secret 값}" -v
연동 후 Talend API 실행 화면
<네이버 지역검색 API를 활용한 맛집 List 만들기>
- NaverClient 클래스
package com.example.restaurant.naver;
import com.example.restaurant.naver.dto.SearchImageReq;
import com.example.restaurant.naver.dto.SearchImageRes;
import com.example.restaurant.naver.dto.SearchLocalReq;
import com.example.restaurant.naver.dto.SearchLocalRes;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
@Component
public class NaverClient {
@Value("${naver.client.id}")
private String naverClientId;
@Value("${naver.client.secret}")
private String naverClientSecret;
@Value("${naver.url.search.local}")
private String naverLocalSearchUrl;
@Value("${naver.url.search.image}")
private String naverImageSearchUrl;
public SearchLocalRes searchLocal(SearchLocalReq searchLocalReq){
var uri = UriComponentsBuilder.fromUriString(naverLocalSearchUrl)
.queryParams(searchLocalReq.toMultiValueMap())
.build()
.encode()
.toUri();
var headers = new HttpHeaders();
headers.set("X-Naver-Client-Id", naverClientId);
headers.set("X-Naver-Client-Secret", naverClientSecret);
headers.setContentType(MediaType.APPLICATION_JSON);
var httpEntity = new HttpEntity<>(headers);
var responseType = new ParameterizedTypeReference<SearchLocalRes>(){};
var responseEntity = new RestTemplate().exchange(
uri,
HttpMethod.GET,
httpEntity,
responseType
);
return responseEntity.getBody();
}
public SearchImageRes searchImage(SearchImageReq searchImageReq){
var uri = UriComponentsBuilder.fromUriString(naverImageSearchUrl)
.queryParams(searchImageReq.toMultiValueMap())
.build()
.encode()
.toUri();
var headers = new HttpHeaders();
headers.set("X-Naver-Client-Id", naverClientId);
headers.set("X-Naver-Client-Secret", naverClientSecret);
headers.setContentType(MediaType.APPLICATION_JSON);
var httpEntity = new HttpEntity<>(headers);
var responseType = new ParameterizedTypeReference<SearchImageRes>(){};
var responseEntity = new RestTemplate().exchange(
uri,
HttpMethod.GET,
httpEntity,
responseType
);
return responseEntity.getBody();
}
}
- WishListDto 클래스
package com.example.restaurant.wishlist.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class WishListDto {
private Integer index;
private String title; // 음식명, 장소명
private String category; // 카테고리
private String address; // 주소
private String roadAddress; // 도로명
private String homePageLink; // 홈페이지 주소
private String imageLink; // 음식, 가게 이미지 주소
private boolean isVisit; // 방문여부
private int visitCount; // 방문 카운트
private LocalDateTime lastVisitDate; // 마지막 방문일자
}
- WishListEntity 클래스
package com.example.restaurant.wishlist.entity;
import com.example.restaurant.db.MemoryDbEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class WishListEntity extends MemoryDbEntity {
private String title; // 음식명, 장소명
private String category; // 카테고리
private String address; // 주소
private String roadAddress; // 도로명
private String homePageLink; // 홈페이지 주소
private String imageLink; // 음식, 가게 이미지 주소
private boolean isVisit; // 방문여부
private int visitCount; // 방문 카운트
private LocalDateTime lastVisitDate; // 마지막 방문일자
}
- WishListRepository 클래스
package com.example.restaurant.wishlist.repository;
import com.example.restaurant.db.MemoryDbRepositoryAbstract;
import com.example.restaurant.wishlist.entity.WishListEntity;
import org.springframework.stereotype.Repository;
@Repository
public class WishListRepository extends MemoryDbRepositoryAbstract<WishListEntity> {
}
- WishListService 클래스
package com.example.restaurant.wishlist.service;
import com.example.restaurant.naver.NaverClient;
import com.example.restaurant.naver.dto.SearchImageReq;
import com.example.restaurant.naver.dto.SearchLocalReq;
import com.example.restaurant.wishlist.dto.WishListDto;
import com.example.restaurant.wishlist.entity.WishListEntity;
import com.example.restaurant.wishlist.repository.WishListRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class WishListService {
private final NaverClient naverClient;
private final WishListRepository wishListRepository;
public WishListDto search(String query){
// 지역검색
var searchLocalReq = new SearchLocalReq();
searchLocalReq.setQuery(query);
var searchLocalRes = naverClient.searchLocal(searchLocalReq);
if(searchLocalRes.getTotal() > 0){
var localItem = searchLocalRes.getItems().stream().findFirst().get();
var imageQuery = localItem.getTitle().replaceAll("<[^>]*>","");
var searchImageReq = new SearchImageReq();
searchImageReq.setQuery(imageQuery);
// 이미지 검색
var searchImageRes = naverClient.searchImage(searchImageReq);
if(searchImageRes.getTotal() > 0){
var imageItem = searchImageRes.getItems().stream().findFirst().get();
// 결과를 리턴
var result = new WishListDto();
result.setTitle(localItem.getTitle());
result.setCategory(localItem.getCategory());
result.setAddress(localItem.getAddress());
result.setRoadAddress(localItem.getRoadAddress());
result.setHomePageLink(localItem.getLink());
result.setImageLink(imageItem.getLink());
return result;
}
}
return new WishListDto();
}
public WishListDto add(WishListDto wishListDto) {
var entity = dtoToEntity(wishListDto);
var saveEntity = wishListRepository.save(entity);
return entityToDto(saveEntity);
}
private WishListEntity dtoToEntity(WishListDto wishListDto){
var entity = new WishListEntity();
entity.setIndex(wishListDto.getIndex());
entity.setTitle(wishListDto.getTitle());
entity.setCategory(wishListDto.getCategory());
entity.setAddress(wishListDto.getAddress());
entity.setRoadAddress(wishListDto.getRoadAddress());
entity.setHomePageLink(wishListDto.getHomePageLink());
entity.setImageLink(wishListDto.getImageLink());
entity.setVisit(wishListDto.isVisit());
entity.setVisitCount(wishListDto.getVisitCount());
entity.setLastVisitDate(wishListDto.getLastVisitDate());
return entity;
}
private WishListDto entityToDto(WishListEntity wishListEntity){
var dto = new WishListDto();
dto.setIndex(wishListEntity.getIndex());
dto.setTitle(wishListEntity.getTitle());
dto.setCategory(wishListEntity.getCategory());
dto.setAddress(wishListEntity.getAddress());
dto.setRoadAddress(wishListEntity.getRoadAddress());
dto.setHomePageLink(wishListEntity.getHomePageLink());
dto.setImageLink(wishListEntity.getImageLink());
dto.setVisit(wishListEntity.isVisit());
dto.setVisitCount(wishListEntity.getVisitCount());
dto.setLastVisitDate(wishListEntity.getLastVisitDate());
return dto;
}
public List<WishListDto> findAll() {
return wishListRepository.findAll()
.stream()
.map(it -> entityToDto(it))
.collect(Collectors.toList());
}
public void delete(int index) {
wishListRepository.deleteById(index);
}
public void addVisit(int index){
var wishItem = wishListRepository.findById(index);
if(wishItem.isPresent()){
var item = wishItem.get();
item.setVisit(true);
item.setVisitCount(item.getVisitCount()+1);
}
}
}
- ApiController 클래스
package com.example.restaurant.controller;
import com.example.restaurant.wishlist.dto.WishListDto;
import com.example.restaurant.wishlist.service.WishListService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/api/restaurant")
@RequiredArgsConstructor
public class ApiController {
private final WishListService wishListService;
@GetMapping("/search")
public WishListDto search(@RequestParam String query){
return wishListService.search(query);
}
@PostMapping("")
public WishListDto add(@RequestBody WishListDto wishListDto){
log.info("{}", wishListDto);
return wishListService.add(wishListDto);
}
@GetMapping("/all")
public List<WishListDto> findAll(){
return wishListService.findAll();
}
@DeleteMapping("/{index}")
public void delete(@PathVariable int index){
wishListService.delete(index);
}
@PostMapping("/{index}")
public void addVisit(@PathVariable int index){
wishListService.addVisit(index);
}
}
- PageController 클래스
package com.example.restaurant.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/pages")
public class PageController {
@GetMapping("/main")
public ModelAndView main(){
return new ModelAndView("aaaa/main");
}
}
반응형