Skip to content

hw3 myCourseMVC

JeongHyeon Lee edited this page Mar 11, 2021 · 1 revision

hw3-myCourseMVC Report

Spring MVC๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์š”๊ตฌ ์‚ฌํ•ญ์— ๋งž๊ฒŒ ์›น ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•œ๋‹ค.

1. ์›น ํŽ˜์ด์ง€ ์ ‘์† ์‹œ ์ธ์ฆ ์œ ๋ฌด ์ฒดํฌ

๋กœ๊ทธ์ธ ์—ฌ๋ถ€๋ฅผ ์ฒดํฌํ•˜๊ธฐ ์œ„ํ•ด security-context.xml์— jdbc-user-service๋ฅผ ์ด์šฉํ•˜์—ฌ DB์— ์ €์žฅ๋œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์กฐํšŒํ•˜์—ฌ ์ธ์ฆํ•œ๋‹ค. ๋˜ํ•œ, ์ ‘๊ทผ ๊ถŒํ•œ์„ Login ํŽ˜์ด์ง€๋งŒ permitAll๋กœ ์ง€์ •ํ•˜๊ณ  ๋‚˜๋จธ์ง€ ํŽ˜์ด์ง€๋“ค์€ hasRole(โ€˜ROLE_STUDENTโ€™)๋กœ ์ง€์ •ํ•จ์œผ๋กœ์จ ์›น ํŽ˜์ด์ง€ ์ ‘์† ์‹œ ์ธ์ฆ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋Š” ๋กœ๊ทธ์ธ ํผ์„ ์ถœ๋ ฅํ•˜๋„๋ก ํ•˜๊ณ , ์ธ์ฆ๋œ ๊ฒฝ์šฐ ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋“ค์„ ๋‘˜๋Ÿฌ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

<authentication-manager>
	<authentication-provider>
		<jdbc-user-service data-source-ref="dataSource"
			users-by-username-query="select username, password, enabled from users where username=?"
			authorities-by-username-query="select username, authority from authorities where username=?" />
	</authentication-provider>
</authentication-manager>
<http auto-config="true" use-expressions="true">
	<intercept-url pattern="/" access="hasRole('ROLE_STUDENT')" />
	<intercept-url pattern="/login" access="permitAll" />
	<intercept-url pattern="/summary" access="hasRole('ROLE_STUDENT')" />
	<intercept-url pattern="/details/2018-1" access="hasRole('ROLE_STUDENT')" />
	<intercept-url pattern="/details/2018-2" access="hasRole('ROLE_STUDENT')" />
	<intercept-url pattern="/details/2019-1" access="hasRole('ROLE_STUDENT')" />
	<intercept-url pattern="/details/2019-2" access="hasRole('ROLE_STUDENT')" />
	<intercept-url pattern="/details/2020-1" access="hasRole('ROLE_STUDENT')" />
	<intercept-url pattern="/details/2020-2" access="hasRole('ROLE_STUDENT')" />
	<intercept-url pattern="/register" access="hasRole('ROLE_STUDENT')" />
	<intercept-url pattern="/doRegister" access="hasRole('ROLE_STUDENT')" />
	<intercept-url pattern="/successRegistration" access="hasRole('ROLE_STUDENT')" />
	<intercept-url pattern="/viewRegistration" access="hasRole('ROLE_STUDENT')" />
	<intercept-url pattern="/resources/**" access="permitAll" />
	<intercept-url pattern="/**" access="denyAll" />
	<form-login login-page="/login" authentication-failure-url="/login?error" />
	<logout />
</http>

2. ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€

๋กœ๊ทธ์ธ ๋˜์ง€ ์•Š์€ ์ƒํƒœ์ผ ๊ฒฝ์šฐ ๋ณด์—ฌ์ค„ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€(login.jsp)๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž์ฒด์ ์œผ๋กœ ์ž‘์„ฑํ•˜์˜€๋‹ค. ์ธ์ฆ ์‹œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด LoginController.java์—์„œ ์„ค์ •๋œ ๋ฉ”์‹œ์ง€๊ฐ€ ์ถœ๋ ฅ๋˜๊ณ  ์ •์ƒ์ ์œผ๋กœ ๋กœ๊ทธ์ธ ํ•  ๋•Œ๋Š” CSRF Token์„ ํ•จ๊ป˜ ์ „์†กํ•จ์œผ๋กœ์จ ๊ณต๊ฒฉ์ž๋กœ๋ถ€ํ„ฐ์˜ ๊ณต๊ฒฉ์„ ๋ฐฉ์ง€ํ•œ๋‹ค.

<head>
  <title>Login (jhlee customized)</title>
</head>
<body>
  <div class="container">
    <form class="form-signin" method="post" action="<c:url value="login" />">
	<h2 class="form-signin-heading">Please sign in๐Ÿ˜„</h2>
	<c:if test="${ not empty errorMsg }">
	  <div style="color: #ff0000"> <h4> ${ errorMsg }</h4></div>
	</c:if>
	<c:if test="${ not empty logoutMsg }">
	  <div style="color: #0000ff"> <h4> ${ logoutMsg }</h4></div>
	</c:if>
	<p>
	  <label for="username" class="sr-only">UserName</label>
	  <input type="text" id="username", name="username", class="form-control" placeholder="Username" required autofocus>
	</p>
	<p>
	  <label for="password" class="sr-only">Password</label>
	  <input type="password" id="password", name="password", class="form-control" placeholder="Password" required>
	</p>
	<input name="${ _csrf.parameterName }" type="hidden" value="${ _csrf.token }" />
	<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
    </form>
  </div>
</body>

๊ฒฐ๊ณผ๋ฌผ

3. ๋ฉ”์ธ ํŽ˜์ด์ง€

์ธ์ฆ๋œ ์‚ฌ์šฉ์ž๋Š” ํ•™๊ธฐ ๋ณ„ ์ด์ˆ˜ ํ•™์  ์กฐํšŒ, ์ˆ˜๊ฐ• ์‹ ์ฒญํ•˜๊ธฐ, ์ˆ˜๊ฐ• ์‹ ์ฒญ ์กฐํšŒ ๋ฉ”๋‰ด๊ฐ€ ๋ณด์ด๋Š” ๋ฉ”์ธ ํŽ˜์ด์ง€(home.jsp)๋กœ ์ด๋™ํ•œ๋‹ค. ๋กœ๊ทธ์•„์›ƒ ์‹œ์—๋Š” LoginController.java์—์„œ ์ •์˜ํ•œ๋Œ€๋กœ ๋กœ๊ทธ์ธ ํผ์œผ๋กœ ์ด๋™ํ•˜์—ฌ ๋กœ๊ทธ์•„์›ƒ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

<head>
  <title>Menu</title>
</head>
<body>
<p><a href="${ pageContext.request.contextPath }/summary">ํ•™๊ธฐ๋ณ„ ์ด์ˆ˜ ํ•™์  ์กฐํšŒ</a></p>
<p><a href="${ pageContext.request.contextPath }/register">์ˆ˜๊ฐ• ์‹ ์ฒญํ•˜๊ธฐ</a></p>
<p><a href="${ pageContext.request.contextPath }/viewRegistration">์ˆ˜๊ฐ• ์‹ ์ฒญ ์กฐํšŒ</a></p>
  <c:if test="${ pageContext.request.userPrincipal.name != null }">
    <a href="javascript:document.getElementById('logout').submit()">Logout</a>
  </c:if>
  <form id="logout" action="<c:url value="/logout" />" method="post">
    <input type="hidden" name="${ _csrf.parameterName }" value="${ _csrf.token }" />
  </form>
</body>

๊ฒฐ๊ณผ๋ฌผ

4. Course Model ๋งŒ๋“ค๊ธฐ

๊ฐ ๋ฉ”๋‰ด๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋จผ์ € model์ด ํ•„์š”ํ•˜๋‹ค. ์ด๋ฒˆ ๊ณผ์ œ์—์„œ์˜ ๋ชจ๋ธ์€ ์ˆ˜๊ฐ•ํ•œ ๊ต๊ณผ๋ชฉ์ด๋ฏ€๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด Course.java๋ฅผ ์ž‘์„ฑํ•˜์˜€๋‹ค. ์ถ”ํ›„ ์ˆ˜๊ฐ•์‹ ์ฒญ ํผ ์ž‘์„ฑ ์‹œ ์ž…๋ ฅํ•œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๊ฒ€์ฆ ์ž‘์—…์„ ํ•  ๋•Œ ๊ฐ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์กฐ๊ฑด๊ณผ ๋งŒ์กฑํ•˜์ง€ ์•Š์•˜์„ ๊ฒฝ์šฐ ์ถœ๋ ฅํ•  ๋ฉ”์‹œ์ง€๋ฅผ ์„ค์ •ํ–ˆ๋‹ค.

@Getter
@Setter
@NoArgsConstructor
@ToString
public class Course {
	@Range(min=2018, max=2021, message="It's not a valid course year")
	private int year;    // ์ˆ˜๊ฐ•๋…„๋„
	
	@Range(min=1, max=2, message="It's not a valid semester")
	private int semester;    // ํ•™๊ธฐ
	
	@NotEmpty(message="Class name cannot be empty")
	private String className;    // ๊ต๊ณผ๋ชฉ๋ช…
	
	@NotEmpty(message="Classification cannot be empty")
	private String classification;    // ๊ต๊ณผ๊ตฌ๋ถ„
	
	@NotEmpty(message="Professor name cannot be empty")
	private String professor;    // ๋‹ด๋‹น๊ต์ˆ˜
	
	@Range(min=1, max=3, message="It's not a valid credits")
	private int credits;    // ํ•™์ 
}

5. DB ์กฐํšŒ

DB์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” ํŠธ๋žœ์žญ์…˜ ๊ฐ์ฒด์ธ CoruseDao.java์— ์ž‘์„ฑ๋œ ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์กฐํšŒํ•˜๋„๋ก ํ•˜์˜€๋‹ค.

@Repository
public class CourseDao {
    private JdbcTemplate jdbcTemplate;

    @Autowired
    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
    
    public List<Course> getSummary() {  // ํ•™๋…„/ํ•™๊ธฐ๋ณ„ ์ด์ˆ˜ ํ•™์  ์ •๋ณด ์กฐํšŒ
        String sqlStatement = "select ์ˆ˜๊ฐ•๋…„๋„, ํ•™๊ธฐ, sum(ํ•™์ ) from courses GROUP BY ์ˆ˜๊ฐ•๋…„๋„, ํ•™๊ธฐ ORDER BY ์ˆ˜๊ฐ•๋…„๋„, ํ•™๊ธฐ";
        return jdbcTemplate.query(sqlStatement, new RowMapper<Course>() {
            @Override
            public Course mapRow(ResultSet rs, int rowNum) throws SQLException {
                Course summary = new Course();
                summary.setYear(rs.getInt("์ˆ˜๊ฐ•๋…„๋„"));
                summary.setSemester(rs.getInt("ํ•™๊ธฐ"));
                summary.setCredits(rs.getInt("sum(ํ•™์ )"));			
                return summary;
           }	
        });
    }

    // ํŠน์ • ํ•™๊ธฐ์— ์ˆ˜๊ฐ•ํ•œ ๊ฐ•์˜ ์ •๋ณด ์กฐํšŒ
    public List<Course> getSemesterCourses(int year, int semester) {  
        String sqlStatement = "select * from courses where ์ˆ˜๊ฐ•๋…„๋„=? and ํ•™๊ธฐ=?";
        return jdbcTemplate.query(sqlStatement, new Object[] {year, semester}, new RowMapper<Course>() {

            @Override
            public Course mapRow(ResultSet rs, int rowNum) throws SQLException {
                Course course = new Course();
                course.setYear(rs.getInt("์ˆ˜๊ฐ•๋…„๋„"));
                course.setSemester(rs.getInt("ํ•™๊ธฐ"));
                course.setClassName(rs.getString("๊ต๊ณผ๋ชฉ๋ช…"));
                course.setClassification(rs.getString("๊ต๊ณผ๊ตฌ๋ถ„"));
                course.setProfessor(rs.getString("๋‹ด๋‹น๊ต์ˆ˜"));
                course.setCredits(rs.getInt("ํ•™์ "));	
                return course;
            }	
        });
    }
    public int getTotalCredits() {    // ์ด์ˆ˜ ์ด ํ•™์  ๊ณ„์‚ฐ
        String sqlStatement = "select sum(ํ•™์ ) from courses";
        return jdbcTemplate.queryForObject(sqlStatement, Integer.class);
    }
    
    public boolean insert(Course insertCourse) {  // DB์— ์ˆ˜๊ฐ•์‹ ์ฒญ ์ •๋ณด ์‚ฝ์ž…
    	int year = insertCourse.getYear();
    	int semester = insertCourse.getSemester();
    	String className = insertCourse.getClassName();
    	String classification = insertCourse.getClassification();
    	String professor = insertCourse.getProfessor();
    	int credits = insertCourse.getCredits();
    	
    	String sqlStatement = "insert into registrations (๋…„๋„, ํ•™๊ธฐ, ๊ต๊ณผ๋ชฉ๋ช…, ๊ต๊ณผ๊ตฌ๋ถ„, ๋‹ด๋‹น๊ต์ˆ˜, ํ•™์ ) values (?,?,?,?,?,?)";
    	
    	return (jdbcTemplate.update(sqlStatement, new Object[] {year, semester, className, classification, professor, credits}) == 1);
    }
    
    public List<Course> getRegisterCourses() {    // ์ˆ˜๊ฐ•์‹ ์ฒญ ๋‚ด์—ญ ์กฐํšŒ
    	String sqlStatement = "select * from registrations";
    	return jdbcTemplate.query(sqlStatement, new RowMapper<Course>() {

    	    @Override
	    public Course mapRow(ResultSet rs, int rowNum) throws SQLException {
	        Course registerCourse = new Course();
               registerCourse.setYear(rs.getInt("๋…„๋„"));
               registerCourse.setSemester(rs.getInt("ํ•™๊ธฐ"));
               registerCourse.setClassName(rs.getString("๊ต๊ณผ๋ชฉ๋ช…"));
               registerCourse.setClassification(rs.getString("๊ต๊ณผ๊ตฌ๋ถ„"));
               registerCourse.setProfessor(rs.getString("๋‹ด๋‹น๊ต์ˆ˜"));
               registerCourse.setCredits(rs.getInt("ํ•™์ "));	
               return registerCourse;
          }	
    	});
    }
}

6. ์„œ๋น„์Šค

CourseService.java์—์„œ๋Š” CourseDao.java์—์„œ ์กฐํšŒํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ž‘์„ฑํ•ด์„œ CourseController.java์—์„œ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ค€๋‹ค.

@Service
public class CourseService {

	@Autowired
	private CourseDao courseDao;
	
       // ํ•™๋…„/ํ•™๊ธฐ๋ณ„ ์ด์ˆ˜ ํ•™์  ์ •๋ณด ์กฐํšŒ
	public List<Course> getTakenSummary() {
             return courseDao.getSummary();
       }

       // ์ด์ˆ˜ ์ด ํ•™์  ๊ณ„์‚ฐ
	public int getTotalTakenCredits() {
             return courseDao.getTotalCredits();
       }
	
       // ํŠน์ • ํ•™๊ธฐ์— ์ˆ˜๊ฐ•ํ•œ ๊ฐ•์˜ ์ •๋ณด ์กฐํšŒ
	public List<Course> getSemesterCourses(int year, int semester) {
		return courseDao.getSemesterCourses(year, semester);
	}

       // DB์— ๊ฐ•์˜ ์ •๋ณด ์‚ฝ์ž…
	public void insert(Course course) {    
		courseDao.insert(course);
	}

       // ์ˆ˜๊ฐ•์‹ ์ฒญ ๊ฐ•์˜ ๋‚ด์—ญ ์กฐํšŒ
       public List<Course> getRegisterCourses() {
		return courseDao.getRegisterCourses();
	}

}

7. ์ปจํŠธ๋กค๋Ÿฌ

์š”์ฒญ URL์„ ๋งคํ•‘ํ•˜๋Š” CourseController๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•จ์œผ๋กœ์จ mapping๋œ URL ํŽ˜์ด์ง€์—์„œ DB์— ์ €์žฅ๋œ ์ •๋ณด๋ฅผ ์กฐํšŒํ•ด์„œ ๊ฐ€์ ธ์˜จ ์ •๋ณด๋ฅผ ๋ณ€์ˆ˜์— ์ €์žฅํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

@Controller
public class CourseController {
    @Autowired
    private CourseService courseService;
	
    @RequestMapping("/summary")  // ํ•™๊ธฐ๋ณ„ ์ด์ˆ˜ ํ•™์  ์กฐํšŒ ํŽ˜์ด์ง€
    public String showSummary(Model model) {		
        List<Course> summaries = courseService.getTakenSummary();  // ํ•™๊ธฐ๋ณ„ ์ทจ๋“ ํ•™์ 
        model.addAttribute("summaries", summaries);
        int totalCredits = courseService.getTotalTakenCredits();  // ์ด ์ด์ˆ˜ ํ•™์ 
        model.addAttribute("totalCredits", totalCredits);
        return "summary";
    }
	
    // ํ•™๊ธฐ ์ •๋ณด๋ฅผ ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„ ํ•ด๋‹น ํ•™๊ธฐ์˜ ์ˆ˜๊ฐ• ๋‚ด์—ญ ํŽ˜์ด์ง€๋กœ ๋งคํ•‘
    @RequestMapping("/details/{semesterInfo}")
    public String showDetails(@PathVariable String semesterInfo, Model model) {
        int year = Integer.parseInt(semesterInfo.split("-")[0]);
        int semester = Integer.parseInt(semesterInfo.split("-")[1]);
        List<Course> courses = courseService.getSemesterCourses(year, semester);
        model.addAttribute("courses", courses);	
        return semesterInfo;
    }
	
    @RequestMapping("/register")  // ์ˆ˜๊ฐ•์‹ ์ฒญ ํŽ˜์ด์ง€
    public String registerCourse(Model model) {
        model.addAttribute("course", new Course());
        return "register";
    }
	
    // ์ˆ˜๊ฐ•์‹ ์ฒญ ํŽ˜์ด์ง€์—์„œ ํผ ์ „์†ก(submit) ์‹œ
    @RequestMapping(value="/doRegister", produces="text/plain;charset=UTF-8")
    public String doRegister(Model model, @Valid Course course, BindingResult result) {
        if (result.hasErrors()) {  // ์ˆ˜๊ฐ•์‹ ์ฒญ ๋‚ด์—ญ์— ์˜ค๋ฅ˜๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ
            System.out.println("== ์ˆ˜๊ฐ•์‹ ์ฒญ ์˜ค๋ฅ˜ ==");
            List<ObjectError> errors = result.getAllErrors();
			
            for (ObjectError error : errors) {
                System.out.println(error.getDefaultMessage());
            }
            return "register";  // ๋‹ค์‹œ ์ˆ˜๊ฐ•์‹ ์ฒญ ํŽ˜์ด์ง€์—์„œ ์ž…๋ ฅ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ํ•จ
        }
        courseService.insert(course);  // ์˜ค๋ฅ˜๊ฐ€ ์—†๋‹ค๋ฉด DB์— ์ €์žฅํ•˜๊ณ 
        return "successRegistration";  // ์ˆ˜๊ฐ•์‹ ์ฒญ ์™„๋ฃŒ ํŽ˜์ด์ง€๋กœ ์ด๋™
    }
    @RequestMapping("/viewRegistration")  // ์ˆ˜๊ฐ•์‹ ์ฒญ ๋‚ด์—ญ ํŽ˜์ด์ง€
    public String viewRegistration(Model model) {
        List<Course> courses = courseService.getRegisterCourses();
        model.addAttribute("courses", courses);
		
        return "viewRegistration";
    }
}

8. ๋ฉ”๋‰ด

8.1 ํ•™๋…„/ํ•™๊ธฐ๋ณ„ ์ด์ˆ˜ ์ด ํ•™์ 

ํ•™๊ธฐ ๋ณ„ ์ด์ˆ˜ ํ•™์  ์กฐํšŒ(summary.jsp) ๋ฉ”๋‰ด๋ฅผ ๋“ค์–ด๊ฐ€๋ฉด CourseController.java์—์„œ /summary์˜ summaries์™€ totalCredits ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๋„, ํ•™๊ธฐ, ์ทจ๋“ํ•™์ ๊ณผ ์ด๊ณ„๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งํฌ์—๋Š” ์—ฐ๋„์™€ ํ•™๊ธฐ ์ •๋ณด๋ฅผ ๋„ฃ์–ด ๊ฐ๊ฐ์˜ ๋‹ค๋ฅธ ํŽ˜์ด์ง€๋กœ ์—ฐ๊ฒฐ๋˜๋„๋ก ํ–ˆ๋‹ค.

<table class="table" border="1">
  ...
  <tfoot>
    <tr><th>์ด๊ณ„</th><th></th>
        <th><c:out value="${ totalCredits }"></c:out></th><th></th></tr>
  </tfoot>
  <tbody>
    <c:forEach var="summary" items="${ summaries }">
      <tr>
        <td><c:out value="${ summary.year }"></c:out></td>
        <td><c:out value="${ summary.semester }"></c:out></td>
        <td><c:out value="${ summary.credits }"></c:out></td>
        <td><a href="${ pageContext.request.contextPath }/details/${ summary.year }-${summary.semester}">๋งํฌ</a></td>
      </tr>
    </c:forEach>
</tbody>
</table>

๊ฒฐ๊ณผ๋ฌผ

8.2 ํ•™๊ธฐ ๋ณ„ ์ˆ˜๊ฐ• ๋‚ด์—ญ

ํ•™๊ธฐ ๋ณ„ ์ด์ˆ˜ ํ•™์  ์กฐํšŒ ๋ฉ”๋‰ด(summary.jsp)์—์„œ โ€˜์ƒ์„ธ๋ณด๊ธฐโ€™์˜ ๋งํฌ๋ฅผ ํด๋ฆญํ•˜๋ฉด ๊ฐ ํ•™๊ธฐ ๋ณ„ ์ˆ˜๊ฐ• ๋‚ด์—ญ์„ CourseController.java์˜ /details/{semesterInfo}(์˜ˆ: 2020๋…„ 1ํ•™๊ธฐ๋Š” /details/2020-1)๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ํ•™๊ธฐ course๋“ค์„ ๊ฐ€์ ธ์™€ ์ถœ๋ ฅํ•œ๋‹ค.

<table class="table" border="1">
    <tbody>
        <c:forEach var="course" items="${ courses }">
            <tr>
                <td><c:out value="${ course.year }"></c:out></td>
                <td><c:out value="${ course.semester }"></c:out></td>
                <td class="className"><c:out value="${ course.className }"></c:out></td>
                <td class="classifcation">
                    <c:out value="${ course.classification }"></c:out></td>
                <td class="professor"><c:out value="${ course.professor }"></c:out></td>
                <td><c:out value="${ course.credits }"></c:out></td>
            </tr>
        </c:forEach>
    </tbody>
</table>

๊ฒฐ๊ณผ๋ฌผ

8.3 ์ˆ˜๊ฐ•์‹ ์ฒญ ํผ

์ˆ˜๊ฐ• ์‹ ์ฒญ ๋ฉ”๋‰ด์—์„œ ์›น ํผ(form)์„ ํ†ตํ•ด 2021๋…„ 1ํ•™๊ธฐ์— ์‹ ์ฒญํ•  ๊ณผ๋ชฉ์„ ์ž…๋ ฅํ•œ๋‹ค. 2021๋…„๊ณผ 1ํ•™๊ธฐ๋ผ๋Š” ์ •๋ณด๋Š” ์ˆ˜๊ฐ•์‹ ์ฒญ ์‹œ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•  ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ํŒ๋‹จํ•˜์—ฌ hidden์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์„œ ์ „์†กํ•˜๋„๋ก ํ•˜์˜€๋‹ค. ๋‚˜๋จธ์ง€๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๊ฒ€์ฆ ์ž‘์—…์„ ํ•˜๋Š”๋ฐ ์ผ๋ถ€ ๋น„์›Œ์ง„ ์นธ๋“ค์ด ์žˆ๊ณ  ํ•™์ ์€ 1~3ํ•™์ ์ด ์œ ํšจํ•œ ๊ฐ’์ธ๋ฐ 0์ด ์ž…๋ ฅ๋˜์–ด ์žˆ์–ด ์˜ค๋ฅ˜๊ฐ€ ๋‚ฌ์œผ๋ฏ€๋กœ CourseController.java์˜ /doRegister์—์„œ ๋ช…์‹œํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋‹ค์‹œ ์ˆ˜๊ฐ•์‹ ์ฒญ ํŽ˜์ด์ง€(register.jsp)๋กœ ๋Œ์•„์™€ ์‚ฌ์šฉ์ž๊ฐ€ ์–‘์‹์— ๋งž๊ฒŒ ํผ์„ ์ฑ„์šธ ์ˆ˜ ์žˆ๋„๋ก ์žฌ ์š”์ฒญํ•˜๊ณ  ์žˆ๋‹ค.

<sf:form method="post" action="${ pageContext.request.contextPath }/doRegister"
         modelAttribute="course" acceptCharset="UTF-8">
    <table class="formtable">
        <sf:input class="control" type="hidden" value="2021" path="year" />
        <sf:input class="control" type="hidden" value="1" path="semester" />
        <tr>
            <td class="label">๊ต๊ณผ๋ชฉ๋ช…</td>
            <td><sf:input class="control" type="text" path="className" /><br/>
                <sf:errors path="className" class="error" /> </td>
        </tr>
        <tr>
            <td class="label">๊ต๊ณผ๊ตฌ๋ถ„</td>
            <td><sf:input class="control" type="text" path="classification" /><br/>
                <sf:errors path="classification" class="error" /></td>
        </tr>
        <tr>
            <td class="label">๋‹ด๋‹น๊ต์ˆ˜</td>
            <td><sf:input class="control" type="text" path="professor" /><br/>
                <sf:errors path="professor" class="error" /></td>
        </tr>
        <tr>
            <td class="label">ํ•™์ </td>
            <td><sf:input class="control" type="text" path="credits" /><br/>
                <sf:errors path="credits" class="error" /></td>
        </tr>
        <tr>
            <td></td>
            <td><input type="submit" value="์ˆ˜๊ฐ•์‹ ์ฒญ" /></td>
        </tr>
    </table>
</sf:form>

๋ชจ๋“  ํผ์„ ์œ ํšจํ•œ ๊ฐ’์œผ๋กœ ์ฑ„์› ์„ ๊ฒฝ์šฐ์—๋Š” ์ˆ˜๊ฐ•์‹ ์ฒญ์ด ์ •์ƒ์ ์œผ๋กœ ์ง„ํ–‰๋˜์–ด CourseController.java์˜ /doRegister์—์„œ ๋ช…์‹œํ•œ๋Œ€๋กœ ์ˆ˜๊ฐ•์‹ ์ฒญํ•œ ๊ฐ•์ขŒ ์ •๋ณด๋ฅผ DB์— ์ €์žฅํ•˜๊ณ  ์ˆ˜๊ฐ•์‹ ์ฒญ ์™„๋ฃŒ(successRegistration.jsp) ํŽ˜์ด์ง€๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.

๊ฒฐ๊ณผ๋ฌผ

8.4 ์ˆ˜๊ฐ•์‹ ์ฒญ ๋‚ด์—ญ ์กฐํšŒ

์ˆ˜๊ฐ•์‹ ์ฒญ ์กฐํšŒ(viewRegistration.jsp) ๋ฉ”๋‰ด์—์„œ๋Š” CourseController.java์˜ /viewRegistration์—์„œ ์ˆ˜๊ฐ•์‹ ์ฒญ ๊ฐ•์˜ ์ •๋ณด๋ฅผ ์กฐํšŒํ•˜์—ฌ 2021๋…„ 1ํ•™๊ธฐ ์ˆ˜๊ฐ• ์‹ ์ฒญ ๋‚ด์—ญ์„ ์ถœ๋ ฅํ•œ๋‹ค.

<c:forEach var="course" items="${ courses }">
    <tr>
        <td><c:out value="${ course.year }"></c:out></td>
        <td><c:out value="${ course.semester }"></c:out></td>
        <td class="className"><c:out value="${ course.className }"></c:out></td>
        <td class="classifcation"><c:out value="${ course.classification }"></c:out></td>
        <td class="professor"><c:out value="${ course.professor }"></c:out></td>
        <td><c:out value="${ course.credits }"></c:out></td>
    </tr>
</c:forEach>

๊ฒฐ๊ณผ๋ฌผ