'SpringBoot' 카테고리의 다른 글

회원가입 구현  (1) 2024.10.21
AJAX를 통한 삭제 기능  (2) 2024.10.21
수정 기능 구현  (0) 2024.10.20
REST API 에러처리  (1) 2024.10.18
에러 처리  (1) 2024.10.18

회원가입

'SpringBoot' 카테고리의 다른 글

로그인 기능  (0) 2024.10.22
AJAX를 통한 삭제 기능  (2) 2024.10.21
수정 기능 구현  (0) 2024.10.20
REST API 에러처리  (1) 2024.10.18
에러 처리  (1) 2024.10.18

ajax란 ?

 

  • 비동기성: 전체 페이지를 다시 로드하지 않고, 필요한 데이터만 서버에 요청하고 응답을 받습니다. 사용자는 페이지가 계속 표시된 상태에서 서버와의 통신이 이루어집니다.
  • 데이터 교환: JSON, XML, HTML, 또는 일반 텍스트 형식으로 데이터를 서버에서 받아올 수 있습니다. 요즘에는 주로 JSON 형식을 사용합니다.
  • 자바스크립트 사용: AJAX 요청과 응답 처리는 자바스크립트를 통해 이루어집니다. 자바스크립트는 서버와 HTTP 요청을 보내고, 응답을 처리하여 페이지에 업데이트하는 역할을 합니다.
  • 브라우저 지원: 거의 모든 최신 웹 브라우저가 AJAX를 지원하며, 다양한 웹 애플리케이션에서 널리 사용됩니다.

 

gpt 참고

 

페이지를 다시 로드하지 않고 비동기적으로 서버와 통신한다

주로 JSON 형식을 사용하고

 

JSON

key value 값으로 구성된 객체로 이루어진 배열

ex>

{
  "name": "John",
  "age": 30,
  "city": "Seoul"
}

 

또 자바스크립트를 사용해서 이루어진다

 

ajax를 통해 리스트의 항목을 삭제해보자

<div>
    <h4 th:text="${item.title}"></h4>
    <p th:text="${item.price}"></p>
    <a th:href="@{'/modify/' + ${ item.id } }">
        <button >수정</button>
    </a>
    <button class="delete_btn">삭제</button>
</div>

일단 삭제버튼 생성

 

community 무료버전은 스크립트가 안된다고 한다

그래서 30일 무료체험버전 다운로드해서 해야될듯 하다

 

 

 

'SpringBoot' 카테고리의 다른 글

로그인 기능  (0) 2024.10.22
회원가입 구현  (1) 2024.10.21
수정 기능 구현  (0) 2024.10.20
REST API 에러처리  (1) 2024.10.18
에러 처리  (1) 2024.10.18

현재 이미지를 누르면 상세페이지로 넘어가는데 수정 기능이 있으면 좋겠다

 

<div class="card" th:each="item : ${items}">
    <a th:href="@{'/detail/' + ${ item.id } }">
        <img src="https://placehold.co/300">
    </a>
    <div>
        <h4 th:text="${item.title}"></h4>
        <p th:text="${item.price}"></p>
        <a th:href="@{'/modify/' + ${ item.id } }">
            <button >수정</button>
        </a>

    </div>
</div>

모든 상품목록에 수정 기능이 필요하니 타임리프 반복문 안에 a태그로 modify로 id값을 가져가게 만들어준다

 

@GetMapping("/modify/{id}")
String modify(Model model,
              @PathVariable Integer id) {
    var item = itemService.findById(id);
    if (item.isPresent()) {
        model.addAttribute("detail", item.get());
    } else {
        return "redirect:/list";
    }
    return "modify";
}

url로 이동하게 만들어뒀으니 그걸 잡아주는 컨트롤러가 필요하다

GetMapping 같은 경우는 modify/변하는 id 값으로 받아주고

먼저 기본적으로 등록되있는 값을 보여주기 위해 modify라는 html안에

데이터베이스 안에 아이템의 정보를 넣어준다

또 널값일 수 있으니 if문으로 해주고

modify.html을 반환

 

<form action="/update" method="POST">
    <input type="hidden" th:value=${detail.id} name="id">
    <input type="text" th:value="${detail.title}" name="title">
    <input type="text" th:value="${detail.price}" name="price">
    <button type="submit" > 수정완료 </button>
</form>

 

id 값은 보일 필요는 없지만 쓸 곳이 있으니 히든으로 생성해놓는다

또 여기서 th:value라는게 있는데 input 태그 안에 기본적으로 값이 들어가있으려면

th:value를 사용해서 채워놓을 수 있다

그리고 이번에도 사용자에게 받은 값을 전송해야하기 때문에 form 태그 안에 감싸준다

이번엔 update로 보내주기 때문에

컨트롤러로 넘어간다

 

@PostMapping("/update")
String modifyPost(Integer id,String title, Integer price) {
    itemService.modify(id, title, price);
    return "redirect:/list";
}

 

update로 들어왔을 때 id, title, price 값을 기본 id값과 사용자에게 받은 title, price 값을 가지고 또 서비스로 넘어간다

 

public void modify(Integer id, String title, Integer price) {
    var item = itemRepository.findById(id).orElse(null);
    item.setTitle(title);
    item.setPrice(price);
    itemRepository.save(item);
}

 

이건 서비스 쪽에 modify인데

일단 save 라는게 새로 추가하는 뜻도 있는데

자체가 id값이 중복되는 값이 있을경우 수정으로 바뀌게 된다고 한다

또 save 안에는 Entity 객체가 들어와야하는데

var item = itemRepository.findById(id)

 

이렇게만 받아왔을 경우

Optional

 

상태이기 때문에 .orElse(null)로 변경해주는거 같다

gpt가 orElse(null)은 엔티티가 존재하지 않을 경우 null을 반환하는 방법이라고 한다

맞는거같다

이렇게 수정기능 완성 ~

 

+ 강의 확인해보니 save 라는게 새로운 Entity여도 id값이 중복이면 수정이 가능하다

public void modify(Integer id, String title, Integer price) {
    Item item = new Item();
    item.setId(id);
    item.setTitle(title);
    item.setPrice(price);
    itemRepository.save(item);
}

 

이런식으로도 접근이 가능하다 !

'SpringBoot' 카테고리의 다른 글

회원가입 구현  (1) 2024.10.21
AJAX를 통한 삭제 기능  (2) 2024.10.21
REST API 에러처리  (1) 2024.10.18
에러 처리  (1) 2024.10.18
상품 상세 페이지  (1) 2024.10.16

타임리프를 쓰는 경우에는 알아서 error.html로 보내주지만

단순히 데이터만 이동시키는 REST API 같은 경우는 다른 방법이 필요하다

 

try catch

@GetMapping("/dd")
@ResponseBody
String error() {
    try {
        
    } catch (Exception e) {
        return "에러";
    }
    return "잘됨";
}

try {

  에러가 날 수 있는 코드 ex> 

if (result.isPresent()) {
    model.addAttribute("detail", result.get());
} else {
    return "redirect:/list";
}

} catch (

  catch 블록은 항상 예외 클래스 타입을 명시해줘야한다

  이렇게 많지만 모든 예외를 포괄하는게

  Exception 이다

) {

  에러가 날 시 사용될 코드

}

 

강제로 에러가 나게도 가능하다

@GetMapping("/dd")
@ResponseBody
String error() {
    try {
        throw new Exception("db 저장 에러");
    } catch (Exception e) {
        System.out.println(e.getMessage());
        return "에러";
    }
}

throw new Exception() 을 통해서 에러가 나게도 가능하다

또 sout를 통해 e.getMessage를 사용했는데

에러가 난 이유에 대한 메세지를 반환한다

종류가 많

 

또 그냥 에러처리만 사용할 순 없는데

위에 처럼 try catch 문으로 예외처리를 해주거나

@GetMapping("/dd")
@ResponseBody
String error() throws Exception {
    throw new Exception("db저장 에러");
}

 

이런 식으로 함수 옆에 throws Exception을 붙여줘야한다

 

REST API 에서 문자만 보내는거보다 에러코드와 함께 보내줄 수 있다

@GetMapping("/dd")
ResponseEntity<String> error() {
    try {
        throw new Exception("db 저장 에러");
    } catch (Exception e) {
        return ResponseEntity.status(400).body("에러이유");
    }
}

ResponseEntity를 통해 가능하다

return 하는 곳에

ResponseEntity

 

.status는 상태코드

2xx 정상작동

4xx 유저원인

5xx 서버원인

 

.body는 그 html에 바디에 이유 같은걸 실어서 보낼 수 있다

 

또 .status에 상태코드 입력하는걸 모르겠다면

에러코드를 모아둔 함수도 있다

HttpStatus하고 뒤에 .을 찍어보면 사용할 수 있는 에러코드들이 있다

 

@ExceptionHandler

 

try catch를 사용해도 못잡는 url에 관한 부분도 있고

try 내부에서만 에러처리가 가능하기 때문에 스프링에서 제공해주는

Spring boot에서 제공하는 기능이 있다

@ExceptionHandler(Exception.class)
ResponseEntity<String> error() {
    return ResponseEntity.status(HttpStatus.NOT_FOUND).body("에러");
}

 

이렇게 위에 @ExcpetionHandler(Exception.class)를 달아줄 시

해당 클래스 내에 있는 모든 오류가 날 시 이 부분으로 넘겨준다

 

근데 또 클래스 자체가 여러개일 경우에 하나하나 집어넣는것도 일이니

따로 클래스를 새로 만들어서 모든곳에 적용되게 만들 수 있다

 

@ControllerAdvice

 

@ControllerAdvice
public class MyExceptionHandler {
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handler() {
        return ResponseEntity.status(400).body("모든 컨트롤러 에러시 발동");
    }
}

 

따로 클래스를 생성해서 @ControllerAdvice를 달아놓고

그안에 예외처리에 대해서 작성해놓으면

모든 클래스에서 발동된다

 

기본 컨트롤러에도 ExceptionHandler를 통해서 에러처리를 해두었다면

컨트롤러 내부에 있는 에러처리가 우선이 된다

 

또 @ExceptionHandler() 괄호안의 들어가는 부분으로 특정 상황에서만 에러처리가 가능하다

 

현재는 Exception.class로 모든 에러를 처리하는데

예를 들어 url 타입에 정수형이 들어와야하는데 문자열이 들어올시 실행창에 에러이름이 나온다

MethodArgumentTypeMismatchException 이런 식으로 나오게 되는데

@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResponseEntity<String> handler() {
    return ResponseEntity.status(400).body("숫자가 들어와야함");
}

 

이런식으로 타입이 매치되지 않았을 때에 대한 에러처리도 가능하다

'SpringBoot' 카테고리의 다른 글

AJAX를 통한 삭제 기능  (2) 2024.10.21
수정 기능 구현  (0) 2024.10.20
에러 처리  (1) 2024.10.18
상품 상세 페이지  (1) 2024.10.16
navbar 만들기 (th:fragment, th:replace)  (1) 2024.10.16
@GetMapping("/detail/{id}")
    String detail(Model model,
              @PathVariable Integer id) {
    var result = itemRepository.findById(id);

    if (result.isPresent()) {
        model.addAttribute("detail", result.get());
    } else {
        return "redirect:/list";
    }
    return "detail.html";
}

예를 들어 상품의 상세정보로 가는 페이지에 url 마지막은 정수형의 id가 들어와야한다

하지만 다른 문자열이나 들어올 시 

 

id 부분에 문자열 "안녕"이 들어간 페이지

이런 페이지로 가진다 유저 입장에서 보면 난감할거다

 

타임리프를 의존성에 추가 후 사용중이라면 

templates 폴더내에 error.html을 만들어놓을시 자동으로 보내준다

여기서 이제 에러페이지를 만들어주면 된다

 

error 페이지에서만 사용할 수 있는 타임리프 문법이 또 있다

<p th:text="${status}"></p>

HTTP 상태 코드를 반환해준다


<p th:text="${error}"></p>

오류의 요약 정보를 반환


<p th:text="${path}"></p>

어느 경로에서 문제가 발생했는지 반환


<p th:text="${message}"></p>

오류 메시지 또는 상태 메시지를 반환


<p th:text="${exception}"></p>


발생한 예외 객체의 이름이나 설명을 반환

'SpringBoot' 카테고리의 다른 글

수정 기능 구현  (0) 2024.10.20
REST API 에러처리  (1) 2024.10.18
상품 상세 페이지  (1) 2024.10.16
navbar 만들기 (th:fragment, th:replace)  (1) 2024.10.16
사이트 내에서 입력받은 상품 추가  (1) 2024.10.16

GetMapping url에 

{작명} 을 사용시

ex > GetMapping("/detail/{아무거나}")

시에 모든 문자들을 허용한다

 

@GetMapping("/detail/{id}")
String detail() {
    return "detail.html";
}

이러면 url 주소가 /detail/ 뒤에 뭐가 오든

detail.html로 옮겨준다

 

지금은 db에 모든 정보가 아닌 id값을 통한 상세 정보가 필요하다

 

Optional result = itemRepository.findById(1);

레포지토리에 findById 를 통해서 id를 입력해서 그 id에 해당하는 정보만 반환하게 된다

여기서 반환되는 타입은 Optional 인데

Optional 이란 null 이거나 null이 아닐수도 있다는것이다

id를 만약 찾는데 db에는 100가지의 옷을 등록해놨는데

101번을 찾는다면 null 일 수도 있기 때문이다

 

그래서 if문으로 반환되는 변수에 값이 있는지 확인하고 막아줘야한다

Optional.isPresent() 로 안에 내용이 존재하는지 boolean 값으로 반환해준다

또 그안에 값을 꺼낼 땐 .get으로 꺼내준다

if (result.isPresent()) {
    model.addAttribute("detail", result.get());
} else {
    return "redirect:/list";
}

안에 값이 존재할 경우 모델에 db 정보를 넣어주고

존재하지 않을 경우에는 list 페이지로 되돌아간다

원래는 에러페이지 만들고 하는데 아직 만들지 않았으니

list로 돌아가게 만들었다

 

@GetMapping("/detail/{id}")
String detail(Model model,
              @PathVariable Integer id) {
    var result = itemRepository.findById(id);

    if (result.isPresent()) {
        model.addAttribute("detail", result.get());
    } else {
        return "redirect:/list";
    }
    return "detail.html";
}

GetMapping 시에 {여기에 작명을 한 이유}

는 @PathVariable로 뒤에 들어온 값들을 가져올 수 있다

상세정보는 id 값에 따라서 정보들이 달라야하기 때문에 id 값으로 정보들을 html에 넣어준다

 

<h4 th:text="${detail.title}"></h4>
<p th:text="${detail.price}"></p>

detail.html 같은 경우 타임리프 문법으로 가져온 정보들을 채워주면 된다

'SpringBoot' 카테고리의 다른 글

REST API 에러처리  (1) 2024.10.18
에러 처리  (1) 2024.10.18
navbar 만들기 (th:fragment, th:replace)  (1) 2024.10.16
사이트 내에서 입력받은 상품 추가  (1) 2024.10.16
접근 권한 (access modifiers  (0) 2024.10.15

여러 페이지에서 사용하는 내비게이션 바 같은 경우는

<div class="nav">
    <a class="logo">SpringMall</a>
    <a href="/list">List</a>
    <a href="/write">Write</a>
</div>

 

이렇게 만든다고 하면 계속 만들어주는 것도 일이다

그래서 이 ui 자체를 조각으로 분리해서 여러 곳에서도 사용이 가능하다

 

따로 nav.html 식으로 파일을 만들어준다

그 안에

<div class="nav" th:fragment="navbar">
    <a class="logo">SpringMall</a>
    <a href="/list">List</a>
    <a href="/write">Write</a>
</div>

 

위에 코드하고 다를게 없어보이지만 th:frament="변수명" 이 추가되었다

타임리프 문법 추가시 다른곳에서도 다른 타임리프 문법으로 추가가 가능하다

 

<div th:replace="~{ nav.html::navbar }"></div>

 

사용할 페이지에 아무 div 만들고

th:replace="~{ 경로::변수명 }" 입력시

위 div가 갈아치워진다

th:insert 로도 추가도 가능하지만

갈아치우는게 일반적

'SpringBoot' 카테고리의 다른 글

에러 처리  (1) 2024.10.18
상품 상세 페이지  (1) 2024.10.16
사이트 내에서 입력받은 상품 추가  (1) 2024.10.16
접근 권한 (access modifiers  (0) 2024.10.15
HTML에 서버데이터 넣기  (0) 2024.10.14

+ Recent posts