<form id="profileUpdate" onsubmit="update(${principal.user.id} ,event)">
이런식으로 jsp 안에 버튼에 온클릭 이벤트 삽입(매개변수 id로 보냄)
그후 ajax처리
function update(userId,event) {
event.preventDefault(); //폼 태그 액션 막기
let data=$("#profileUpdate").serialize();
console.log(data);
$.ajax({
type:"put",
url:`/api/user/${userId}/`,
data : data,
contentType : "application/x-www-form-urlencoded; charset=utf-8",
dataType: "json"
}).done(res=>{
alert("수정에 성공하였습니다.");
location.href=`/user/${userId}`;
}).fail(error=>{
alert("수정에 실패하였습니다.");
});
}
.serialize() 는 입력된 form 데이터의 element들을 모두 data로 한꺼번에 직렬화 할수있다
아니면 serialize 안쓰고 직접 JSON으로 적어서
contentType 에 "application/JSON" 으로 보내도되고 선택은 자유
`` 백틱 사용하는 이유 : el식 쓰려고
새로 api 패키지 만들고 안에 api 컨트롤러 생성
@RequiredArgsConstructor
@RestController
public class UserApiController {
private final UserService userService;
//DATA를 응답하는 애들은 api
@PutMapping("/api/user/{id}")
public CMRespDto<?> update(UserUpdateDto userUpdateDto , @PathVariable int id) {
User userEntity = userService.회원수정(id,userUpdateDto.toEntity());
return new CMRespDto<>(1,"회원수정완료",userEntity);
}
}
AJAX 통해서 보낸 URL을 통해 컨트롤러단에서 서비스로 보낸다 파라메터에는 새로만든Dto랑 세션값 id, session 넣고 이 과정에서 새로 UserUpdateDto를 만들었고 영속화 진행, 여기서
session값도 바로 수정해준다(바꾸고 난 후에 세션정보 남을수있도록).
DB와 통신하는 새로운 로직이 생겼으니, DTO도 만든다.
import com.pyo.yourspick.domain.user.User;
import lombok.Data;
@Data
public class UserUpdateDto {
private String name;
private String password;
private String website;
private String bio;
private String phone;
private String gender;
public User toEntity(){
return User.builder()
.name(name)
.password(password)
.website(website)
.bio(bio)
.phone(phone)
.gender(gender)
.build();
}
}
* 아직 널처리 낫널처리 안한상태이고
toEntity는 추후 @Entity 어노테이션으로 따로 지정 가능함. 빌더통해서 영속화 과정을 거쳐준다
service 패키지의 UserService 클래스로 가서
@RequiredArgsConstructor
@Service
public class UserService {
private final UserRepository userRepository;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
@Transactional
public User 회원수정(int id, User user) {
//1. 영속화
User userEntity = userRepository.findById(id).orElseThrow(()->
new IllegalArgumentException("아이디 못찾음!"));
//2. 영속화된 오브젝트를 수정 - 더티체킹(업데이트 완료
userEntity.setName(user.getName());
String rawPassword = user.getPassword();
String encPassword = bCryptPasswordEncoder.encode(rawPassword);
userEntity.setPassword(rawPassword);
userEntity.setWebsite(user.getWebsite());
userEntity.setWebsite(user.getWebsite());
userEntity.setBio(user.getBio());
userEntity.setPhone(user.getPhone());
userEntity.setGender(user.getGender());
return userEntity;
} // 더티체킹이 되서 업데이트가 완료됨
}
Q . Repository.saveAll() 을 안써도 업데이트가 되나요? 된다면 어떻게 되는거?
A. @Transactional 어노테이션을 붙여주면 영속성 컨텍스트 에서의 변화를 감지하면 알아서 업데이트
하기 때문임
자, 이제 DB는 제대로 변경되었다 하지만 아직 세션에는 저장되지않았다, 저장해주자
@PutMapping("api/user/{id}")
public CMRespDto<?> update(UserUpdateDto userUpdateDto, @PathVariable int id, @AuthenticationPrincipal PrincipalDetails principalDetails){
User userEntity = userService.회원수정(id, userUpdateDto.toEntity());
principalDetails.setUser(userEntity);
return new CMRespDto<>(1, "업데이트 완료", userEntity);
}
}
@AuthenticationPricipal 선언하고
setUser에 userEntity를 넣어주자. 이제 세션을 넣었으면
function update(userId) {
let data = $("#profileUpdate").serialize();
$.ajax({
type: "put",
data: data,
url: `/api/user/${userId}`,
contentType: "application/x-www-form-urlencoded; charset=utf-8",
dataType: "json"
}).done(res => {
console.log(res,"성공");
location.href=`/user/${userId}`;
}).fail(error => {
console.log(error,"실패")
})
}
이제 js에서 `` 백틱 사용해서 userId 받아서 되돌아가면 성공.
'Spring > JPA + Security' 카테고리의 다른 글
[Spring] 회원 수정 에서 유효성 처리 하기 -2 DB에 없는 값 (0) | 2023.01.08 |
---|---|
[Spring] 회원 수정 에서 유효성 처리하기 - 2 Exception Handler 적용 (0) | 2023.01.07 |
[Spring Security] 세션을 JSP로 넘기는 방법 2가지 (0) | 2023.01.07 |
[Spring Security] 스프링 시큐리티의 로그인 세션의 위치, @AuthenticationPrincipal 예제 (0) | 2023.01.07 |
스프링 시큐리티에서의 로그인 - 시큐리티한테 위임 (0) | 2023.01.07 |
댓글