Skip to content

Commit

Permalink
Merge pull request #2 from Dh3356/feature/implement-restinterceptor-#1
Browse files Browse the repository at this point in the history
Implement RestInterceptor
  • Loading branch information
Dh3356 authored Nov 27, 2024
2 parents 543ad01 + 99265f2 commit 2d62be4
Show file tree
Hide file tree
Showing 4 changed files with 241 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.restful_spring.rest_interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
import org.springframework.web.cors.CorsUtils;
import org.springframework.web.servlet.HandlerInterceptor;

public abstract class RestInterceptor implements HandlerInterceptor {

protected List<RestfulPattern> restfulPatterns = List.of();

@Override
public final boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (isPreFlightRequest(request) || shouldSkip(request)) {
return true;
}
return doInternal(request, response, handler);
}

private boolean isPreFlightRequest(final HttpServletRequest request) {
return CorsUtils.isPreFlightRequest(request);
}

private boolean shouldSkip(final HttpServletRequest request) {
return this.restfulPatterns.stream()
.noneMatch(pattern -> pattern.matches(request));
}

protected boolean doInternal(HttpServletRequest request, HttpServletResponse response, Object handler) {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.restful_spring.rest_interceptor;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class RestInterceptorRegistration {

private final RestInterceptor restInterceptor;
private int order = 0;

public RestInterceptorRegistration(RestInterceptor restInterceptor) {
this.restInterceptor = restInterceptor;
}

public RestInterceptorRegistration addRestfulPatterns(RestfulPattern... restfulPatterns) {
return addRestfulPatterns(List.of(restfulPatterns));
}

public RestInterceptorRegistration addRestfulPatterns(Collection<RestfulPattern> restfulPatterns) {
restInterceptor.restfulPatterns = new ArrayList<>(restfulPatterns);
return this;
}

public RestInterceptorRegistration order(int order) {
this.order = order;
return this;
}

protected RestInterceptor getRestInterceptor() {
return restInterceptor;
}

protected int getOrder() {
return order;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.restful_spring.rest_interceptor;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

public class RestInterceptorRegistry {

private final InterceptorRegistry registry;
private final List<RestInterceptorRegistration> registrations = new ArrayList<>();

public RestInterceptorRegistry(InterceptorRegistry registry) {
this.registry = registry;
}

public RestInterceptorRegistration addInterceptor(RestInterceptor restInterceptor) {
RestInterceptorRegistration registration = new RestInterceptorRegistration(restInterceptor);
registrations.add(registration);
return registration;
}

public void build() {
this.registrations.forEach(registration -> {
RestInterceptor restInterceptor = registration.getRestInterceptor();

registry.addInterceptor(restInterceptor)
.addPathPatterns(restInterceptor.restfulPatterns.stream()
.map(RestfulPattern::getPath)
.collect(Collectors.toList()))
.order(registration.getOrder());
});
}
}
137 changes: 137 additions & 0 deletions src/main/java/com/restful_spring/rest_interceptor/RestfulPattern.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package com.restful_spring.rest_interceptor;

import jakarta.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import org.springframework.http.HttpMethod;
import org.springframework.web.util.UriTemplate;

public class RestfulPattern {

private final UriTemplate path;
private final Set<HttpMethod> methods;

private RestfulPattern(final UriTemplate path, final Set<HttpMethod> methods) {
this.path = path;
this.methods = methods;
}

public static RestfulPattern of(final String path, final Collection<HttpMethod> methods) {
return new RestfulPattern(new UriTemplate(path), new HashSet<>(methods));
}

public static RestfulPattern of(final String path, final HttpMethod method) {
return new RestfulPattern(new UriTemplate(path), Set.of(method));
}

public static RestfulPatternBuilder builder() {
return new RestfulPatternBuilder();
}

public boolean matches(final HttpServletRequest request) {
return methods.contains(HttpMethod.valueOf(request.getMethod())) && path.matches(request.getRequestURI());
}

public String getPath() {
return path.toString();
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof RestfulPattern that)) {
return false;
}

if (!methods.equals(that.methods)) {
return false;
}
return Objects.equals(path, that.path) && Objects.equals(methods, that.methods);
}

@Override
public int hashCode() {
int result = methods.hashCode();
result = 31 * result + (path != null ? path.hashCode() : 0);
return result;
}

@Override
public String toString() {
return "RestfulPattern{" +
"methods=" + methods +
", path=" + path.toString() +
'}';
}

public static class RestfulPatternBuilder {

private final Set<HttpMethod> methods;
private UriTemplate path;

public RestfulPatternBuilder() {
this.path = new UriTemplate("/**");
this.methods = new HashSet<>();
}

public RestfulPatternBuilder path(String path) {
this.path = new UriTemplate(path);
return this;
}

public RestfulPatternBuilder get() {
this.methods.add(HttpMethod.GET);
return this;
}

public RestfulPatternBuilder post() {
this.methods.add(HttpMethod.POST);
return this;
}

public RestfulPatternBuilder put() {
this.methods.add(HttpMethod.PUT);
return this;
}

public RestfulPatternBuilder delete() {
this.methods.add(HttpMethod.DELETE);
return this;
}

public RestfulPatternBuilder patch() {
this.methods.add(HttpMethod.PATCH);
return this;
}

public RestfulPatternBuilder trace() {
this.methods.add(HttpMethod.TRACE);
return this;
}

public RestfulPatternBuilder options() {
this.methods.add(HttpMethod.OPTIONS);
return this;
}

public RestfulPatternBuilder head() {
this.methods.add(HttpMethod.HEAD);
return this;
}

public RestfulPatternBuilder all() {
return get().post().put().delete().patch().trace().options().head();
}

public RestfulPattern build() {
if (methods.isEmpty()) {
return new RestfulPattern(path, Set.of(HttpMethod.values()));
}
return new RestfulPattern(path, methods);
}
}
}

0 comments on commit 2d62be4

Please sign in to comment.