select 태그이다.
path와 같은 값이 처음 화면에서 보이게끔 나와진다.
배열과 ArrayList를 model.addAttribute를 하여 받아올 수도 있다. 이 떄에는 options 태그를 사용한다.
data_list1 은 배열이고 data_list2 은 ArrayList 이다. 각 data1, data2, data3 값을 집어 넣었고
path 값에 따라 첫 화면에 나오는 데이터가 정해지고 맨 위의 항목1 이렇게 나오는 것과 달리 데이터 값 그대로 data1, data3 으로 나온 것을 확인할 수 있다.
key 값과 value 값을 가진 KeyValueBean을 만들어서 key 와 value 값을 넣고 arrayList에 넣어서 model 객체에 주입해주고 난 뒤에,
다음과 같이 사용하게 되면 바깥에서 보이는 label 값은 key 로, value 값은 value 이렇게 지정하면 화면에서는 항목 1 이렇게 보이는데 소스보기를 눌러보면
다음과 같이 value엔 value 인 data1 2 등이 들어가고 바깥 보이는 것들은 항목1 2 이렇게 나타나게 된다.
체크박스 태그는 다음과 같이 사용한다. 이제 이것도 마찬가지로 path 의 값이 value 값과 일치한다면 화면에 체크가 되어있는 상태로 나타나게 된다. path 값을 없애면 체크가 없다.
이것 또한 배열과 arrayList 를 이용할 수 있으며, label 값과 value 값을 통해 화면에 나오는 것을 조정할 수 있다.
radiobutton 또한 마찬가지
ㅡㅡㅡㅡ
Redirect는 서버가 클라이언트에게 요청할 주소를 응답결과로 전달하는 것을 의미한다.
클라이언트는 응답결과로 받은 요청주소를 직접 요청하게 된다.
브라우저가 요청하는 것이므로 주소창의 주소는 변경된다.
Redirect는 새로운 요청이 발생하는 것이므로 HttpServletRequest 객체는 소멸 후 새롭게 생성되며
HttpSession 객체는 그대로 유지된다.
@GetMapping("/test2")
public String test2() {
return "redirect:/sub1";
}
sub1으로 redirect 하게끔 리턴을 하였다.
forward는
코드의 흐름을 서버상에서만 이동하는 것을 의미한다. 서블릿만 이동한 것이다.
브라우저는 다른 곳으로 흐름이 이동되었다는 것을 알 수 없기 때문에 주소창의 주소는 변경되지 않는다.
HttpServletRequest, HttpSession 둘 다 유지된다.
return "forward:/sub1" 로 하면된다. 이 떄에 주소창에 redirect는 sub1 이 나오지만 이거는 test2 그대로 가게된다.
redirect : 클라이언트에게 새로운 페이지 요청을 응답결과로 전달한다.
forward : 서버상에서 코드의 흐름이 이동된다.
ㅡㅡㅡㅡ
Request
*브라우저에 의해 새로운 요청이 발생하면 브라우저는 서버에 요청에 관련된 정보를 전송한다.
*이를 받은 서버는 브라우저가 보낸 요청 정보들을 보관하기 위해 HttpServletRequest 객체를 생성해
요청 정보들을 담아 둔다.
*요청 정보가 담겨 있는 HttpServletRequest 객체는 응답결과가 브라우저로 전송될 때까지 유지되며 사용이 가능하다.
RequestScope
*새로운 요청이 발생해 응답결과가 브라우저로 전달 될 때 까지 요청 정보가 담겨있는 Request 객체를 사용할 수 있다.
*이러한 사용 범위를 RequestScope 라고 부른다.
*HttpServletRequest 객체에는 서버 개발자가 필요에 의해 데이터나 객체를 저장 할 수 있고 RequestScope 내에서 사용 가능하다.
원래와 같으면 forward는 request로 넘어가니깐 둘 다 Model이 아닌 HttpServletRequest 객체를 사용했으면
result2 메서드에서 print가 잘 찍혔을 것이다.
Model은 request객체에 주입한다. model에는 없다. 따라서 위의 캡처 소스는 result2 메서드 안에서
print가 정상적으로 찍히지 않는다. 이것을 찍고 싶다면 HttpServletRequest 객체를 사용해서
request를 이용해서 찍어내면 될 것이다.
result.jsp에서 ${requestScope.data2} 를 이용해 찍어내는 것은 가능하다.
ModelAndView도 같은 형식으로 흘러간다.
기억이 아리송하면 해당 txt를 보고 연습할 것
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
Bean 주입하기
***Java 방식***
@Autowired 를 이용하면 Bean을 자동 주입받을 수 있다.
java 형식에서 이 Bean은 RootAppContext.java에 저장해 두는데 data1,data2 를 가진 DataBean1을
다음과 같이 RootAppContext.java에 작성해 주었다.
Bean태그와 함꼐 RequestScope 태그를 달았는데, 이 bean이 주입되는 시기가 새로운 요청이 발생 되었을 때 주입된다는 뜻이다.
TestController를 보면 Autowired 어노테이션 밑에 DataBean1 requestBean1; 이 선언되어 있다.
DataBean1 타입으로 주입받겠다고 명시되어있는데, RootAppContext.java에서 DataBean1 타입을 반환하는 메서드를 찾아서 호출하게되는데 @RequestScope가 붙어져 있기 때문에 TestController에서 requestBean1에 bean이 주입되는 시점은 새로운 요청이 발생됐을 때 bean이 주입된다. 그래서 /test1 이 요청이 되었을 때, bean 객체가 자동으로 주입이 되고 그것을 사용을 해서 forwarding 을 한 것이다. 그런데 이제 forward 는 새로운 요청이 발생이 되는 것이 아니기 때문에 문자열1 문자열2 가 세팅되어져 있는 requestBean1 객체를 그냥 그대로 가져다가 사용을 하게되는 것이다.
그런데, @RequestScope 어노테이션을 붙여서 bean 을 정의를 하면 bean이 주입되는 시기가 새로운 요청이 발생되었을 때 객체를 만들어서 주입하겠다라는 의미이지 이것을 request에 저장하겠다는 의미가 아니다. 따라서 캡쳐본 밑의 result1 메서드에서는 Model을 정의해서 model 안에 정의해 주었지만 저 코드 없이 result1.jsp에서
${requestScope.requestBena1.data1} 을 한다고 해서 출력이 되는 것이 아니다. 아무것도 출력이 되지 않는다. 따라서
해당 캡처와 같이 model에 따로 add 해주어서 jsp에서 사용해 주는 것이다.
요약 하자면
새로운 요청이 발생했을 때에 bean을 주입하는 것일 뿐 request에 저장하는 것이 아니다. 따라서 jsp 에서 requestScope를 이용해서 사용할 수가 없다. 이 때에는 model 을 통해 따로 request에 주입해주어야 한다.
***xml 방식***
java 방식에서는 bean 선언을 RootAppContext.java 파일에다가 해주었다.
XML 에서는 root-context.xml 에다가 해주게 되는데
다음과 같이 선언한다. scope='request' 는 @RequestScope 과 같이 요청 되었을 때에 주입되기 위해 사용한다.
그리고 나머지 TestController.java 나 DataBean1.java 나 다 동일하게 해주는데 한 가지를 다르게 해준다.
TestController.java에서
@Autowired
DataBean1 requestBean1; 이렇게 선언이 되어있을텐데 오류가 나게된다. 얘는 새로운 호출이 일어났을 때에만 주입이 되는데 계속 주입하려고 시도를 하기 때문에 오류가 난다고 한다. 이 때에는 @Autowird 밑에 @Lazy 를 붙여주면
해결이 된다.
bean에 이름을 지정할 떄에 JAVA 방식에서는 다음과 같이 Bean 어노테이션 괄호 안에 기입하고,
XML방식에서는
<bean class='kr.co.bepoz.beans.DataBean2' id='requestBean2' scope='request'/> 다음과 같이 사용한다.
@Resource(name="requestBean2")
@Lazy
DataBean2 requestBean2;
TestController.java에서는 Resource(name="***") 를 통해 접근가능하다.
XML 방식에서는 다음과 같이 id 값으로 bean을 주입하는 경우에는 따로 model에 담아 주지않아도 jsp 에서 사용할 수 있다. root-context.xml 에 id를 지정하는 순간 request 객체에 담아주기 때문이다.
만약 model 객체에 따로 담아주려고 한다면 overflow 에러가 발생하게 된다.
그리고 Component 방식으로도 주입할 수 있다.
먼저 JAVA 부터 보자면
DataBean 클래스위에 @Component 와 @RequestScope를 선언해준다.
@Component(value="requestBean4") 은 id 값을 지정해 준 것이며 그냥 @Component만 사용해줄 수도 있다.
이 두 어노테이션을 사용하지 않았다면 RootAppContext.java 에서 @Bean 과 @RequestScope 를 이용해서 등록을 해주었겠지만 @Component의 경우에는 패키지를 스캔해주어야 한다.
그래서 ServletContext.java 에 @ComponentScan("kr.co.softcampus.beans") 를 추가해 준다.
그 후 TestController에 주입을 해주는데 이는 앞선 DataBean 1/2 와 같이 @Autowired 또는 @Resource(name="")를
이용해준다.
XML에서도 동일하게 DataBean3/4 를 처리하고 이번에는 root-context.xml 이 아닌
servlet-context.xml 에 코드를 추가해준다.
<context:component-scan base-package="kr.co.bepoz.beans"/> 이것을 추가해준다.
TestController 에서 마찬가지로 적용을 해주는데
@Component 이용 시에는 id가 있어도 request에 자동주입이 되지않으므로 model 객체에 넣어주어야 한다.
java
@Lazy 안써도됨. id를 통한 Bean 주입을 해도 request 생성이 안됨
xml
@Lazy 써야됨. id를 통한 Bean 주입 시에 request 생성 됨. 하지만 Component 를 이용할 경우에는 request 생성안됨.
기본은 RootAppContext.java 와 root-context.xml 에 넣어야 되지만
Component 시에는 ServletAppContext.java 와 servlet-context에 넣어주면 된다.
'공부 기록들' 카테고리의 다른 글
2020.04.20 MVC(6) (쿠키, 유효성 검사, JSR-303) (0) | 2020.04.20 |
---|---|
2020.04.17 MVC(5) ( SessionScope, ApplicationScope) (0) | 2020.04.17 |
2020.04.14-15 MVC(3) (파라미터 받아오기2, 커맨드 객체) (0) | 2020.04.15 |
2020.04.13 MVC(2) (파라미터 받아오기) (0) | 2020.04.13 |
2020.04.10 static에 대해서 & MVC(1) (0) | 2020.04.10 |