카테고리 없음

22-10-07_jsp(2)

dadba 2022. 10. 7. 21:58

1. container의 계층구조 통해 중복제거하는 방법

2. auto injection을 통해서 작업의 부하를 줄이는 법

 

 

-----------------------------------------------------------------------------------

 

1. 컨테이너간의 계층구조 형성하는 방법

 

 

요기 이렇게 해주고

 

여기보면 1번에 주입해야 쓸수있는데, 2번에 있죠 저기서 꺼내와보자

 

여기도 위에 쟤를 주석처리하니까 밑에 참조할게 없죠 

 

그러면 이 둘에 에러가 나는데, 둘 다 주입받아야 하는게 없음. 

가장 간단한 방법은 각자 dbInfo를 정의해서 넣어주면 되지만  그러면 코드 중복이 생기죠. 

 

그러면 중복을 해결해야 함. 공통되는 부분을 상위의 definition을 분리해서 정의해주고 상속받아서 쓰면 , 하위에서 중복코드를 쓰지 않아도 됨. 

즉, 중복을 해결하는 가장 간단한 방법은, 상속을 사용하면 됨

 

.

여기에 이렇게 만들어 주자

 

 

 

parent 붙음. 하나의 컨테이너를 만들때도 계층구조를 만들 수 있다는 것

package kr.or.ddit.di;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ContextHierarchyTestView {

	public static void main(String[] args) {
		//밑의 xontext1, 2가 써야 할 properties가 여기 들어있음.
		//상위로만들어서 아래에서는 상속해주는거임. 
		ConfigurableApplicationContext parent = 
				new ClassPathXmlApplicationContext("/kr/or/ddit/di/conf/Properties-Context.xml");
		
		//상속받기.
		ConfigurableApplicationContext context1 = 
				new ClassPathXmlApplicationContext(
						new String[] {"/kr/or/ddit/di/conf/CollectionDI-Context.xml"}
						, parent
				);

		ConfigurableApplicationContext context2 = 
				new ClassPathXmlApplicationContext(
						new String[] {"/kr/or/ddit/di/conf/VariousDI-Context.xml"}
						, parent
				);
	}

}

그러면

계층구조가 이렇게 형성이 되서 parent의 baen들을 child쪽으로 공급이 가능함. 그런데 반대방향으로의 주입은 안 됨. parent가 생기는 시점에  child는 생기지 않기 때문.

또한 형제들끼리의 주입구조도 불가능함

부모에서 자식으로의 주입만 가능함. 

 

 

여기 이제 넣으려고 하는데 DBInfo가 안보이죠. 보이게 해봅시다

 

이케하면

 

 

 

이케나오고

이케뜹니다

 

--

아잇 조졋네 놓침

 

--

 

 

최프....사용자 분류가 여럿임...

분리해서 완전히 별개의 application처럼쓰는데 계층분리래

 

User context

 

Admin Context

나눠서 

User context는 확장자를 *.user

Admin Context는 확장자를 *.admin으로 나누면 url이 다 나뉨

그러면 앞에 controller-view가 나뉨. 가지고 노는 modeler등을 같은데. 

 

계층구조를 형성하면, BLL, PL, DL, mybatis,db..여기를 parent로 두고, 

이걸 user / admin에 주입해주면

 

이런식으로 계층구조를 나눠놓으면

 

같은 백인데 전혀 다른 aplication처럼 사용이 가능함..

 

--

기록포기

--

 

Auto Injection할 것

새로 만들어 주는데, beans와 context만

 

auto injection 하려면 auto register 먼저 되어야 함

 

 

--

spring 특깅 ==하위버전 호환성이 아주 좋음. 즉 아주 옛날버전을써도 잘 돌음. 

Annotation 없는 구버전 써도 잘돌아가고요

 

우리가 쓸 수 있는 anotation들이있는데 

 

이제 어떤 어노테이션을 써야 Regist가 되고 어떤 어노테이션을 써야 injection을 하겠는가.

 

@Controller , 우리가 익히 아는 그 controller layer를 등록하고 싶을 떄 

@Service , 우리가 아는 BLL이죠?

@Repository, 이건 생소하죠 DAO에요. 저장소에 접근한다는 의미로 repository라고 해요.

@Component, 이건 진짜 잉?스럽죠?

 

-근데 이거 등록만 하는건데 왜 이렇게 나뉘어졌죠?

-시스템입장에서는 다 똑같거든요 한개나 다름없어요 

이유는

 

 

어노테이션은 주석이예요

// /* */
이것도 다 주석이지만, 어노테이션과는 달라요. 왜냐면, 저 주석들은 사람말을 대상으로 해요. 즉 compile되는 class파일에는  byte code에는 주석이 포함되지 않아요. 

인간적인 코멘트거든요

 

그런데 어노테이션은 주석인데, 대상이 사람만을 대상으로 하지 않고, 시스템과 사람을 모두 대상으로 해요. 

@Override 이런 것도 어노테이션인데, 이거 보면 사람도 의미파악이 되죠. 어디서 상속받아서 재정의했구나. 그런데, 

이런거 추가하면 에러가 나죠 근데

없애면 또 에러 안나죠? 즉

컴파일러도 이걸 보고 있다는거죠. 

 

어노테이션은 사람과 시스템 모두를 대상으로 하는거예요

 

 

그러니까, 시스템 입장에도 보여주지만, 사람을 대상으로도 알려줘야되서 이름이 나뉘어 진 거예요

 

---

 

@Configuration

 

---

스프링 5,6 버전에서는 xml을 아예 안써요 사람들이 찡찡대서 xml 걷고 다 자바처리했거든요. 

그치만 우리는 xml을쓰죠. 한국에선 아직 이걸 쓰기떄문이예요 그래서 이걸 수업하는건데요.

 

나중에 자바로 configuration 설정하는 방법도 한번 알아봐야 해요. 그때 자바로 설정파일 설정 할 때 쓰는게 @Configuration 이 어노테이션이예요

 

 

 

그 후에 추가된게 또 

@ControllerAdvice, 얘도 컨트롤러에다가 쓰는데,  좀 달라요. 이 Advice라는 의미가 뭐냐면 , 객체지향 방법론이 아니라 관점지향방법론이라는 새로운 관점으로 봐야 하는데요.. 다음주쯤 볼게요

또 추가된게

@RESTController, 여기서 만들어진 모든 data는 json..이라던가..

그 다음에 또 만들어진게

@RESTControllerAdvice...얘도 advice를 알아야 하니 나중에 봅시다

 

이정도 까지가 자동 bean 등록하기 위한 거예요

	<context:annotation-config />
	<!-- auto regist -->
	@Component
	@Repository
	@Service
	@Controller
	@Configuration

	@ControllerAdvice	 
	@RESTController
	@RESTControllerAdvice

 

========

'어디에 있는' 걸 자동등록하느냐

얘임. 쭉 둘러보다가 저런 어노테이션들 찾으면 등록해줌. 

그래서 베이스패키지를 받아감.

 

-===

이건 어노테이션 달면, 저 조건에 맞는 걸 찾아서 생성자 주입해줌

 

얘도...

순서도 다 똑같은데 그냥

어노테이션을 쓴다. 는 방식만 다른거지.

 

---

@Autowired는 걍 자동인데

@Resource를 쓰면 명시적으로 여기에 연결해 할 수 있어서 좀 더 안전함

 

이제 저 autowired 어노테이션을 열어서 보면

클래슨데요

81번째 줄에 보니까 얘는 생성자, 메서드, 파라미터, 필드, 어노테이션 타입에 사용 가능할수있어요

이렇게 되어서 autowired는 저기 다 사용할 수 있어요

 

근데 얘는 열어보면 타입, 필드, 메서드에만 쓸 수 있어요

 

그래서 여기 에러가 나니까

이렇게 올려줘버리면 잘되져

 

짠

 

	<!-- 2. auto injection -->
	@AutoWired : type(class)를 기준으로 bean을 검색하고, 주입 
	@Resource : 검색기준을 설정할 수 있음.

딱 봤을때 그러면 @Resource얘가 더 안전하죠, 위에 애는 언제든 예외를 발생시킬 수 있으니까.

근데 쓰기 좀 불편하니까, autoWired를 많이 씀

 

근데 가급적 autoWired를 쓰면 안 될 때가 있음. 

이 두 어노테이션의 결정적인 차이는, 

autoWired는 spring에서 만든거라 spring container 나가면 작동을 안함, 대신에 Resource는 나가도 잘만 작동함

 

---

자 다시, spring의 지향방향은 POJO임 어디서든 잘돌아가야 함. 

그래서 Resource가 더 spring자체에 대한 종속성을 낮춰서 spring에 더 잘 맞는 거임,

 

근데 쓰기는 autoWired가 편하잖아? 그래서 이거랑 똑같은걸 java에 만들면 되지? 해서 만들어 놓은게 있음. 

 

https://mvnrepository.com/artifact/javax.inject/javax.inject

저기서 이놈을 넣어줍니다

 

 

 

이건

import javax.inject.Inject;

스프링 외에 다른데에서도 잘만 쓸수 있어요 

그래서 autoWired대신에 이거 쓰면 됨 

 

요놈을 열어보면

생성자에도 쓸 수 있어서, 생성자 주입이나 세터 주이에 다 쓸 수 있어서 편안함

 

요놈은 같이 쓰이는 애가 있는데

이렇게 있어서 생성자에도 쓸 수있고 명확하게 인젝션 해 줄 수 있다는걸..

 

---

이건 꼭 스프링이 가진거로. 얘는 꼭 인젝션 해야 합니다

 

--

필터링 구조도 적용해보자

저거 false로 하면 옆에 s 사라짐

 

 

---

이렇게 만들어 주시고요

 

 

 

이렇게 하면 다 등록되버리죠? view는 뺼 거에요

일단 다 빼고요

 

선별적으로 넣어봅시다...

 

respository와 service는 include 포함시켜야겠죠

 

 

얘는 원래 상속이 안되는얘에요 그래서 상속을 meta-??????로 완성해요

 

이렇게 등록을 dao(repository)와 service를 해줘요

 

 

--

이제 자식을 만들어 주고요

 

이렇게 하면 잘된 게 아니라, dao, service는 두번씩 등록된거죠

 

---

이거잠깐볼까여

 

오호 얘는 component면서 service인거죠

그래서

 

 

view에 compenent annotation을 썻다고 이래서 잘되었다고 하면 안되고요

component가 repository(dao)도 service도 있어서 중복인거죠 그래서 쟤네를 빼줘야 해요

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

	<context:component-scan base-package="kr.or.ddit.sample" use-default-filters="false">
		<context:include-filter type="annotation" 
			expression="org.springframework.stereotype.Component"/>
		<context:exclude-filter type="annotation" 
			expression="org.springframework.stereotype.Repository"/>	
		<context:exclude-filter type="annotation" 
			expression="org.springframework.stereotype.Service"/>	
	</context:component-scan>

</beans>

그래서 이렇게 해줘야해요

 

--

예제를해보자

 

package kr.or.ddit.di.auto;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import kr.or.ddit.sample.view.SampleView;

public class AutoHierarchyTestView {
	public static void main(String[] args) {
		ConfigurableApplicationContext root =
				new ClassPathXmlApplicationContext("/kr/or/ddit/auto/conf/Parent-Context.xml");
		//사실 어떤 구현체를 쓰든 제한은 없음 지금은 CPXAC를 썻지만
		
		root.getBean(SampleView.class);	//이건안돼요
	}
}

이건안돼요 왜냐면 저 root가 view를 안가지고있어서 하위 컨텐츠가 필요ㅕ해요

 

 

=====

 

빈을 초기화 하다가 생긴 문제..... init, start 같은... 여기서 강조했던 건... init 메서드인 start가 호출되는 시점... 모든 인젝션이 끝나고 나서 호출이 됨. 거기서 문제가 생긴거임.... 초기화를 완료할랫는데 인젝션이 안되어있어요....왜냐면 @required 걸어놓고 안넣어줘서그래요...

 

이렇게 Inject 어노테이션을 추가해줘요...

그럼잘됨

 

 

=====================================

새로운걸합시다 MVC 인가

이런걸하면

이런게있어요 그리고 아래에 뭔가 버전이있어요

 

뭐랫더라이게 ㅎ..

 

 

스프링에서 자주 사용하는 템플릿을 가져오려고 함., 사이즈가 좀 커서

그럼 이제 오케이하고

top-level 패키지를 달래요

이케 써서 완료합니다 그러면

이렇게 하단에서 돌면서 가져와요 이제 

그러면 이제

이런거 열어보면 우리가 안넣었는데 알아서 가져와놨거드요

 

spring context = 컨테이너

spring webmvc : 웹용모듈

javax.inject inject  annotation

 

서블릿, jsp, jstl...

loggin framework... 테스트에 쓰는 junit...다 넣어버림

이게 템플릿이에요ㅕ

 

근데ㅐ 지금 버전이 낮아서 못쓰니까 수정합시다

 

 

 

 

애당초 1.6은 보안취약성때문에 안써요

이렇게 바꾸고 업데이트 해주시고요

밑에보니까 하드코딩해놔서 쟤도 수정해줍니다

이거 버전도 바꿔주새ㅔ요

 

그리고 web.xml 보면

이런게 있는데요

ContextLoaderListener

요놈을 ctrl 키 누르고 가서 보면

 

아렇게 있는데

web/ 에서만 사용하는 container인데 start up, shut down 다 해주고요, 

root라고 하면 상위인거예용 그러면 application 통틀어서 가장 먼저 실행된대요

 

왜그러냐

이런게 있어선데요 쟤도 봅시다

이렇게 보면 어플리케이션에 어떤 변경사항이 있는지 감지하는애래요

 

서버가 구동되는 시점을 알아차리고 상위 컨테이너를 생성하고 서버가 종료되는 시점을 알아서 상위컨테이너를 종료시키는 역할인거예요

 

일단 대충만 알아두새요

 

--

여기 다시 와서

상위...ㄴㅇㄹ...

 

 

스프링 내부에 front-controller에요 유일하게 존재하는 Servlet 걔

init 미리 만들어서 contextConfigLocation요거 설정파일 똑같이 가는거.....음 네 그래요

 

--

자 여기 이런게 자동으로 들어와있는데요

container에 미리 등록되었다고 S가 있어요

그러면 상위컨테이너, 하위컨테이너 어디에 있을까요..

 

이거 상위root 파일인데 여기 보면 아무것도 없거든요

 

그러면 하위컨테이너 설정파일에 등록되어있겠죠

요게 하위인데 여기 이렇게 등록되어있군요

이렇게 어노테이션이 붙어있어서 bean이 될 수 있던 거죠

디테일한 구조는 아직 몰라도 이렇게 알고있으면되죠...

 

 

--

이거 실행해봄녀

암거ㅗㅅ도 안햇는데 웬 페이지를 하나 보여주죠..

 

 

home 메서드가 controller로 역할했다는거고 

이거 소스 보면 xml 보이니까 어디서 만들었을텐데요

이거 jsp가 어디서 만들어졌지

 

이거같거든요

저거 qualified name 복사해서 

 

여기서 이제 한번 보면 형태가 좀 이상하죠

 

씁 지금 보니까 request, set attribute 이런거 다 안보이는데 

model.addAttribute("serverTime", formattedDate );

이런게있고... 키, 값으로 들어가있네?

 

그게 여기 열어보니까

이렇게 되서 보여주는걸 보면..

controller에서 뭔가 메세지를... view에 전달해줘서 보내준걸.. 알수잇죠..?

우리가 아는거랑은 좀 다르지만 비슷한 구조가 

 

지금 home 빼고 주소가 다 날아갔는데, 그러면 어디선가 이걸 설정해줬겠죠

음 일단 여기서 처리해준거였죠

 

 

일단 한글로 인코딩 처리좀 해주고요

 

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" contentType="text/html; charset=UTF-8" %>
<html>
<head>
	<title>Home</title>
</head>
<body>
<h1>
	Hello world!  
</h1>

<P>  The time on the server is ${serverTime}. </P>
<a href="${pageContext.request.contextPath }/01/sample.do">sample1</a>
</body>
</html>

이렇게 해준다음에...

 

package kr.or.ddit;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class SampleController {
	//이걸 command handler로 써보고 싶거든요
	@RequestMapping("/01/sample.do")
	public String handler1() {
		System.out.println("handler1 동작 완료");
		return "01/sampleView";
	}
}

이걸 만들어주고요...

 

리턴한 주소가 이런 주소였던거죠 저기에 만들어야죠

 

이렇게된거죠

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h4> 뷰레이어 렌더링 완료</h4>
</body>
</html>

이렇게 만들어주고 server restart 해서 보면요

컨트롤러가 동작하면 로그에서 많은걸 볼수잇어요

상위 컨테이너가 만들어 지고있고요

 

상위 / 하위 컨테이너 로그들을 볼 수 있어요

 

RequestMappingHandlerMapping 이런게 있는데 

다음주애 중요한거예요

 

이런것도잇어죠

 

돌린거 보면

딱히 해준거 없는데 잘돌져

 

또

package kr.or.ddit;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class SampleController {
	@RequestMapping("/01/sample.do")
	public String handler1(HttpServletRequest req) {
		System.out.println("handler1 동작 완료");
		String infomation = "생성한 모델정보";
		req.setAttribute("infomation", infomation);
		return "01/sampleView";
	}
}

sampleView를 이렇게 해주고

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h4> 뷰레이어 랜더링 완료 </h4>
<h4>model : ${infomation }</h4>
</body>
</html>

이렇게 하면 information도 잘 출력되죠

 

 

 

---

포기

---

??

 

....

.....

 

jsp에 이렇게 param1에 값을 문자로 넣어줬는데ㅐ 

이렇게 int로 받는데..... 자동으로 spring이 cast 해줘서 에러가 안나고 

 

짠...후....

 

 

 

 

 

---

2.5버전이라 저 서블릿 어노테이션 못써서 다 에러나,.. 다 바꿔보자 스프링방식으로..

 

--

필기포기

--

 

스프링에서 컨트롤러는 클래스가 아님.

 

클래스에 있는 메서드 하나하나가 컨트롤러가 된다

스프링 쓸 떄 유의점은, 서버가 돌고나면 컨테이너가 잘 동작했는지 확인해야함

....

 

 

 

lifeCycle method는 arg가 없어애 햐나

 

이거 지우고 restart

예 잘 돌았네요

 

https://releases.jquery.com/

 

jQuery CDN

The integrity and crossorigin attributes are used for Subresource Integrity (SRI) checking. This allows browsers to ensure that resources hosted on third-party servers have not been tampered with. Use of SRI is recommended as a best-practice, whenever libr

releases.jquery.com

minified 카피

넣어주세요

 

ㅇ예에 ..잘되네요...

 

이제..

factoryBean 잘쓰면 이거 안해도되겠죠...

 

 

과제1... btsForm에서 EL, core tag로 다 바꿔놓기...

 

..

 

이 위에.. spring에서는 req, resp를 최대한 안써야 spring이 대신 일을 많이 해줌. 근데 안그러면 내가 다해야함...

 

 

---

...

 

 

이런식으로 안하고 순수하게 결과를 보내겠다는거거든

@ResponseBody 어노테이션 붙이면 됨....

 

	//식별이 필요해. multivalue annotation으로 쓰자
										//똑같은 요청이라도 POST요청만 들어옴
	@RequestMapping(value="/calculate", method=RequestMethod.POST)
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		CalculateVO vo = parseRequest(req);
		req.setAttribute("calculator", vo);
		sendResponse(req, resp);
	}
						//post를 제외한 get, put, ?가 다 이리 옴 따로 method 안쓰면.
	@RequestMapping("/calculate")
	@ResponseBody
	public String doGet(int leftOp, int rightOp, OperatorType operator) throws ServletException, IOException {
 			String expression = operator.getExpression(leftOp, rightOp);
 			return expression;

	}

개발자들의 코드가 단순해짐. 책임을 전부 spring에서 처리해주니까....

 

많은 spring 개발자들이 있겠지만 찐고수들은 최대한 spring 써먹어서 코드가 단순해짐. ...

 

-------

 

음 다 처리하고나니

package kr.or.ddit.servlet03;

import java.io.IOException;

import javax.servlet.ServletException;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.or.ddit.enumpkg.OperatorType;
import kr.or.ddit.vo.CalculateVO;

//@WebServlet("/calculate")
public class CalculateController{
	
	//식별이 필요해. multivalue annotation으로 쓰자
										//똑같은 요청이라도 POST요청만 들어옴
	@RequestMapping(value="/calculate", method=RequestMethod.POST,headers="content-type=application/json"
						, produces="application/json")
						//request의 body안에있는 데이터를 unMarsharling 해야 한다는걸 의미
						//annotation 하나로 parsing 끝남..
	@ResponseBody
	public CalculateVO doPostJson(@RequestBody CalculateVO vo) throws ServletException, IOException {
		return vo;
	}
	//갑자기 쌩뚱맞게 vo가 반환되면 container입장에서..? 이 자체가 marshalling이 되어서 json되어서 response의 body를 만들어서 나가야됨
	//@ResponseBody 를붙여줌.
	
	@RequestMapping(value="/calculate", method=RequestMethod.POST)
	@ResponseBody
	public String doPost(CalculateVO vo) throws ServletException, IOException {
		return vo.getExpression();	//문자열, 메세지 자체임 @ResponseBody 적어주기
	}
						//post를 제외한 get, put, ?가 다 이리 옴 따로 method 안쓰면.
	@RequestMapping("/calculate")
	@ResponseBody
	public String doGet(int leftOp, int rightOp, OperatorType operator) throws ServletException, IOException {
 			String expression = operator.getExpression(leftOp, rightOp);
 			return expression;
	}
}

이게 1차 최종모양이네...

so simple해졌네...

 

어노테이션을 만들어서 쓸수도있는데 거꾸로.. 쓴다음에 만들어보자 그러면 의도를 파악하기 좋음. 

 

 

근데 doget, dopost왜나눔 같이 합치면어때?

package kr.or.ddit.servlet03;

import java.io.IOException;

import javax.servlet.ServletException;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.or.ddit.enumpkg.OperatorType;
import kr.or.ddit.vo.CalculateVO;

//@WebServlet("/calculate")
public class CalculateController{
	
	//식별이 필요해. multivalue annotation으로 쓰자
										//똑같은 요청이라도 POST요청만 들어옴
	@RequestMapping(value="/calculate", method=RequestMethod.POST,headers="content-type=application/json"
						, produces="application/json")
						//request의 body안에있는 데이터를 unMarsharling 해야 한다는걸 의미
						//annotation 하나로 parsing 끝남..
	@ResponseBody
	public CalculateVO doPostJson(@RequestBody CalculateVO vo) throws ServletException, IOException {
		return vo;
	}
	//갑자기 쌩뚱맞게 vo가 반환되면 container입장에서..? 이 자체가 marshalling이 되어서 json되어서 response의 body를 만들어서 나가야됨
	//@ResponseBody 를붙여줌.
	
	@RequestMapping(value="/calculate")
	@ResponseBody
	public String doPost(CalculateVO vo) throws ServletException, IOException {
		return vo.getExpression();	//문자열, 메세지 자체임 @ResponseBody 적어주기
	}
						//post를 제외한 get, put, ?가 다 이리 옴 따로 method 안쓰면.
//	@RequestMapping("/calculate")
//	@ResponseBody
//	public String doGet(int leftOp, int rightOp, OperatorType operator) throws ServletException, IOException {
// 			String expression = operator.getExpression(leftOp, rightOp);
// 			return expression;
//	}
}

파라미터 넘어오는 경우에만... 모든 방향으로 처리...

json 넘어오는건 윗줄...

이렇게 하면 될건데 이제 그러면 vo의 필드 이름이 중요함... 같은 이름으로 받을수잇으니까...

 

주석 다지우면

package kr.or.ddit.servlet03;

import java.io.IOException;
import javax.servlet.ServletException;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import kr.or.ddit.vo.CalculateVO;

public class CalculateController{
	@RequestMapping(value="/calculate", method=RequestMethod.POST,headers="content-type=application/json"
						, produces="application/json")
	@ResponseBody
	public CalculateVO doPostJson(@RequestBody CalculateVO vo) throws ServletException, IOException {
		return vo;
	}

	@RequestMapping(value="/calculate")
	@ResponseBody
	public String doPost(CalculateVO vo) throws ServletException, IOException {
		return vo.getExpression();
	}

}

이렇게짧아짐...wow

 

 

 

후 이제

 

이놈이 남았어요 오늘 수업 최종이예요

 

 

---------

 

상위(root)와 하위 설정파일이예요

 

 

--

@Controller

이놈이 가진 ...handler mapping이라고 정보를 수집하는애가 있는데  이 어노테이션이 없으면 정보수집을 못해요 그래서 controller에는 얘만써야해요

 

 

@required 주려면 @RequestParam 먼저 필요함 헤더에서 꺼낼건ㄴ지 파라미터에서 꺼낼건지...

 

 

이거보면 규칙성이 propertyname이 파라미터 이름이랑 같음

그거 가지고 populate 해 줬는데, 왜내면 spring에 beanutils가 내장되어있는데 심지어 performance가 더 좋음

 

validateUtils 만들었었죠

스프링 안에 이미 있어서 @Valid 걍 이거만 쓰면 됨...

 

 

1) 검증하려면, 검증 조건이 있어야 함