Skip to content

Commit

Permalink
added redirect methods in the Response class
Browse files Browse the repository at this point in the history
  • Loading branch information
Gmugra committed Dec 28, 2020
1 parent d968c18 commit 502b102
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 6 deletions.
53 changes: 51 additions & 2 deletions core/src/main/java/net/cactusthorn/routing/Response.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.cactusthorn.routing;

import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -8,9 +9,28 @@
import java.util.Optional;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

public final class Response {

static class Redirect {
private int code;
private URI uri;

Redirect(int code, URI uri) {
this.code = code;
this.uri = uri;
}

int code() {
return code;
}

URI uri() {
return uri;
}
}

private int statusCode;
private Object body;
private String contentType;
Expand All @@ -22,6 +42,8 @@ public final class Response {
private Map<String, List<Integer>> intHeaders = new HashMap<>();
private Map<String, List<Long>> dateHeaders = new HashMap<>();

private Redirect redirect;

// @formatter:off
private Response(
int statusCode,
Expand All @@ -33,7 +55,8 @@ private Response(
List<Cookie> cookies,
Map<String, List<String>> headers,
Map<String, List<Integer>> intHeaders,
Map<String, List<Long>> dateHeaders) {
Map<String, List<Long>> dateHeaders,
Redirect redirect) {
this.statusCode = statusCode;
this.body = body;
this.contentType = contentType;
Expand All @@ -44,6 +67,7 @@ private Response(
this.headers = headers;
this.intHeaders = intHeaders;
this.dateHeaders = dateHeaders;
this.redirect = redirect;
}
// @formatter:on

Expand Down Expand Up @@ -91,6 +115,10 @@ public Map<String, List<Long>> dateHeaders() {
return dateHeaders;
}

public Optional<Redirect> redirect() {
return Optional.ofNullable(redirect);
}

public static final class Builder {

private static final int DEFAULT_STATUS_CODE = 200;
Expand All @@ -105,6 +133,7 @@ public static final class Builder {
private final Map<String, List<Integer>> intHeaders = new HashMap<>();
private final Map<String, List<Long>> dateHeaders = new HashMap<>();
private boolean skipProducer;
private Redirect redirect;

private Builder() {
}
Expand Down Expand Up @@ -282,13 +311,33 @@ public Builder addDateHeader(String name, long date) {
return this;
}

public Builder movedTemporarily(URI uri) {
redirect = new Redirect(HttpServletResponse.SC_MOVED_TEMPORARILY, uri);
return this;
}

public Builder movedPermanently(URI uri) {
redirect = new Redirect(HttpServletResponse.SC_MOVED_PERMANENTLY, uri);
return this;
}

public Builder seeOther(URI uri) {
redirect = new Redirect(HttpServletResponse.SC_SEE_OTHER, uri);
return this;
}

public Builder redirect(int statusCode, URI uri) {
redirect = new Redirect(statusCode, uri);
return this;
}

public Response build() {
List<Cookie> unmodifiableCookies = Collections.unmodifiableList(cookies);
Map<String, List<String>> unmodifiableHeaders = Collections.unmodifiableMap(headers);
Map<String, List<Integer>> unmodifiableIntHeaders = Collections.unmodifiableMap(intHeaders);
Map<String, List<Long>> unmodifiableDateHeaders = Collections.unmodifiableMap(dateHeaders);
return new Response(statuscode, bbody, contenttype, ttemplate, characterencoding, skipProducer, unmodifiableCookies,
unmodifiableHeaders, unmodifiableIntHeaders, unmodifiableDateHeaders);
unmodifiableHeaders, unmodifiableIntHeaders, unmodifiableDateHeaders, redirect);
}
}

Expand Down
16 changes: 12 additions & 4 deletions core/src/main/java/net/cactusthorn/routing/RoutingServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import net.cactusthorn.routing.EntryPointScanner.EntryPoint;
import net.cactusthorn.routing.RoutingConfig.ConfigProperty;
import net.cactusthorn.routing.PathTemplate.PathValues;
import net.cactusthorn.routing.Response.Redirect;
import net.cactusthorn.routing.annotation.*;
import net.cactusthorn.routing.convert.ConverterException;
import net.cactusthorn.routing.producer.Producer;
Expand Down Expand Up @@ -155,21 +156,28 @@ private void produce(HttpServletRequest req, HttpServletResponse resp, EntryPoin

private void produce(HttpServletRequest req, HttpServletResponse resp, EntryPoint entryPoint, Response response) throws IOException {

if (response.statusCode() != HttpServletResponse.SC_OK) {
resp.setStatus(response.statusCode());
}

response.cookies().forEach(c -> resp.addCookie(c));

response.headers().entrySet().forEach(e -> e.getValue().forEach(v -> resp.addHeader(e.getKey(), v)));
response.intHeaders().entrySet().forEach(e -> e.getValue().forEach(v -> resp.addIntHeader(e.getKey(), v)));
response.dateHeaders().entrySet().forEach(e -> e.getValue().forEach(v -> resp.addDateHeader(e.getKey(), v)));

if (response.redirect().isPresent()) {
Redirect redirect = response.redirect().get();
resp.setHeader("Location", redirect.uri().toString());
resp.setStatus(redirect.code());
return;
}

resp.setCharacterEncoding(response.characterEncoding().orElse(responseCharacterEncoding));

String contentType = response.contentType().orElse(entryPoint.produces());
resp.setContentType(contentType);

if (response.statusCode() != HttpServletResponse.SC_OK) {
resp.setStatus(response.statusCode());
}

String template = response.template().orElse(entryPoint.template());

if (response.skipProducer()) {
Expand Down
42 changes: 42 additions & 0 deletions core/src/test/java/net/cactusthorn/routing/ResponseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

import static org.junit.jupiter.api.Assertions.*;

import java.net.URI;
import java.net.URISyntaxException;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.junit.jupiter.api.Test;

import net.cactusthorn.routing.Response.Redirect;

public class ResponseTest {

@Test //
Expand Down Expand Up @@ -88,4 +94,40 @@ public void skipProducer() {
response = Response.builder().skipProducer().build();
assertTrue(response.skipProducer());
}

@Test //
public void seeOther() throws URISyntaxException {
URI uri = new URI("/xxx");
Response response = Response.builder().seeOther(uri).build();
Redirect redirect = response.redirect().get();
assertEquals(HttpServletResponse.SC_SEE_OTHER, redirect.code());
assertEquals(uri, redirect.uri());
}

@Test //
public void movedTemporarily() throws URISyntaxException {
URI uri = new URI("/yyy");
Response response = Response.builder().movedTemporarily(uri).build();
Redirect redirect = response.redirect().get();
assertEquals(HttpServletResponse.SC_MOVED_TEMPORARILY, redirect.code());
assertEquals(uri, redirect.uri());
}

@Test //
public void movedPermanently() throws URISyntaxException {
URI uri = new URI("/zzz");
Response response = Response.builder().movedPermanently(uri).build();
Redirect redirect = response.redirect().get();
assertEquals(HttpServletResponse.SC_MOVED_PERMANENTLY, redirect.code());
assertEquals(uri, redirect.uri());
}

@Test //
public void redirect() throws URISyntaxException {
URI uri = new URI("/rrr");
Response response = Response.builder().redirect(300, uri).build();
Redirect redirect = response.redirect().get();
assertEquals(300, redirect.code());
assertEquals(uri, redirect.uri());
}
}
23 changes: 23 additions & 0 deletions core/src/test/java/net/cactusthorn/routing/RoutingServletTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
Expand Down Expand Up @@ -107,6 +109,11 @@ public Response responseAll() {
return Response.builder().skipProducer().setBody("FROM RESPONSE").setCharacterEncoding("KOI8-R").setTemplate("TTT")
.setStatus(201).addCookie(cookie).addHeader("h", "v").addIntHeader("hi", 10).addDateHeader("hd", 20L).build();
}

@GET @Path("api/redirect") //
public Response redirect() throws URISyntaxException {
return Response.builder().seeOther(new URI("/xyz")).build();
}
}

public static class EntryPoint1Provider implements ComponentProvider {
Expand Down Expand Up @@ -357,4 +364,20 @@ public void responseAll() throws ServletException, IOException {
assertEquals("hd", dateHeaderName.getValue());
assertEquals(20L, dateHeaderValue.getValue());
}

@Test //
public void redirect() throws ServletException, IOException {
Mockito.when(req.getPathInfo()).thenReturn("/api/redirect");

servlet.doGet(req, resp);

ArgumentCaptor<String> header = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<Integer> code = ArgumentCaptor.forClass(Integer.class);

Mockito.verify(resp).setStatus(code.capture());
Mockito.verify(resp).setHeader(Mockito.eq("Location"), header.capture());

assertEquals("/xyz", header.getValue());
assertEquals(303, code.getValue());
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package net.cactusthorn.routing.demo.jetty.entrypoint;

import java.net.URI;
import java.net.URISyntaxException;

import javax.inject.Inject;

import net.cactusthorn.routing.Response;
import net.cactusthorn.routing.annotation.DefaultValue;
import net.cactusthorn.routing.annotation.GET;
import net.cactusthorn.routing.annotation.Path;
Expand Down Expand Up @@ -33,4 +37,9 @@ public String doit(@PathParam("var") int in, @DefaultValue("10.5") @QueryParam("
public String empty(@PathParam("var") @DefaultValue("DEFAULT") String sss) {
return "|" + sss + "| :: " + this.getClass().getSimpleName() + "@" + this.hashCode();
}

@GET @Path("/seeother") //
public Response seeother() throws URISyntaxException {
return Response.builder().seeOther(new URI("/rest/api/test30?test=33.45")).build();
}
}

0 comments on commit 502b102

Please sign in to comment.