스프링은 설정이 너무 빡세다.. crud는 서블릿이나 스프링이랑 별다르지 않지만..
프레임워크는 잘익혀두는것이 중요하다
0.1. Model 객체란
- Model 객체는 Controller 에서 생성된 데이터를 담아 View 로 전달할 때 사용하는 객체.
- Model 객체는 스프링이 제공하는 모델을 사용하는 것이므로 따로 반환을 해주지 않아도 된다.
- 생명주기: ModelAndViewContainer가 생성될 때 함께 만들어진다. Model은 Map이라고 보면 된다.
- 이미 만들어져있는 model을 가져와서 컨트롤러의 파라미터에 전달해주기 때문에 런타임에서는 model 객체를 사용하게 됩니다.
Model 객체 : 속성 값을 담아두는 객체ModelAndView 객체 : 속성 값 뿐만 아니라 View 이름도 담아둘 수 있는 객체
0.1.1. 사용방법
addAttribute("key", "value") 메서드를 이용해 view에 전달할 데이터를 key, value형식으로 전달할 수 있다.
addAttribute는 Map의 put과 같은 기능과 같아서 이를 통해 해당 모델에 원하는 속성과 그것에 대한 값을 주어 전달할 뷰에 데이터를 전달할 수 있습니다.
Spring에서 Controller의 메서드를 작성할 때는 특별하게 Model이라는 타입을 파라미터로 지정할 수 있습니다.
0.1.2. 사용 예시
<code />
@Controller
public class TestController {
@GetMapping("/test")
public void testMethod(Model model) {
String test = "model interface";
model.addAttribute("test", test);
}
}
Controller이노테이션을 생성한후에 @GetMapping하여 url을 "/test/"로, 메서드에 매개변수를 Model 타입의 model변수를 선언했습니다.
String 타입의 변수 test를 선언하고, model.addAttribute를 통해 view에 데이터를 전달 했습니다.
<code />
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html><head><meta charset="EUC-KR"><title>Insert title here</title></head><body><h1>Test</h1>
<h2>${test}</h2></body></html>
처음 Controller에 Model타입의 model의 변수 선언을 통해 ${test}부분의 test는 model.addAttribute("test", test)로 인해 치환되어 model interface가 출력되었습니다.
0.2. @ModelAttribute
요청 파라미터를 받아서 필요한 객체를 만들고 그 객체에 값을 넣어주어야 한다.
보통 @RequestParam을 사용해서 값을 받고, set을 사용해서 값을 넣어주곤 하지만 이 과정을 자동화시켜주는 것이 @ModelAttribute이다.
@ModelAttribute를 사용하지 않을 때 (model도 같이 사용해보기)
<code />
public void item(@RequestParam String name,
@RequestParam int price,
Model model){
Item item = new Item();
item.setName(name);
item.setPrice(price);
model.addAttribute("item", item);
}
이렇게 @RequestParam으로 일일이 받아서 set을 해줘야 값이 저장된다. 하지만 @ModelAttribute를 사용하면 간단해진다.
modelAttribute 사용
<code />
public void modelAttributeEx(@ModelAttribute Item item, Model model){
model.addAttribute("item", item);
}
이렇게 간결하게 사용 가능하다.
@ModelAttribute가 실행되는 원리를 설명하자면 요청 파라미터의 이름으로 Item 객체의 프로퍼티를 찾는다.
그리고 해당 프로퍼티의 setter를 호출해서 파라미터 값을 입력한다.
하지만 저기에서 model.addAttribute도 생략 가능하다. @ModelAttribute를 사용함으로써 model에도 자동적으로 객체가 추가 되기 때문이다.
@ModelAttribute 어노테이션도 생략가능하다.
<code />
public void ModelAttributeEx(Item item, Model model){}
최종적으로 위와 같이 쓸 수 있다.
<code />
// FormItemController - 추가
@ModelAttribute("regions")
public Map<String, String> regions() {
Map<String, String> regions = new LinkedHashMap<>();
regions.put("SEOUL", "서울");
regions.put("BUSAN", "부산");
regions.put("JEJU", "제주");
return regions;
}
@ModelAttribute의 특별한 사용법
등록 폼, 상세화면, 수정 폼에서 모두 서울, 부산, 제주라는 체크 박스를 반복해서 보여주어야 한다. 이렇게 하려면 각각의 컨트롤러에서 model.addAttribute(...) 을 사용해서 체크 박스를 구성하는 데이터를 반복해서 넣어주어야 한다.
@ModelAttribute 는 이렇게 컨트롤러에 있는 별도의 메서드에 적용할 수 있다.
이렇게하면 해당 컨트롤러를 요청할 때 regions 에서 반환한 값이 자동으로 모델( model )에 담기게 된다.
물론 이렇게 사용하지 않고, 각각의 컨트롤러 메서드에서 모델에 직접 데이터를 담아서 처리해도 된다
@ModelAttribute("regions") 가 있는 컨트롤러를 호출할때 이 표시가 붙은 메서드가 model.addAttribute()로 이름은 ""안에 있는 것("regions")으로 하여 자동으로 모델에 담긴다.
0.2.1. @ModelAttribute
@ModelAttribute는 HTTP 요청의 파라미터를 객체로 바인딩하기 위해 사용된다.
컨트롤러 메서드의 파라미터 앞에 @ModelAttribute를 사용하여 해당 파라미터를 객체로 변환하고, 이를 컨트롤러 메서드 내에서 사용할 수 있다.
또한, 이 어노테이션을 사용하면 해당 객체를 자동으로 뷰로 전달된다.
주로 HTML 폼 데이터를 처리할 때 사용된다.
객체 클래스에 @Setter 어노테이션이나 Setter가 필요하다.
예시
<code />
@PostMapping("/user")
public String createUser(@ModelAttribute User user) {
// user 객체를 사용하여 사용자 생성 로직 수행return "userCreated";// 뷰 이름 반환
}
0.2.2. @RequestBody
@RequestBody는 HTTP 요청의 본문(body)에 담긴 데이터를 객체로 바인딩하기 위해 사용된다.
컨트롤러 메서드의 파라미터 앞에 @RequestBody를 사용하여 해당 파라미터를 요청 본문의 데이터를 변환하여 객체로 받아올 수 있다.
주로 JSON, XML, 또는 기타 데이터 형식의 요청을 처리할 때 사용된다.
예시
<code />
@PostMapping("/user")
public String createUser(@RequestBody User user) {
// user 객체를 사용하여 사용자 생성 로직 수행return "userCreated";// 뷰 이름 반환
}
바인딩 종류 특징
@ModelAttribute | - 변환이 아닌 바인딩을 시키기 때문에 변수들의 Setter 함수가 없으면 저장되지 않는다.- @ModelAttribute를 사용하여 HTTP Body에 내용을 담기 위해서는 multipart/form-data 형식으로 전송해야 한다.- HTTP 파라미터들은 Setter를 통해 일대일 객체에 바인딩하기 위해 사용된다.- @ModelAttribute에는 매핑시키는 파라미터의 타입이 객체의 타입과 일치하는지를 포함한 다양한 검증(Validation) 작업이 추가적으로 진행된다. | |||
@RequestParam | - @RequestParam은 1개의 HTTP 요청 파라미터를 받기 위해서 사용된다. | |||
@RequestBody | - @RequestBody로 받은 데이터는 Spring에서 관리하는 MessageConverter들 중 하나인 MappingJackson2 HttpMessageConverter를 통해 Java 객체로 변환된다.- Spring은 메시지를 변환하는 과정에서 객체의 기본 생성자를 통해 객체를 생성하고 내부적으로 Reflection을 사용해 값을 할당하므로 @RequestBody에는 값을 주입하기 위한 생성자나 Setter가 필요 없다. |
1. 1. @RequestParam
1개의 HTT 요청 파라미터를 받기 위해서 사용한다.
1.0.1. 예제
<code />
@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam String id) {
return "ID: " + id;
}
- @RequestParam을 이용해서 id 쿼리 매개변수를 추출한다.
1.0.2. 속성
1.0.3. 1. name
- 위의 예제에서는 변수 이름과 매개변수 이름이 동일한데, 이를 다르게 설정할 수도 있다.
<code />
@PostMapping("/api/foos")
@ResponseBody
public String addFoo(@RequestParam(name = "id") String fooId, @RequestParam String name) {
return "ID: " + fooId + " Name: " + name;
}
- 매개변수 앞에 @RequestParam(name = "id")를 추가해주면 된다.
1.0.4. 2. required & defaultValue
- @RequestParam은 요청에 매개변수가 필수적이다. → @RequestParam(required = true)가 기본 설정이다.
- 해당 파라미터가 전송되지 않으면 400 Error을 반환한다.
- @RequestParam(required = false)로 설정하면 파라미터가 없어도 된다. → 이 경우 매개변수가 null로 바인딩된다.
- defaultValue를 통해 기본값을 설정할 수도 있다.
<code />
@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam(required = false, defaultValue = "0") String id) {
return "ID: " + id;
}
2. 2. @RequestBody
클라이언트가 전송하는 Json(application/json) 형태의 HTTP Body 내용을 Java Object로 변환해준다.
- 그렇기 때문에 Body가 존재하지 않는 Get 메소드에서 사용하면 에러가 발생한다.
- HTTP 요청 본문 데이터는 Spring에서 제공하는 HttpMessageConverter를 통해 타입에 맞는 객체로 변환된다.
- @RequestBody를 사용할 객체는 필드를 바인딩할 생성자나 setter 메서드가 필요 없다.
3. 3. @ModelAttribute
클라이언트가 전송하는 multipart/form-data 형태의 HTTP Body 내용과 HTTP 파라미터 데이터를 Setter를 통해 Java 객체에 매핑한다.
- 객체의 필드에 접근해서 데이터를 바인딩할 수 있는 생성자 혹은 setter 메서드가 필요하다.
- Query String 및 Form 형식이 아닌 데이터는 처리할 수 없다.
📌 정리
- RequestParam
- 1개의 HTTP 파라미터를 얻기 위해 사용한다.
- 매개변수가 필수적으로 필요하다.
- 매개변수가 전달되지 않은 경우 400 에러가 발생한다.
- 설정을 통해 바꿀 수 있다.
- RequestBody
- Json으로 받은 HTTP Body 데이터를 HttpMessageConverter를 통해 변환한다.
- setter가 없어도 된다.
- ModelAttribute
- multipart/form-data 형태의 HTTP Body 내용과 HTTP 파라미터들을 Setter를 통해 1대 1로 객체에 바인딩시킨다.
- 매개변수의 바인딩을 받는 필드는 setter 함수가 있어야 한다.
터셉터 ( Interceptor )
Interceptor란 컨트롤러에 들어오는 요청 HttpRequest와 컨트롤러가 응답하는 HttpResponse를 가로채는 역할을 합니다.
인터셉터는 관리자만 접근할 수 있는 관리자 페이지에 접근하기 전에 관리자 인증을 하는 용도로 활용될 수 있습니다.
이번 주제에서는 컨트롤러에서 인터셉터를 활용하여 접근 권한을 해보고, 기술 침투적인 HttpSession을 제거하여 세션을 처리하려 합니다.
인터셉터는 Servlet의 앞, 뒤에서 HttpRequest, HttpResponse을 가로채는 Filter와 그 역할이 유사한데, Filter와 Interceptor는 분명히 다릅니다.
https://t1.daumcdn.net/cfile/tistory/992590395ABF406F18
Filter와 Interceptor의 차이
1. 호출 시점
Filter는 DispatcherServlet이 실행되기 전 , Interceptor는 DispatcherServlet이 실행된 후
2. 설정 위치
Filter는 web.xml , Interceptor는 spring-servlet.xml
3. 구현 방식
Filter는 web.xml에서 설정을 하면 구현이 가능하지만, Interceptor는 설정은 물론 메서드 구현이 필요합니다.
이 글에서는 인터셉터 환경 설정 및 기본적인 사용 방법과 인터셉터를 활용하여 로그인을 처리하는 예제를 구현하도록 하겠습니다.
환경 설정
spring-servlet.xml
<code />
<!-- Interceptors --><mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.victolee.interceptor.MyInterceptor"/> </mvc:interceptor></mvc:interceptors>
모든 요청을 가로채서( Interceptor ) com.victolee.interceptor 패키지에 있는 MyInterceptor 객체를 실행하겠다는 의미입니다.
테스트
Interceptor를 구현하는 방법은 2가지가 있는데, HandlerInterceptor 인터페이스를 구현하는 방법과 HandlerInterceptorAdapter 클래스를 상속 받는 방법이 있습니다.
HandlerInterceptor 인터페이스 구현
<java />
public class MyInterceptor implements HandlerInterceptor
{ // controller로 보내기 전에 처리하는 인터셉터 // 반환이 false라면 controller로 요청을 안함
// 매개변수 Object는 핸들러 정보를 의미한다. ( RequestMapping , DefaultServletHandler )
@Override public boolean preHandle( HttpServletRequest request, HttpServletResponse response,
Object obj) throws Exception { System.out.println("MyInterCeptor - preHandle"); return false; } // controller의 handler가 끝나면 처리됨 @Override public void postHandle( HttpServletRequest request, HttpServletResponse response, Object obj, ModelAndView mav) throws Exception { } // view까지 처리가 끝난 후에 처리됨 @Override public void afterCompletion( HttpServletRequest request, HttpServletResponse response, Object obj, Exception e) throws Exception { } }
<java />
```java
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
h1 {
text-align: center;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
tr:nth-child(even) {
background-color: #f2f2f2;
}
tr:hover {
background-color: #ddd;
}
</style>
</head>
<body>
<form method="post" action="/myboard/updateProcess">
<table border="1">
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>내용</th>
<th>등록일자</th>
<th>수정일자</th>
</tr>
</thead>
<tbody>
<c:forEach items="${myBoarddetail}" var="result">
<tr>
<td>
<input type="hidden" name="atclSn" value="${result.atclSn}">
</td>
<td>
<input type="text" name="atclTitle" value="${result.atclTitle}">
</td>
<td>${result.regNm}</td>
<td>
<textarea name="atclCts" rows="4" cols="50">${result.atclCts}</textarea>
</td>
<td>${result.regDttm}</td>
<td>${result.modDttm}</td>
<td>
<button type="submit">수정</button>
</td>
</tr>
</c:forEach>
</tbody>
</table>
<a href="<c:url value='/myboard/list' />">목록으로 돌아가기</a>
</body>
</html>
```
<java />
package egovframework.edutrack.modules.myboard.service.impl;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
import org.springframework.web.multipart.MultipartFile;
import egovframework.edutrack.modules.myboard.service.MyBoardVO;
import egovframework.rte.psl.dataaccess.mapper.Mapper;
@Mapper("myBoardMapper")
public interface MyBoardMapper {
public List<MyBoardVO> list(MyBoardVO vo);
public List<MyBoardVO> search(MyBoardVO myboardVO);
public void delete(String atclSn);
public void update(MyBoardVO myBoard);
public void create(MyBoardVO myBoard);
public List<MyBoardVO> getdetail(String atclSn);
}
<java />
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="egovframework.edutrack.modules.myboard.service.impl.MyBoardMapper">
<select id="list" parameterType="myBoardVO" resultType="myBoardVO">
SELECT ATCL_SN
, ATCL_TITLE
, REG_NM
, REG_DTTM
FROM tb_my_board
</select>
<select id="search" parameterType="myBoardVO" resultType="myBoardVO">
SELECT ATCL_SN, ATCL_TITLE, REG_NM, REG_DTTM
FROM tb_my_board
WHERE
<choose>
<when test="searchType == 'title'">
ATCL_TITLE LIKE '%' #{keyword} '%'
</when>
<when test="searchType == 'writer'">
REG_NM LIKE '%' #{keyword} '%'
</when>
<otherwise>
ATCL_TITLE LIKE '%' #{keyword} '%' OR REG_NM LIKE '%' #{keyword} '%'
</otherwise>
</choose>
ORDER BY ATCL_SN DESC
</select>
<insert id="create" parameterType="myBoardVO">
INSERT INTO tb_my_board (ATCL_SN, ATCL_TITLE, ATCL_CTS)
VALUES (#{atclSn}, #{atclTitle}, #{atclCts})
</insert>
<select id="getdetail" parameterType="String" resultType="myBoardVO">
SELECT ATCL_SN, ATCL_TITLE, ATCL_CTS, REG_NM, REG_DTTM, MOD_DTTM
FROM tb_my_board
WHERE ATCL_SN = #{atclSn}
</select>
<update id="update" parameterType="myBoardVO">
UPDATE tb_my_board
SET ATCL_TITLE = #{atclTitle},
ATCL_CTS = #{atclCts}
WHERE ATCL_SN = #{atclSn}
</update>
<delete id="delete" parameterType="String">
DELETE FROM tb_my_board
WHERE ATCL_SN = #{atclSn}
</delete>
</mapper>
<java />
package egovframework.edutrack.modules.myboard.service;
import java.util.List;
import org.springframework.web.multipart.MultipartFile;
public interface MyBoardService {
public List<MyBoardVO> list(MyBoardVO vo) throws Exception;
public void delete(String atclSn);
public void update(MyBoardVO myBoard);
public void create(MyBoardVO myBoard);
public List<MyBoardVO> search(MyBoardVO vo);
public List<MyBoardVO> getdetail(String atclSn);
}
<java />
package egovframework.edutrack.modules.myboard.service;
import egovframework.edutrack.comm.service.DefaultVO;
public class MyBoardVO extends DefaultVO {
private String atclSn;
private String atclTitle;
private String atclCts;
private String regNo;
private String regNm;
private String regDttm;
private String modNo;
private String modNm;
private String modDttm;
private String keyword;
public String getAtclSn() {
return atclSn;
}
public void setAtclSn(String atclSn) {
this.atclSn = atclSn;
}
public String getAtclTitle() {
return atclTitle;
}
public void setAtclTitle(String atclTitle) {
this.atclTitle = atclTitle;
}
public String getAtclCts() {
return atclCts;
}
public void setAtclCts(String atclCts) {
this.atclCts = atclCts;
}
public String getRegNo() {
return regNo;
}
public void setRegNo(String regNo) {
this.regNo = regNo;
}
public String getRegNm() {
return regNm;
}
public void setRegNm(String regNm) {
this.regNm = regNm;
}
public String getRegDttm() {
return regDttm;
}
public void setRegDttm(String regDttm) {
this.regDttm = regDttm;
}
public String getModNo() {
return modNo;
}
public void setModNo(String modNo) {
this.modNo = modNo;
}
public String getModNm() {
return modNm;
}
public void setModNm(String modNm) {
this.modNm = modNm;
}
public String getModDttm() {
return modDttm;
}
public void setModDttm(String modDttm) {
this.modDttm = modDttm;
}
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
}
<java />
package egovframework.edutrack.modules.myboard.service.impl;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.annotation.Resource;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import egovframework.edutrack.modules.myboard.service.MyBoardService;
import egovframework.edutrack.modules.myboard.service.MyBoardVO;
import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
@Service("myBoardService")
public class MyBoardServiceImpl extends EgovAbstractServiceImpl implements MyBoardService {
@Resource(name="myBoardMapper")
private MyBoardMapper myBoardMapper;
@Override
public List<MyBoardVO> list(MyBoardVO vo) throws Exception {
return myBoardMapper.list(vo);
}
@Override
public void update(MyBoardVO myBoard) {
myBoardMapper.update(myBoard);
}
@Override
public void create(MyBoardVO myBoard) {
myBoardMapper.create(myBoard);
}
@Override
public List<MyBoardVO> getdetail(String atclSn) {
return myBoardMapper.getdetail(atclSn);
}
@Override
public void delete(String atclSn) {
myBoardMapper.delete(atclSn);
}
@Override
public List<MyBoardVO> search(MyBoardVO vo) {
return myBoardMapper.search(vo);
}
}
<java />
package egovframework.edutrack.modules.myboard.service.impl;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.annotation.Resource;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import egovframework.edutrack.modules.myboard.service.MyBoardService;
import egovframework.edutrack.modules.myboard.service.MyBoardVO;
import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
@Service("myBoardService")
public class MyBoardServiceImpl extends EgovAbstractServiceImpl implements MyBoardService {
@Resource(name="myBoardMapper")
private MyBoardMapper myBoardMapper;
@Override
public List<MyBoardVO> list(MyBoardVO vo) throws Exception {
return myBoardMapper.list(vo);
}
@Override
public void update(MyBoardVO myBoard) {
myBoardMapper.update(myBoard);
}
@Override
public void create(MyBoardVO myBoard) {
myBoardMapper.create(myBoard);
}
@Override
public List<MyBoardVO> getdetail(String atclSn) {
return myBoardMapper.getdetail(atclSn);
}
@Override
public void delete(String atclSn) {
myBoardMapper.delete(atclSn);
}
@Override
public List<MyBoardVO> search(MyBoardVO vo) {
return myBoardMapper.search(vo);
}
}
<java />
```java
package egovframework.edutrack.modules.myboard.service.impl;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.annotation.Resource;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import egovframework.edutrack.modules.myboard.service.MyBoardService;
import egovframework.edutrack.modules.myboard.service.MyBoardVO;
import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
@Service("myBoardService")
public class MyBoardServiceImpl extends EgovAbstractServiceImpl implements MyBoardService {
@Resource(name="myBoardMapper")
private MyBoardMapper myBoardMapper;
@Override
public List<MyBoardVO> list(MyBoardVO vo) throws Exception {
return myBoardMapper.list(vo);
}
@Override
public void update(MyBoardVO myBoard) {
myBoardMapper.update(myBoard);
}
@Override
public void create(MyBoardVO myBoard) {
myBoardMapper.create(myBoard);
}
@Override
public List<MyBoardVO> getdetail(String atclSn) {
return myBoardMapper.getdetail(atclSn);
}
@Override
public void delete(String atclSn) {
myBoardMapper.delete(atclSn);
}
@Override
public List<MyBoardVO> search(MyBoardVO vo) {
return myBoardMapper.search(vo);
}
}
```
<java />
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
h1 {
text-align: center;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
tr:nth-child(even) {
background-color: #f2f2f2;
}
tr:hover {
background-color: #ddd;
}
</style>
</head>
<body>
<form method="post" action="/myboard/updateProcess">
<table border="1">
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>내용</th>
<th>등록일자</th>
<th>수정일자</th>
</tr>
</thead>
<tbody>
<c:forEach items="${myBoarddetail}" var="result">
<tr>
<td>
<input type="hidden" name="atclSn" value="${result.atclSn}">
</td>
<td>
<input type="text" name="atclTitle" value="${result.atclTitle}">
</td>
<td>${result.regNm}</td>
<td>
<textarea name="atclCts" rows="4" cols="50">${result.atclCts}</textarea>
</td>
<td>${result.regDttm}</td>
<td>${result.modDttm}</td>
<td>
<button type="submit">수정</button>
</td>
</tr>
</c:forEach>
</tbody>
</table>
<a href="<c:url value='/myboard/list' />">목록으로 돌아가기</a>
</body>
</html>
<java />
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
h1 {
text-align: center;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
tr:nth-child(even) {
background-color: #f2f2f2;
}
tr:hover {
background-color: #ddd;
}
</style>
</head>
<form method="post" action="/myboard/createProcess">
<form method="post" action="/myboard/delete/{atclSn}">
<body>
<table border="1">
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>내용</th>
<th>등록일자</th>
<th>수정일자</th>
<th>수정</th>
<th>삭제</th>
</tr>
</thead>
<tbody>
<c:forEach items="${myBoarddetail}" var="result">
<tr>
<td>${result.atclSn}</td>
<td>${result.atclTitle}</td>
<td>${result.regNm}</td>
<td>${result.atclCts}</td>
<td>${result.regDttm}</td>
<td>${result.modDttm}</td>
<td>
<a href="<c:url value='/myboard/edit/${result.atclSn}' />">수정</a>
</td>
<td>
<a href="<c:url value='/myboard/delete/${result.atclSn}' />">삭제</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
<a href="<c:url value='/myboard/list' />">목록으로 돌아가기</a>
</body>
</html>
'취준 note 2023 > spring' 카테고리의 다른 글
스프링 트랜젝션+pagenation (0) | 2023.08.12 |
---|---|
스프링AOP (0) | 2023.08.12 |
스프링 di (0) | 2023.08.12 |
스프링 시큐리티 (0) | 2023.08.11 |
spring master - chap2 스프링빈 의존성 주입(IOC) (0) | 2023.01.23 |