스프링 이전에 Servlet을 직접 사용할땐 URL마다 하나하나 만들어야하고

 

각각의 설정하기가 매우 복잡했다.

 

이것을 해결하는것이 Spring의 dispatcherServlet이다.

매번 반복작업하던 비생산적인 작업들을 스프링이 뒷단에서 직업해주고 있다.

 

HandlerMapping 으로 클라이언트가 서버에 요청할때 접근할 수 있게 해주고

HandlerAdapter로 요청에 맞는 기능을 찾아준다.

//스프링 내부 소스코드
//스프링이 구동될떄 초기에 여러 형태를 미리 준비해놓을 수 있다.

protected void initStrategies(ApplicationContext context) {
    this.initMultipartResolver(context);
    this.initLocaleResolver(context);
    this.initThemeResolver(context);
    this.initHandlerMappings(context);
    this.initHandlerAdapters(context);
    this.initHandlerExceptionResolvers(context);
    this.initRequestToViewNameTranslator(context);
    this.initViewResolvers(context);
    this.initFlashMapManager(context);
}

또 한 여러 작업을 하고 클라이언트에게 다시 송출할때도

viewResolver로 보내준다.

viewResolver는 기본으로 제공해주지만 아래처럼 커스텀해서 사용할 수 있다.

//viewResolver 설정해서 간단하게 사용하기

@Configuration
@ComponentScan
public class OneServletWebConfig {

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
}

 

요청을 받고 요청의 맞는 기능을 구현하고 형태에 맞게 화면에 전송하는 것을 다구현하지않고

스프링의  dispatcherServlet이 구현해준다.

TDD 테스트 주도 개발이란?

 

개발을 먼저하지 않고 테스트코드를 먼저 만든다.

시간이 많이 걸리는 단점은 있지만 프로젝트를 유지보수할때 큰효과가 나타난다.

 

mocha,should는 단위테스트이다.

Ex)함수테스트 : 함수별로 테스트한다.

 

mocha 모카란?

테스트에 사용하는 라이브러리

테스트 코드를 작성하면 테스트를 실행시켜주는것

 

테스트수트 : 테스트 환경을 꾸며준다. describe()를 사용한다.

 

테스트케이스 : 실제 테스트를 말하며 모카에서는 it()을 구현한다.

 

 

설치방법 : Npm install mocha —saver-dev

-dev : -dev를 하면 개발환경에서 필요하다는 말이다.

 

테스트 실행방법

node_modules/.bin/mocha [테스트파일명] 를 실행한다.

 

테스트 코드

const utils = require('./testUtils.js');
const assert = require('assert');

//mocha는 node로 실행할 수 없다.
describe('utils.js모듈의 capitialize 함수', ()=>{
    it('문자열 첫번째 문자를 대문자로 변환한다.', () =>{
        //테스트 코드 작성
        const result = utils.capitialize('hello');
        assert.equal(result, 'Hello');
    })

    it('문자열 첫번째 문자를 소문자로 변환한다.', () =>{
        //테스트 코드 작성
        const result = utils.capitialize('hello');
        assert.equal(result, 'hello');
    })
})

 

 

 

Should.js

테스트에 사용하는 라이브러리

슈드는 검증 라이브러리 이다.

예제 목록:https://github.com/tj/should.js/  

 

설치하기: npm I should —save-dev

테스트 코드

const utils = require('./testUtils.js');
const should = require('should');

//mocha는 node로 실행할 수 없다.
describe('utils.js모듈의 capitialize 함수', ()=>{
    it('문자열 첫번째 문자를 대문자로 변환한다.', () =>{
        //테스트 코드 작성
        const result = utils.capitialize('hello');
        result.should.be.equal('Hello');

    })

    it('문자열 첫번째 문자를 소문자로 변환한다.', () =>{
        //테스트 코드 작성
        const result = utils.capitialize('hello');
        result.should.be.equal(result, 'hello');
    })
})

 

슈퍼테스트

통합테스트에 사용한다.

Ex)api의 기능테스트

내부적으로 express를 구동시키고 테스트코드에서 작성된 시나리오대로 결과를 검증한다.

 

예제:https://github.com/visionmedia/supertest

 

설치하기:npm I supertest —save-dev

 

const request = require('supertest');

const express = require('express');



const app = express();



app.get('/user', function(req, res) {

  res.status(200).json({ name: 'john' });

});



request(app)

  .get('/user')

  .expect('Content-Type', /json/)

  .expect('Content-Length', '15')

  .expect(200)

  .end(function(err, res) {

    if (err) throw err;

  });

 

예제처럼 API의결과를 시나리오대로 테스트해보는것이다.

그럼 Servlet이란? 

자바엔터프라이즈 에디션에서 제공하는 웹을 만들 수 있게 제공하는것이다.

요청당 쓰레드를 사용한다.

 

지금은 직접 사용하진않지만 Spring의 기초뼈대이다.

 

서블릿은 단독으로 실행할 수 없고 서블릿 컨테이너가 실행해야한다.

 

서블릿 스펙을 준수하는 컨테이너(톰캣)가 서블릿의 라이플사이클을 이용해 실행한다.

 

라이플사이클

서블릿컨테이너가 서블릿 인스턴스의 init메소드를 호출하여 초기화한다.

 

서블릿 컨테이너가 구동될때 서블릿 리스너가 DB에 연결하고 여러가지 서블릿에 제공할 수 있다.

서블릿컨텍스트에서 꺼내서 사용한다.

 

서블릿 컨테이너가 종료할때 서블릿 리스너를 이용해 DB커넥션을 반납한다.

 

 

Java servlet API은 런타임때 빠진다. 컨테이너가 가지고있다.

 

Servlet 예제

public class HelloServlet extends HttpServlet {

    //원시적인 ServletApplication
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet");
        ApplicationContext applicationContext = (ApplicationContext) getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

        HelloService helloService = applicationContext.getBean(HelloService.class);
        resp.getWriter().println("Hello "+ helloService.getName());
    }

    private Object getName() {
        return getServletContext().getAttribute("name");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }

    @Override
    public void init() throws ServletException {
        System.out.println("init");
    }

    @Override
    public void destroy() {
        System.out.println("destroy");
    }
}

 

서블릿에서 사용하는 두가지 기능

 

서블릿리스너

servletlistener

public class MyListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("contextInitialized");
        //서블릿보다 윗개념이기에 서블릿에서 꺼내서 사용할 수 있다.
        sce.getServletContext().setAttribute("name","사용");
    }

    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("contextDestroyed");
    }
}

-서블릿 컨테이너보다 윗개념

-서블릿컨테이너에서 발생하는 이벤트에 특정한 코드를 실행할때 사용한다.

-종료될때도 사용할 수 있다.

-(DB연결등 여러가지)

 

서블릿필터

servletfilter

public class MyFilter implements Filter {
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Filter");
        //체인형식으로 다음필터에게 전달해주어야한다.
        filterChain.doFilter(servletRequest, servletResponse);
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("My Filter init");
    }

    public void destroy() {
        System.out.println("My Filter destroy");
    }
}

-필터를 거쳐 서블릿에간다

-요청이 들어왔을때 서블릿으로 가기전에 전처리할때 사용한다.

-여러개의 서블리셍 추가적인 작업을 하거나 특정한 URL에 적용할 수 있다.

-체인 구조로 순차적으로 실행된다.

+ Recent posts