59일차 (2) - 스프링 (요청 처리, 응답 처리 연습)

Yohan·2024년 5월 16일
0

코딩기록

목록 보기
87/156
post-custom-banner

요청처리, 응답처리 예시

package com.study.springstudy.springmvc.chap02;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

// 요청 처리
@Controller
@RequestMapping("/coffee/*") // /coffee/*로 들어오는 요청을 처리할게~
public class CoffeeController {

    /*
    *  @request-uri : /coffee/order
    *  @forwarding-jsp : /WEB-INF/views/mvc/coffee-form.jsp
    */


//    @RequestMapping(value = "/order", method = RequestMethod.GET)
    @GetMapping("/order") // /coffee/order는 GET 요청만 받을게~
    public String order() {
        return "mvc/coffee-form";
    }

//    @RequestMapping(value = "/result", method = RequestMethod.POST)
    @PostMapping("/result") // /coffee/result는 POST 요청만 받을게~
    public String result(String menu, int price, Model model) { // @RequestParam 생략 가능

        // 1. 주문 데이터 (menu, price) 읽어오기

        // 2. jsp에 보내서 렌더링
        // 수송객체인 model을 통해서 jsp로 전달
        model.addAttribute("mmm", menu);
        model.addAttribute("ppp", price);

        return "mvc/coffee-result";
    }
}

  • View로 전달된 menu, price는 ${} 형태로 사용됨

요청처리, 응답처리 연습

  • 1번, GetMapping, mvc/s-form을 반환 해주면됨
  • 2번, PostMapping, if문을 통해 아이디, 비밀번호 검증, mvc/s-result를 반환
package com.study.springstudy.springmvc.chap02;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/hw/*")
public class LoginController {

    @GetMapping("/s-login-form")
    public String login() {
        return "mvc/s-form";
    }

    @PostMapping("/s-login-check")
    public String loginCheck(String id, String pw, Model model) {

        String result;

        if (id.equals("grape111") && pw.equals("ggg9999")) {
            result = "success";
        } else if(!id.equals("grape111")) {
            result = "f-id";
        } else {
            result = "f-pw";
        }

        model.addAttribute("result", result);

        return "mvc/s-result";
    }
}
  • s-result.jsp가 아래처럼 구성되어있기 때문에 result라는 문자열을 생성한 후 검증을 통해 조건에 맞는 것을 model 객체를 통해 jsp로 반환한다.
    • 아이디, 비밀번호가 일치하면 result는 success가 되어 jsp에는 로그인 성공이라는 메세지가 뜨게된다.

요청 처리, 응답 처리 연습2

  • 학생 성적정보에 대한 목록조회, 등록, 삭제, 상세 조회

ScoreController

  • 데이터베이스에 저장, 삭제, 조회 등을 해야하기 때문에 의존객체를 설정
    • 나중에 인터페이스를 통해 구현하도록 수정 (DIP를 만족하게 하기위해)
  • register에서 성적정보(입력)는 dto로 받고, Score 생성자에 dto를 파라미터로 넣어서 평균, 합산, 등급 ... 등을 추가로 만듦!
@Controller
@RequestMapping("/score") // /score URL에 대한 요청 처리
public class ScoreController {

    // 의존객체 설정
    private ScoreJdbcRepository repository = new ScoreJdbcRepository();

    @GetMapping("/list")
    public String list(Model model) {

        List<Score> scoreList = repository.findAll();
        model.addAttribute("sList", scoreList);

        return "score/score-list";
    }

    @PostMapping("/register")
    public String register(ScorePostDto dto) {

        // 데이터베이스에 저장
        // 성적정보에 대한 것은 dto로 줄테니까 나머지(평균, 합산, 등급)는 Score에서 만들어
        Score score = new Score(dto);
        repository.save(score);

        // 다시 조회로 돌아가야 저장된 데이터를 볼 수 있음
        // 포워딩이 아닌 리다이렉트로 재요청을 넣어야 새롭게 디비를 조회
        return "redirect:/score/list";
    }

    @GetMapping("/remove")
    public String remove(long stuNum) {
        // 1. 삭제를 원하는 학번을 읽기

        // 2. 저장소에 연결하여 삭제처리를 진행시킨다.
        repository.delete(stuNum);

        // 3. 삭제가 완료된 화면을 띄우기 위해 조회요청으로 리다이렉션한다.
        return "redirect:/score/list";
    }

    @GetMapping("/detail")
    public String detail(long stuNum, Model model) {
        // 1. 상세조회를 원하는 학번을 읽기
        // 2. DB에 상세조회 요청
        Score score = repository.findOne(stuNum);
        // 3. DB에서 조회한 회원정보 JSP에게 전달
        model.addAttribute("s", score);


        return "score/score-detail";
    }

}

ScoreRepository

// 역할: 적당한 저장소에 CRUD하기
public interface ScoreRepository {

    // 저장소에 데이터 추가하기
    boolean save(Score score);

    // 저장소에서 데이터 전체조회하기
    // 리스트로 Score들을 전부 갖다줘
    List<Score> findAll();

    // 저장소에서 데이터 개별조회하기
    Score findOne(long stuNum);

    // 저장소에서 데이터 삭제하기
    Score delete(long stuNum);
}

ScoreJdbcRepository

public class ScoreJdbcRepository implements ScoreRepository {

    // DB 연결
    private String url = "jdbc:mariadb://localhost:3307/spring5";
    private String username = "root";
    private String password = "mariadb";

    public ScoreJdbcRepository() {
        try {
            Class.forName("org.mariadb.jdbc.Driver");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    // 저장소에 데이터 추가하는 기능
    @Override
    public boolean save(Score score) {

        try (Connection conn = connect()) {

            String sql = "INSERT INTO tbl_score " +
                    "(stu_name, kor, eng, math, total, average, grade) " +
                    "VALUES (?, ?, ?, ?, ?, ?, ?)";

            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, score.getStuName());
            pstmt.setInt(2, score.getKor());
            pstmt.setInt(3, score.getEng());
            pstmt.setInt(4, score.getMath());
            pstmt.setInt(5, score.getTotal());
            pstmt.setDouble(6, score.getAverage());
            pstmt.setString(7, score.getGrade().toString());

            int result = pstmt.executeUpdate(); // SQL 쿼리 실행

            if (result == 1) return true;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    // 저장소에서 데이터 전체조회하는 기능
    @Override
    public List<Score> findAll() {

        List<Score> scoreList = new ArrayList<>();
        try (Connection conn = connect()) {

            String sql = "SELECT * FROM tbl_score";

            PreparedStatement pstmt = conn.prepareStatement(sql);
            ResultSet rs = pstmt.executeQuery(); // 정보 조회 실행

            while(rs.next()) { // 정보가 조회될 때 마다 scoreList에 추가
                Score score = new Score(rs); // 정보의 내용 Score에서 처리
                scoreList.add(score);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return scoreList;
    }

    // 저장소에서 데이터 개별조회하는 기능 (학번으로 구분)
    @Override
    public Score findOne(long stuNum) {

        try (Connection conn = connect()) {
            String sql = "SELECT * FROM tbl_score WHERE stu_num =?";

            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setLong(1, stuNum);
            ResultSet rs = pstmt.executeQuery(); // 조회

            while(rs.next()) {
                Score score = new Score(rs); // Score에서 처리
                return score;
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Score delete(long stuNum) {


        try(Connection conn = connect()){
            String sql = "DELETE FROM tbl_score WHERE stu_num =?";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setLong(1, stuNum);

            int result = pstmt.executeUpdate();


        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // db연결 메서드
    private Connection connect() throws SQLException {
        return DriverManager.getConnection(url, username, password);
    }
}

ScorePostDto

// 역할: 브라우저가 전달한 성적정보를 포장하는 객체
public class ScorePostDto {

    private String name;
    private int kor;
    private int eng;
    private int math;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getKor() {
        return kor;
    }

    public void setKor(int kor) {
        this.kor = kor;
    }

    public int getEng() {
        return eng;
    }

    public void setEng(int eng) {
        this.eng = eng;
    }

    public int getMath() {
        return math;
    }

    public void setMath(int math) {
        this.math = math;
    }

    @Override
    public String toString() {
        return "ScorePostDto{" +
                "name='" + name + '\'' +
                ", kor=" + kor +
                ", eng=" + eng +
                ", math=" + math +
                '}';
    }
}

Score

  • 데이터베이스의 컬럼과 1대1 매칭되는 객체들을 가지고 있는 클래스
  • 저장소에서 데이터를 조회하는 기능을 할 때 rs를 파라미터로 받아 처리해주는 기능과 dto를 파라미터로 받아서 추가적인 평균, 합산, 등급을 만들어주는 기능 또한 맡았다.
// 역할: 데이터베이스의 테이블의 컬럼과 1대1로 매칭되는 필드를 가진 객체
public class Score {

    private long stuNum;
    private String stuName;
    private int kor;
    private int eng;
    private int math;
    private int total;
    private double average;
    private Grade grade;

    public Score(ResultSet rs) throws SQLException {
        this.stuNum = rs.getLong("stu_num");
        this.stuName = rs.getString("stu_name");
        this.kor = rs.getInt("kor");
        this.eng = rs.getInt("eng");
        this.math = rs.getInt("math");
        this.total = rs.getInt("total");
        this.average = rs.getDouble("average");
        this.grade = Grade.valueOf(rs.getString("grade"));
    }


    public Score(ScorePostDto dto) {
        this.stuName = dto.getName();
        this.kor = dto.getKor();
        this.eng = dto.getEng();
        this.math = dto.getMath();
        this.total = kor + eng + math;
        this.average = total / 3.0;
        this.grade = calcGrade();
    }

    private Grade calcGrade() {
        if (average >= 90) {
            return Grade.A;
        } else if (average >= 80) {
            return Grade.B;
        } else if (average >= 70) {
            return Grade.C;
        } else if (average >= 60) {
            return Grade.D;
        } else {
            return Grade.F;
        }
    }


    public long getStuNum() {
        return stuNum;
    }

    public void setStuNum(long stuNum) {
        this.stuNum = stuNum;
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public int getKor() {
        return kor;
    }

    public void setKor(int kor) {
        this.kor = kor;
    }

    public int getEng() {
        return eng;
    }

    public void setEng(int eng) {
        this.eng = eng;
    }

    public int getMath() {
        return math;
    }

    public void setMath(int math) {
        this.math = math;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    public double getAverage() {
        return average;
    }

    public void setAverage(double average) {
        this.average = average;
    }

    public Grade getGrade() {
        return grade;
    }

    public void setGrade(Grade grade) {
        this.grade = grade;
    }

    @Override
    public String toString() {
        return "Score{" +
                "stuNum=" + stuNum +
                ", stuName='" + stuName + '\'' +
                ", kor=" + kor +
                ", eng=" + eng +
                ", math=" + math +
                ", total=" + total +
                ", average=" + average +
                ", grade=" + grade +
                '}';
    }
}
profile
백엔드 개발자
post-custom-banner

0개의 댓글