jakarta servlet-api
jakarta servlet.jsp-api
jakarta servlet jstl
구현체 glassfish jstl
compileOnly 'jakarta.servlet:jakarta.servlet-api:6.0.0'
compileOnly 'jakarta.servlet.jsp:jakarta.servlet.jsp-api:3.1.1'
implementation 'jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:3.0.0'
implementation 'org.glassfish.web:jakarta.servlet.jsp.jstl:3.0.1'
spring webmvc -> spring context가 안에 탑재되어있다.


implementation 'org.springframework:spring-webmvc:6.1.10'
mybatis
mybatis-spirng
ojdbc11
lombok
slj4f api
구현체 logback classic
spring-test
spring-jdbc
spring-data jdbc
tomcat jdbc
dependencies {
implementation "org.springframework:spring-webmvc:$springVersion"
implementation "org.springframework:spring-jdbc:$springVersion"
implementation 'org.springframework.data:spring-data-jdbc:3.3.1'
implementation 'org.apache.tomcat:tomcat-jdbc:10.1.25'
runtimeOnly 'com.oracle.database.jdbc:ojdbc11:23.4.0.24.05'
implementation 'org.mybatis:mybatis:3.5.16'
implementation 'org.mybatis:mybatis-spring:3.0.3'
implementation 'org.mindrot:jbcrypt:0.4'
compileOnly 'jakarta.servlet:jakarta.servlet-api:6.0.0'
compileOnly 'jakarta.servlet.jsp:jakarta.servlet.jsp-api:3.1.1'
implementation 'jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:3.0.0'
implementation 'org.glassfish.web:jakarta.servlet.jsp.jstl:3.0.1'
compileOnly 'org.projectlombok:lombok:1.18.34'
annotationProcessor 'org.projectlombok:lombok:1.18.34'
implementation 'org.slf4j:slf4j-api:2.0.13'
implementation 'ch.qos.logback:logback-classic:1.5.6'
testImplementation "org.springframework:spring-test:$springVersion"
testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter'
}
...
...
<servlet><!--서블릿 정의-->
<servlet-name>dispatcher</servlet-name> <!--서블릿 이름 정의-->
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name><!--스프링 설정 위치 지정-->
<param-value><!--두개의 설정 파일 사용-->
configs.MvcConfig <!--Spring MVC와 관련된 설정을 정의하는 클래스-->
configs.ControllerConfig <!--애플리케이션의 컨트롤러를 정의하는 클래스-->
</param-value>
</init-param>
</servlet>
<servlet-mapping><!--서블릿과 URL패턴 매핑-->
<servlet-name>dispatcher</servlet-name> <!--매핑할 서블릿 이름 지정-->
<url-pattern>/</url-pattern><!--서블릿이 매핑될 URL 패턴을 지정-->
</servlet-mapping>
<!--모든 URL 패턴 (/)을 dispatcher 서블릿으로 매핑, 모든 요청이 DispatcherServlet을 통해 처리됨을 의미함-->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern><!--모든 경로를 의미-->
</filter-mapping>
</web-app>

컨테이너를 만들때 설정 class 클래스로 넣어준다
@EnableWebMvc

WebMvc안에 있는 메서드들 많다!

MvcConfig 클래스는 주로 웹 애플리케이션의 MVC 설정을 담당한다 (Model, View, Controller)
@EnableWebMvc 어노테이션을 통해 Spring MVC를 활성화하고 관련 설정들을 제공해준다.@ComponentScan 어노테이션으로 해당 경로 패키지에서 스프링 빈을 검색@Import: 다른 구성 클래스들을 현재 구성 클래스에 포함시키는 역할configureDefaultServletHandling 메서드는 기본 서블릿을 활성화 하여 Spring이 처리하지 않는 요청을 처리하도록 요청한다.
configureViewResolvers: jsp 뷰 resolver를 설정
기본세팅~
*configs.ControllerConfig 지움!!!
1) 컨트롤러 구현

@Controller
public class MemberController {
@GetMapping("/member/join")
public String join(@RequestParam("name") String name){ //@RequestParam -> 요청 데이터 이름 명시 하면 뒤에 name변수에 대입
System.out.println("name: "+name);
return "member/join";
}
}
🔽



RequestParam의 필수값을 false로하면 이름 입력하지 않아도 null로 대체되서 들어간다.



public String join(@RequestParam(value = "name", defaultValue = "기본값") String name){
...
...
}
기본 값을 설정 해준 경우 required = false를 직접 해주지 않아도 자동으로 false된다.
http://localhost:3000/day04/member/join

2) JSP 구현

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<c:url var="actionUrl" value="/member/join"/>
<h1>회원가입</h1>
<form method="POST" action="${actionUrl}" autocomplete="off">
<dl>
<dt>이메일</dt>
<dd>
<input type="text" name="email">
</dd>
</dl>
<dl>
<dt>비밀번호</dt>
<dd>
<input type="password" name="password">
</dd>
</dl>
<dl>
<dt>비밀번호 확인</dt>
<dd>
<input type="password" name="confirmPassword">
</dd>
</dl>
<dl>
<dt>회원명</dt>
<dd>
<input type="text" name="userName">
</dd>
</dl>
<dl>
<dt>약관동의</dt>
<dd>
<input type="checkbox" name="agree" value="true" id="agree">
<label for="agree">회원가입 약관에 동의합니다.</label>
</dd>
</dl>
<button type="submit">가입하기</button>
</form>
✔요청(/hello) -> DispatcherServlet -> HandlerMapping -> 컨트롤러 빈(스프링 컨테이너) -> HandlerAdapter -> 컨트롤러 빈 -> 실행 -> ModelAndView
HandlerAdapter : 컨트롤러 빈의 종류가 다양하기 때문에 맞춰서 실행하기 위한 목적
@Controller, Controller 인터페이스의 구현체, HttpRequestHandler 인터페이스 구현체
Model객체
- addAttribute(키,값)
- addAllAttribute(Map ..)
Attribute: 속성

Model: View에서 사용할 데이터
ModelAndView
1) Model : 데이터 (EL 속성으로 추가된 데이터)
2) View : 출력 템플릿 경로 정보

직접 ModelAndView객체 형태로 사용해도 동일하게 사용한다.
어차피 Model을 주입해도 ViewResolver가 참고하기전 HandlerAdapter -> 컨트롤러 빈 -> 실행 -> ModelAndView이 순서로 실행되며 ModelAndView로 바꿔서 반환해주는건 똑같기때문에 Model객체를 활용하는 방식으로 많이 쓴다.
1) DispatcherServlet
: 요청과 응답의 창구 역할을 하는 서블릿 클래스
- 스프링 컨테이너 생성
스프링은 모든 요청을 처리하는 서블릿이 1개
2) HandlerMapping
: 요청 방식 + 주소 -> 스프링 컨테이너에 있는 컨트롤러 빈을 검색
3) HandlerAdapter
: 형태가 다양한 컨트롤러 빈(@Controller, Controller 인터페이스, HttpRequestHandler 인터페이스) -> 실행 -> ModelAndView로 반환
참고) ModelAndView
- addObject(String name, String value) : EL 속성으로 추가되는 속성
- setViewName(...) : 뷰 경로
요청메서드의 반환값이 String 이지만 -> HandlerAdpter에서 실행시(ex. return member/join) ModelAndView 객체로 변환
4) ViewResolver
: ModelAndView 정보 -> 출력을 위한 View 객체 검색


1) 요청 데이터의 이름과 동일한 매개변수를 요청 메서드에 정의하면 자동으로 주입
2) 정의한 변수의 자료형으로 자동 형변환
3) 요청 데이터의 이름과 요청 메서드에 정의한 이름이 다른 경우
@RequestParam("요청 데이터의 이름")
요청 데이터
GET : ?이름=값&이름=값
POST : 요청 바디 이름=값&이름=값
HttpServletRequest
String getParameter(String name)
String[] getParameterValues(String name);



요청데이터 이름이 동일하면 호출해줌

-> 편의상 전부 컨테이너안에 담겨있다
request, response, session ...
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); //현재 경로 포함 하위 모든 경로
}

static - css - style.css

✔ **
ex) /board/** -> /board 경로의 모든 파일과 하위 경로를 포함한 모든 파일을 의미함
⬇
/board/list.jsp
/board/sub/list.jsp
...
ex) /board/* -> /board 경로의 모든 파일을 의미함
✔ ? : 문자 1개를 의미함 (바뀔수있는)
/m?01 -> /ma01, /mb01, /m101