개인프로젝트/기능프로그램_오늘뭐입지

20240518_로그인 실패 ajax + 위치 자동 출력&위치에 따른 지역 자동 출력

일일일코_장민기 2024. 5. 18. 08:22
728x90

 

아주 간단하고 사소한 기능이다.

Spring Security Passencoder의 matches에 jpa가 더해졌다는 것 빼고는 팀프로젝트 당시와 동일

 

더보기

컨트롤러

@PostMapping("/loginAjax")
public boolean loginAjax(String username, String password) {

    String encodedPassword = memberRestService.findPasswordByUsername(username);
    if(encodedPassword == null || encodedPassword.isEmpty()) {
        return false;
    }
    return passwordEncoder.matches(password, encodedPassword);
}

 서비스

public String findPasswordByUsername(String username) {
    MemberVO member = memberRestRepository.findByUsername(username);
    if (member != null) {
        return member.getPassword();
    }
    return null;
}

 

js

$(function(){

    $(".loginInfo").on("input", function(){
        $("#loginErrorField").empty();
    })

    $("form").on("submit", function(event){
        event.preventDefault();
        loginAjax();
    })
})

function loginAjax(event){

    const loginErrorField = $("#loginErrorField");

    if (loginErrorField.text() !== "") {
        return;
    }

    const username = $("#username").val();
    const password = $("#password").val();

    $.ajax({
        type: "post",
        url: "/loginAjax",
        data: {
            username: username,
            password: password
        },
        datatype: "json",
        success: function(response){
            if(response === true){
                $("form")[0].submit();
            }
            else{
                loginErrorField.html("아이디나 비밀번호를 확인해주세요").css("color", "red");
            }
        },
        error: function(){
            console.log("로그인 ajax 출력 에러")
        }
    })
}

 

 

위치 자동 출력&위치에 따른 지역 자동 출력

더보기

컨트롤러

@PostMapping("/findCountries")
@ResponseBody
public List<String> findCountries() {
    return utilService.findCountries();
}

 

서비스

public List<String> findCountries() {
    List<Place> places = utilRepository.findAll();
    Set<String> countrySet = new HashSet<>();
    for (Place place : places) {
        countrySet.add(place.getCountry());
    }
    return new ArrayList<>(countrySet);

}

 

 

 

js

function viewSelectableCountry(){
    const countryInput = $("#countryInput");
    $.ajax({
        type: "post",
        url: "/findCountries",
        success: function(response){

            let htmlSelection = "<select id='country' name='country'>";
            response.forEach(countryName => {
                htmlSelection += `<option value="${countryName}">${countryName}</option>`
            })
            htmlSelection +=  "</select>"
            countryInput.html(htmlSelection);
            changeAreaByCountry();
        },
        error: function(){
            console.log("위치 출력 에러")
        }
    })
}

 

날씨 모듈도 수정했다

이제 줄줄이 나열된 코드는 필요 없다

 

 

 

 

 

거의 한 6개월만에 Set 쓰게 되었고 겸사겸사 Stream 기능도 알게 되었다.

더보기
public List<String> findCountries() {
    List<Place> places = utilRepository.findAll();
    Set<String> countrySet = new HashSet<>();
    for (Place place : places) {
        countrySet.add(place.getCountry());
    }
    return new ArrayList<>(countrySet);
}
Set은 중복된 요소를 허용하지 않기 때문에, 중복된 국가명을 자동으로 제거


public List<String> findCountries() {
    return utilRepository.findAll().stream()
            .map(Place::getCountry)
            .distinct()
            .collect(Collectors.toList());
}

각 부분의 의미
1. stream():
findAll()로 가져온 리스트를 스트림으로 변환
스트림은 컬렉션(리스트, 배열 등)을 처리하는데 사용

2. map(Place::getCountry):
스트림 내의 각 Place 객체에 대해 getCountry 메서드를 호출하여 위치 명만 추출
Place::getCountry는 Place 객체의 getCountry 메서드를 참조하는 메서드 참조(method reference)
결과적으로 스트림은 위치 명 문자열들로 구성

3. distinct():
스트림에서 중복된 위치 명을 제거
중복되지 않은 고유한 위치 명만을 스트림에 남김

4. collect(Collectors.toList()):
스트림의 요소들을 리스트로 수집
최종 결과는 중복이 제거된 위치 명들의 리스트

필요해지니까 왜 이런 기능이 생겨났는지 알기 쉬웠다.

이런 저런 기능 구현 경험이 중요한 이유...