JSON으로 전달 받은 String 값 List로 변경
여행 리스트를 작성하던 중 작성 한 순서를 변경하고 싶을때, 쉽게 변경 가능하도록 드레그 하여 리스트 순서를 변경할 수 있는 기능을 추가하였습니다.
프론트에서는 드레그를 통해 ui 와 인덱스 번호가 변경될 수 있도록 jquery ui 라이브러리를 사용했습니다.
그리고 실제 데이터베이스의 리스트 순서값을 변경 하기 위해서 리스트 안에 각 객체의 고유 번호와 변경된 순서 값을 ajax를 통해 컨트롤러로 전달했습니다.
Sortable | jQuery UI
Sortable Reorder elements in a list or grid using the mouse. Enable a group of DOM elements to be sortable. Click on and drag an element to a new spot within the list, and the other items will adjust to fit. By default, sortable items share draggable prope
jqueryui.com
1. FrontEnd
📑 navBarTravelMap.html
- 리스트가 들어갈 <ul> 태그
<ul id="sortable" class="item_wrap list-group mt-3"></ul>
- jquery ui 플러그인 드레그 기능 : sortable 메서드
let itemListWrap = $("#sortable");
itemListWrap.sortable({
start:function (event,ui){
ui.item.data('start_pos',ui.item.index());
},
stop:function (event,ui){
var spos = ui.item.data('start_pos');
var epos = ui.item.index();
reorder();
}
});
function reorder(){
// 리스트 순서 추가하기
$("#sortable .list-group-item").each(function (i,box){
$(box).attr('data-index',i);
});
//클릭시 정보 수정 하기 위해 불러오기
$("#sortable .list-group-item").on('click',function () {
let dayNo = $(this).data("no");
$.ajax({
type: 'get',
dataType: 'json',
url:'/board/itemGet?no='+dayNo,
success:function (data) {
...
},
error:function (){
alert("내용을 불러오는 것을 실패했습니다.");
}
});
});
}
- 임시 저장 버튼 클릭시 Ajax를 통해 컨트롤러로 리스트 전달
let btnTotalStorageSave = $("#btnTotalStorageSave");
btnTotalStorageSave.on('click',function () {
let data = [];
itemListWrap.find("li").each(function (index, item){
index = {
itemNo:'',
itemNumber :''
}
index.itemNo = $(this).data("no");
index.itemNumber = $(this).data("index");
data.push(index);
});
var jsonData = JSON.stringify(data);
console.log(jsonData);
$.ajax({
url:'/board/StorageSave',
type:'get',
dataType: 'json',
data: {"jsonData" : jsonData},
success:function (data){
$('#modalMsg').modal("show");
$('#modalMsg .modal-message').html("리스트 순서가 변경되었습니다.");
},
error:function (data){
alert("오류")
}
});
})
2. BackEnd
2-1. Controller
📑 BoardApi.java
프론트에서 전달 한 값은 String 타입으로 컨트롤러에서 받을 수 있게 됩니다.
이때 전달된 값의 형태를 보면, [{},{},{}] 배열 안에 객체가 들어있는 형태의 String 값입니다.
이러한 배열을 객체로 받기 위해서 ObjectMapper를 사용하여 데이터 타입을 변경 시킬 수 있습니다.
ObjectMapper
- Jackson에서 제공하는 ObjectMapper 객체입니다.
- java Object => Json 으로 변경 : writerValue 메서드
- Json => java Object 로 변경 : readValue 메서드
List<Object> 타입으로 변경된 데이터를 서비스으로 전달하여 서비스 클레스에서 변경된 내용을 저장하는 로직을 구현하였습니다.
@GetMapping("/StorageSave")
public boolean itemStorageSave(@RequestParam("jsonData") String itemString){
log.info("임시 저장--------------------- ");
log.info(itemString);
try {
ObjectMapper objectMapper = new ObjectMapper();
List<ItemDTO> itemList = objectMapper.readValue(itemString, new TypeReference<List<ItemDTO>>() {});
itemService.itemListOrderBySet(itemList);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return true;
}
2-2. Service
인터페이스에 메서드 추가
📑 ItemService.java
//아이템 리스트 순서 변경
void itemListOrderBySet(List<ItemDTO> itemList);
실제 구현 로직을 가지고 있는 ItemService.java를 상속받은 클래스
- 전달 받은 리스트 객체에서는 ItemNo와 ItemNumber 필드의 값을 가지고 있습니다.
- for 문으로 리스트 안의 객체를 ItemRepository.getOne()을 통해 가져옵니다.
- 가져온 객체의 정보에 수정 된 ItemNumber를 set메서드를 통해 변경했습니다.
- save 메서드를 통해 다시 저장하면 기존 객체가 update 되어 정보가 변경됩니다.
📑 ItemServiceImpl.java
@Override
public void itemListOrderBySet(List<ItemDTO> itemList) {
for(int i= 0; i<itemList.size();i++){
Item item = itemRepository.getOne(itemList.get(i).getItemNo());
log.info("item : {}",item);
ItemDTO itemDTO = itemEntityToDto(item);
itemDTO.setItemNumber(itemList.get(i).getItemNumber());
log.info("itemDTO : {}",itemDTO);
Item result = itemDtoToEntity(itemDTO);
Item save = itemRepository.save(result);
}
}
📑ItemDTO.java
package com.example.travel.dto.travel;
import com.example.travel.domain.Category;
import lombok.*;
import java.util.List;
@Getter
@Setter
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ItemDTO {
private Long itemNo; //고유번호
private Long categoryId;
// item
private int itemDay; //여행 DAY
private int itemNumber; // DAY 안에서 순서
private int itemAccount; // 비용
private String itemInfo; // 정보 내용
private String itemContent; // 회원 컨텐츠
private String itemTime; // 도착 시간
//kakao api
private String id; // 장소 ID
private String placeName; // 장소 명
private String placeTime; // 운영 시간
private String placeUrl; //url
private String phone; // 전화번호
private String addressName; // 지번 주소
private String roadAddressName; // 도로명 주소
private String x; //x 좌표값
private String y; // y 좌표값
private String distance; // 중심좌표까지의 거리
}
📑ItemRepository.java
package com.example.travel.repository.travel;
import com.example.travel.domain.Category;
import com.example.travel.domain.Item;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface ItemRepository extends JpaRepository<Item,Long> {
List<Item> findItemByCategory(Category category);
@Query(value = "select i from Item i left join Category c on i.category=c where i.category.categoryNo=:cNo and i.itemDay=:iDay order by i.itemNumber" ,nativeQuery = false)
List<Item> findItemList(@Param("iDay") int itemNo,@Param("cNo") Long categoryNo);
}
'Project · Etc > Project' 카테고리의 다른 글
[ Project · Travel Road ] summernote 무료 에디터 사용하기 (0) | 2023.09.04 |
---|---|
[ Project ] AWS 가입 및 프로젝트 배포하기 (0) | 2023.08.21 |
[ Project · Travel Road ] 새로고침 시 데이터 중복 저장 막기, 컨트롤러 구분 (0) | 2023.06.26 |
[ Project · Travel Road ] 해시 태그 로직 구현하기 (0) | 2023.06.25 |
[ Project · Travel Road ] D-DAY 날짜 계산하기 - LocalDateTime · LocalDate · Period (0) | 2023.06.24 |