Skip to content

Conversation

@JangIkhwan
Copy link

완료 작업 목록

  • 프로필 이미지 변경 구현
  • 게시글 이미지 업로드 구현

주요 고민과 해결 과정

  • 오늘은 어제에 이어서 multipart 요청으로 이미지 업로드 기능을 구현해보았습니다
  • path variable을 구현하기 위해서 고민한 결과 Routing 인터페이스를 구현했습니다. Routing 인터페이스는 요청의 path가 라우팅할 핸들러의 url이 지원하는지 확인하고, 메서드를 확인한 후에 핸들러를 반환하기 위해서 사용합니다.
public interface Routing {
    boolean supportsUri(String uri);

    boolean supportsMethod(String method);

    Handler resolveHandler(Request method);
}
  • path variable 이 있는 라우팅의 경우를 처리하기 위해서 PathVariableRouting를 구현했습니다. 이 클래스는 요청 path를 처리할 수 있는지 여부를 정규식으로 검사하고, path variable을 추출하여서 request에 저장합니다.
public class PathVariableRouting implements Routing {
    private Map<String, Handler> handlerMap;
    private List<String> pathVariableNames = new ArrayList<>();
    private Pattern pattern;

    public PathVariableRouting(String uri, Map<String, Handler> handlerMap) {
        this.handlerMap = handlerMap;
        String regex = Arrays.stream(uri.split("/"))
                .map(token -> {
                    if (token.startsWith("{") && token.endsWith("}")) {
                        String varName = token.substring(1, token.length() - 1);
                        pathVariableNames.add(varName);
                        return "([^/]+)";
                    }
                    return token;
                })
                .collect(Collectors.joining("/"));

        this.pattern = Pattern.compile(regex);
    }

    @Override
    public boolean supportsUri(String uri) {
        return pattern.matcher(uri).matches();
    }

    @Override
    public boolean supportsMethod(String method) {
        return handlerMap.containsKey(method);
    }

    @Override
    public Handler resolveHandler(Request request) {
        Matcher matcher = pattern.matcher(request.getPath());

        if (matcher.matches()) {
            for (int i = 0; i < pathVariableNames.size(); i++) {
                String name = pathVariableNames.get(i);
                String value = matcher.group(i + 1); // group(1)부터 시작
                request.setParameter(name, value);
            }
        }

        return handlerMap.get(request.getMethod());
    }
}
  • RequestHandlerresolveHandler() 함수는 이와 같은 Routing 구현체를 리스트에 담아서 매 요청마다 알맞은 Handler를 찾습니다.
 private Handler resovleHandler(Request request) {
        for(Routing routing : routingTable){
            if(routing.supportsUri(request.getPath())){
                if(!routing.supportsMethod(request.getMethod())){
                    throw new MethodNotAllowedException();
                }
                return routing.resolveHandler(request);
            }
        }
        return staticResourceHandler;
    }

- 이미지가 없으면 예외 발생
- 이미지를 로컬에 저장
- uri가 정확히 일치할 때 핸들러를 매칭하는 SimpleRouting 구현
- path variable을 고려해서 핸들러와 uri를 매칭할 때 사용하는 PathVariableRouting 구현
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant