2023.04.12 54일차 SpringBoot
54일차 SpringBoot
요청을 받앗을때 어떻게 할수있는지
아무 클래스나 만들고 컨트롤러 어노테이션만 붙이면 컨트롤러 역할을 한다.
안에 메소드들이 일하게 된다. 어떤 일을 하는지 매핑을 해주면된다.
reqeust의 아규먼트로 받아서 꺼내거나 reqeust의 아규먼트에 @RequestParam이라는 어노테이션의 밸류를 만들면 알아서 넣어준다.
넣어주는 것 뿐만 아니라 스트링을 인트로 형변환도 해줄 수 있다.
3.5 @RequestParam
아규먼트의 이름과 파라미터의 이름이 같다면 @RequestParam의 밸류도 생략이 가능하다.
//경로 : /sub4/link6?email=son.gmail
@RequestMapping("link6")
public void method06(@RequestParam("email") String email) {
System.out.println(email);
}//경로 : /sub4/link6?email=son.gmail
@RequestMapping("link6")
public void method06(@RequestParam String email) {
System.out.println(email);
}3.6 Any other argument
spring.io 메소드 만들때 참조해야한다.
Any other argument 목록에 잇는 아규먼트가 아니면 RequestParam으로 간주한다.
들어가있는게 RequestParam인지 아는게 너무 힘들다.
//경로 : /sub4/link8?address=seoul
@RequestMapping("link8")
public void method08(String address) {
System.out.println(address);
}score를 받을때
@RequestParam("score") String score ->
@RequestParam String score ->
@RequestParam double score ->
double score
생략되어간다는 것을 알아야한다.
그냥 보더라도 requestparam에 들어간다는 것을 알아야한다.
3.7 여러 파라미터
생략해서 그냥 메소드처럼 여러개 넣어도 잘돌아간다.
@RequestMapping("link1")
public void method01(@RequestParam("name") String name,
@RequestParam("age") int age,
@RequestParam("score") double score) {
System.out.println(name);
System.out.println(age);
System.out.println(score);
}
@RequestMapping("link2")
public void method02(String name, int age, double score) {
System.out.println(name);
System.out.println(age);
System.out.println(score);
}3.7 forward / redirect
link1에서 일하고 link2로 redirect하고 싶다.
String 으로 리턴하고 forward:보낼 경로 하면된다.
요청할때마다 두개의 메소드가 다 일하게 된다.
@RequestMapping("link1")
public String method01() {
System.out.println("link1 메소드 일함");
return "forward:/sub6/link2";
}
@RequestMapping("link2")
public void method02() {
System.out.println("link2 메소드 일함");
}
@RequestMapping("link3")
public String method03() {
System.out.println("link3 메소드 일함");
return "forward:/sub6/link2";
}3.7 jsp사용
포워드를 하는 이유가 view로 포워드하는 것이다.
원래대로 일하던 방식대로 request.getRequestDispatcher를 얻어 포워딩할 수 있다.
jsp가 서블릿으로 변경되고 여러가지 일을 하는데 스프링부트에서는 설정이 라이브러리가 없어
pom.xml에 추가해서 라이브러리를 다운받아야한다.
https://mvnrepository.com/에서 검색해서 링크를 그대로 사용하면된다.
1.Tomcat Embed Jasper 버전은 알아서 찾아주니 지워주자.
<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-jasper -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<!-- <version>10.1.7</version> -->
</dependency>2.Jakarta Standard Tag Library API
JSP Standard libray 역시나 버전을 지워주자.
<!-- https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api -->
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>3.0.0</version>
</dependency>3.Jakarta Standard Tag Library Implementation
<!-- https://mvnrepository.com/artifact/org.glassfish.web/jakarta.servlet.jsp.jstl -->
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>3.0.1</version>
</dependency>3.8 forward - 2
기존의 foward와 동일하게 사용할수도 있고 스프링의 forward를 사용할 수도 있다.
@RequestMapping("link4")
public void method04(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("link4에서 일함");
String view = "/WEB-INF/views/abc.jsp";
request.getRequestDispatcher(view).forward(request, response);
}
@RequestMapping("link5")
public String method05() {
System.out.println("link5에서 일함");
return "forward:/WEB-INF/views/abc.jsp";
}3.9 application.properties
우리가 사용하는 뷰가 앞에는 /WEB-INF/views/ 뒤에는 jsp가 꼭 붙는다.
이것들을 반복적으로 작성하지 않도록 prefix와 serffix를 설정할 수 있다.
이렇게 하면 forward도 생략할 수 있다.
spring.mvc.view.prefix= /WEB-INF/views/
spring.mvc.view.suffix= .jsp
@RequestMapping("link6")
public String method06() {
System.out.println("link6에서 일함");
return "abc";
}
@RequestMapping("link7")
public String method07(){
System.out.println("link7에서 일함");
return "def";
}원래 코드에 비해서 생략된게 많아서 보기 어려울 수 있으니 설정을 잘봐야한다.
3.10 default viewName
리턴타입이 String일때는 viewName으로 해석이 된다.
이 viewName을 명시하는것은 propeties의 앞뒤이다.
void리턴타입은 default viewName으로 간주한다.
default viewName은 요청한 경로에 의해서 결정이 된다.
명시적으로 요청하는것과 같다.
/WEB-INF/views/sub6/link8.jsp를 찾게 된다.
//경로 : /sub6/link8
@RequestMapping("link8")
public void method08() {
System.out.println("8번 메소드 일함");
//default view name : /sub6/link8
//return "/sub6/link8";
}3.11 default viewName - 2
리턴타입을 null로 해도 default viewName에서 찾게 된다.
/WEB-INF/views/sub6/link10.jsp를 찾게된다
// 경로 : /sub6/link10
@RequestMapping("link10")
public String method10() {
System.out.println("10번 메소드 일함");
return null;
}연습
WEB-INF/views/sub6/link11.jsp 로 포워드해보자.
다음의 메소드들 이 다 같은 일을 하게 된다.
이것 말고도 방법이 많은데 이 세가지를 사용할것이다.
ModelAndView object객체 View객체 리턴하는 방법 등등이 있다.
여러방법이 있는데 보게되면 api를 보는게 좋다.
혼자 공부햇을때 ModelAndView를 리턴해서 페이지를 로드하고 어노테이션으로 바꾼 것이 있다.
// 경로 : /sub6/link11
@RequestMapping("link11")
public void method11() {
System.out.println("11번 메소드 일함");
}
// 경로 : /sub6/link11
@RequestMapping("link11")
public String method11() {
System.out.println("11번 null 메소드 일함");
return null;
}
// 경로 : /sub6/link11
@RequestMapping("link11")
public String method11() {
System.out.println("11번 String return 메소드 일함");
return "/sub/link11";
}3.12 request param + forward
파라미터를 받고 forward까지 해보자.
경로 : /sub6/link12?name=park&age=33
method12
1.request param 수집 / 가공
2.business logic(생략)
3.add attribute(생략)
4./WEB-INF/views/sub6/link12.jsp로 포워드
@RequestMapping("link12")
public void method12(String name, int age) {
}아무것도 작성하지 않았지만 1번,4번일을 하게 되는 코드인것이다.
3.13 add attribute
forward할때 어떤 값을 담아서 forward햇엇다.
request에 값을 담은 방법을 알아보도록 하자.
서블릿의 api를 이용해서 기존 방법처럼 할 수도 있다.
@RequestMapping("link1")
public void method1(HttpServletRequest request) {
//1. 2.
//3. add attribute
request.setAttribute("myName", "서태웅");
//4. /WEB-INF/views/sub7/link1.jsp로 포워드
}<h1>sub7의 link1.jsp입니다.</h1>
<p>name: ${myName}</p>3.14 add attribute - 2
attribute를 쉽게 제공하는 스프링 api가 있다.
Model 인터페이스를 사용하면된다.
메소드 아규먼트로 Model을 넣으면 적절한 메소드를 사용할 수 있게 된다.
주 설계목적이 model에 attribute를 추가하기 위해 사용된다.
model은 컨트롤러가 요청을 받고 일한 결과를 담고 view에게 전달해서 꺼내지는 역할을 한다.
addAttribute, getAttribute등등이 있다.
주로 addAttribute(객체이름, Object)를 사용할 것이다.
이러면 포워드한 곳에서 모델을 꺼내서 사용하게 된다.
@RequestMapping("link2")
public String method2(Model model) {
//1. 2.
//3. add attribute
model.addAttribute("myName", "채치수");
return "/sub7/link1";
}연습
경로 : sub7/link3
method3작성
/WEB-INF/views/sub7/link3.jsp로 포워드
<h1>sub7의 link3.jsp입니다.</h1>
<h1>address : ${address}</h1>@RequestMapping("link3")
public void method3(Model model) {
model.addAttribute("address", "seoul");
}3.14 add attribute - 3
attribute는 Object를 받기 때문에 어떤 형태의 객체도 받을 수 있다.
List를 넣을 수도 있다.
@RequestMapping("link4")
public void method4(Model model) {
model.addAttribute("list", List.of("java", "spring"));
}<h1>sub7의 link4.jsp입니다.</h1>
<h1>${list[0]}</h1>
<h1>${list[1]}</h1>
<hr />
<c:forEach items="${list}" var="item">
<h1>${item}</h1>
</c:forEach>연습
myMap으로 담아서 address / age / email을 꺼내보자.
<h1>sub7의 link5.jsp입니다.</h1>
<h1>${myMap.address}</h1>
<h1>${myMap.age}</h1>
<h1>${myMap.email}</h1>@RequestMapping("link5")
public void method5(Model model) {
Map<String, String> map = new HashMap<>();
map.put("address", "고양시");
map.put("age", "26");
map.put("email", "email@naver.com");
model.addAttribute("myMap", map);
}3.15 addAttribute - 4
다음 jsp를 구현해보자.
<h1>sub7의 link7.jsp입니다.</h1>
<p>나이 : ${age}</p>
<p>나라 : ${country}</p>
<p>영화목록 </p>
<ul>
<c:forEach items="${movieList}" var="movie">
<li>${movie}</li>
</c:forEach>
</ul>@RequestMapping("link7")
public void method7(Model model) {
model.addAttribute("age", "26");
model.addAttribute("country", "한국");
model.addAttribute("movieList", List.of("스즈메의문단속", "던전앤드래곤", "슬램덩크"));
}3.16 addAttribute javabean - 5
여러개의 값을 javabean에 담아서 가져온적이 있다.
패키지명의 규칙은 회사마다 다르다.
책 167페이지
책을 기준으로 컨트롤러들은 controller
domain VO, DTO(Data Transfer Object)클래스들 = javaBeans으로 넣어주자.
-> 따로 배우던 강의에서는 entity에 담았다.
의미있는 이름으로 만들어야하는데 일단은 아무 이름으로 만들자
자바빈에 담아서 addattribute를 하고 view에서는 attribute.property로 꺼내서 사용하면된다.
public class Dto01 {
private String name;
private int age;
//getter setter들
}@RequestMapping("link8")
public void method8(Model model) {
Dto01 o1 = new Dto01();
o1.setName("박지성");
o1.setAge(40);
model.addAttribute("player", o1);
}<h1>sub7의 link8.jsp입니다.</h1>
<p>이름 : ${player.name}</p>
<p>나이 : ${player.age}</p>3.17 addAttribute javabean - 6
컴포넌트들 간에 값을 전달할때 데이터만 담아서 보내는데 이것을 DTO라고 한다.
SET하고 GET하는 자바빈을 사용하거나 MAP을 사용하기도 한다.
DTO는 VO라고도 한다. 자바빈으로 데이터를 담고 꺼낸다고만 이해하자.
method9 작성, Dto02클래스 작성
경로 : /sub7/link9로 요청오면 Dto02객체 만들어서 model attribute추가
view : /sub7/link9로 포워드하는 코드를 작성해보자.
public class Dto02 {
private String model;
private int price;
private String company;
//getter setter들
}@RequestMapping("link9")
public void method09(Model model) {
Dto02 dto = new Dto02();
dto.setModel("제네시스");
dto.setPrice(10000);
dto.setCompany("현대");
model.addAttribute("value", dto);
}3.18 lombok
이전 예제들에서는 DTO객체를 만들고 getter와 setter들을 작성해주엇다.
이런것들을 자동으로 해주는 롬복 플러그인과 라이브러리가 있다.
스프링의 라이브러리가 아니라 개발자들이 많이 사용하는 라이브러리이다.
프로젝트 우클릭 spring - add Staters하면
처음 프로젝트를 생성할때 추가하는 스타터팩을 추가로 넣을 수 있다.
메이븐에가서 찾아도 된다.
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>어노테이션만 붙이면 getter setter등을 알아서 만들어준다.
생성자 등등도 붙일 수 있다.
라이브러리 추가도 해야하고 이클립스에 플러그인도 설치해야한다.
https://projectlombok.org/ 공식홈페이지에서 다운받자.
롬복 어노테이션을 사용하면 우리눈에는 안보이지만 알아서 추가해준다.
@Getter - getter 자동생성
@Setter - setter 자동생성
@ToString - toString 자동생성
@EqualsAndHashCode - equals, hashcode 자동생성 ,+ canEquals 메소드
@AllArgsConstructor - 모든필드 초기화 생성자
@NoArgsConstructor - 기본생성자
@Getter
@Setter
@ToString
@EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor
public class Dto03 {
private String name;
private int age;
}자주 사용하는 것들을 모아서 @Data 어노테이션 하나에 모아 두었다.
Getter, Setter, ToString, EqualsAndHashCode, RequiredArgsConstructor를 다 붙인 역할을 한다.
@Data
public class Dto04 {
private String name;
private int age;
}대부분 @Data 어노테이션을 붙이면되고 정교하게 하려면 나눠서 작성하면된다.
Dto04에 setter와 getter를 직접만들지 않았지만 정상적으로 작동하는 것을 볼 수 있다.
@RequestMapping("link10")
public void method10(Model model) {
Dto04 dto = new Dto04();
dto.setName("송태섭");
dto.setAge(20);
model.addAttribute("val", dto);
}<h1>sub7의 link10.jsp입니다.</h1>
<p>이름 : ${val.name }</p>
<p>나이 : ${val.age}</p>3.19 @ModelAttribute 어노테이션
넣을 객체를 메소드 아규먼트에 넣고 @ModelAttribute를 붙여주면
객체 생성과 model addAttribtute를 생략할 수 있다.
생략이 많이 되기 때문에 잘 작성해야한다. 모델객체를 직접 만지지 않아도 추가가 가능하다.
@RequestMapping("link1")
public String method1(@ModelAttribute("val") Dto04 dto04) {
dto04.setName("채소연");
dto04.setAge(27);
return "/sub7/link10";
}모델에 넣어놓고 객체에 데이터를 넣는 것이나 객체에 데이터를 심고 모델을 넣는것이나 같은 것이다.
결국 참조값이 같은 객체를 참조하고 있기때문에다. 그 원리를 이용한 것이다.
Dto04 dto = new Dto04();
dto.setName("송태섭");
model.addAttribute("val", dto);
Dto04 dto = new Dto04();
model.addAttribute("val", dto);
dto.setName("송태섭");이 두 결과가 같다. 객체를 만들때 dto라는 이름으로 만들엇고 그것을 참조해서 보내는 것이기 때문이다.
3.20 @ModelAttribute 연습
<h1>sub8의 link2.jsp입니다.</h1>
<p>모델 : ${product.model }</p>
<p>가격 : ${product.price}</p>
<p>기업 : ${product.company }</p>@RequestMapping("link2")
public void method2(@ModelAttribute("product") Dto02 dto02) {
dto02.setModel("ipad");
dto02.setPrice(300);
dto02.setCompany("apple");
}3.21 여러 attribute 넣기
reqeust.setattribute를 여러번 작성해서 값을 여러개 보내듯이
@ModelAttribute어노테이션을 여러개 사용하면 여러개를 담아서 보낼 수 있다.
이렇게 하면 메소드에 아무것도 작성하지 않고 객체를 주입하고 포워드 할수 있으니 구분을 잘해야한다.
또한 requestParam의 이름을 생략했듯이 클래스이름을 lowerCamelCase로 자동으로 맞춰준다.
예) CompanyMember -> companyMember
@RequestMapping("link5")
public void method5(@ModelAttribute Dto02 dto02, @ModelAttribute Dto03 dto03) {
dto02.setCompany("microsoft");
dto03.setName("bill gates");
}
@RequestMapping("link6")
public String method6(@ModelAttribute Dto02 dto02, @ModelAttribute Dto03 dto03) {
dto02.setCompany("apple");
dto03.setName("steve jobs");
return "/sub8/link5";
}2023.04.12
놀랍게도 학원오기전에 햇던 강의에 다 잇엇던 것이다.
실제로 프로젝트를 만들거나 이용을 안해봐서 다 잊고 잇엇던것 같다.
자주 사용해보면서 눈에 익는게 중요한 것 같다. 코드는 점점 가벼워지고 이해는 점점 어려워진다.