Skip to content

Commit b346366

Browse files
gregturnodrotbohm
authored andcommitted
#408 - Form relative links when outside a Spring web request
If forming a link outside a Spring web request, fallback to relative links. Original pull-request: #410. Related issues: #330, #143, #516.
1 parent c784df9 commit b346366

File tree

3 files changed

+22
-31
lines changed

3 files changed

+22
-31
lines changed

src/main/java/org/springframework/hateoas/mvc/ControllerLinkBuilder.java

+10-3
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@
1717

1818
import static org.springframework.util.StringUtils.*;
1919

20-
import lombok.RequiredArgsConstructor;
21-
import lombok.experimental.Delegate;
22-
2320
import java.lang.reflect.Method;
2421
import java.net.URI;
2522
import java.util.Map;
2623

2724
import javax.servlet.http.HttpServletRequest;
2825

26+
import lombok.RequiredArgsConstructor;
27+
import lombok.experimental.Delegate;
28+
2929
import org.springframework.hateoas.Link;
3030
import org.springframework.hateoas.TemplateVariables;
3131
import org.springframework.hateoas.core.AnnotationMappingDiscoverer;
@@ -53,6 +53,7 @@
5353
* @author Kevin Conaway
5454
* @author Andrew Naydyonock
5555
* @author Oliver Trosien
56+
* @author Greg Turnquist
5657
*/
5758
public class ControllerLinkBuilder extends LinkBuilderSupport<ControllerLinkBuilder> {
5859

@@ -257,11 +258,17 @@ public String toString() {
257258
* Returns a {@link UriComponentsBuilder} obtained from the current servlet mapping with scheme tweaked in case the
258259
* request contains an {@code X-Forwarded-Ssl} header, which is not (yet) supported by the underlying
259260
* {@link UriComponentsBuilder}.
261+
*
262+
* If no {@link RequestContextHolder} exists (you're outside a Spring Web call), fall back to relative URIs.
260263
*
261264
* @return
262265
*/
263266
static UriComponentsBuilder getBuilder() {
264267

268+
if (RequestContextHolder.getRequestAttributes() == null) {
269+
return UriComponentsBuilder.fromPath("/");
270+
}
271+
265272
HttpServletRequest request = getCurrentRequest();
266273
UriComponentsBuilder builder = ServletUriComponentsBuilder.fromServletMapping(request);
267274

src/test/java/org/springframework/hateoas/mvc/ControllerLinkBuilderOutsideSpringMvcUnitTest.java

+10-11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import org.junit.Before;
88
import org.junit.Test;
9+
10+
import org.springframework.hateoas.Link;
911
import org.springframework.web.context.request.RequestContextHolder;
1012

1113
/**
@@ -24,18 +26,15 @@ public void setUp() {
2426
}
2527

2628
/**
27-
* @see #342
29+
* @see #408
2830
*/
29-
@Test(expected = IllegalStateException.class)
30-
public void createsLinkToMethodOnParameterizedControllerRoot() {
31-
32-
try {
33-
linkTo(methodOn(ControllerLinkBuilderUnitTest.PersonsAddressesController.class, 15)
34-
.getAddressesForCountry("DE")).withSelfRel();
35-
} catch (IllegalStateException e) {
36-
assertThat(e.getMessage(), equalTo("Could not find current request via RequestContextHolder. Is this being called from a Spring MVC handler?"));
37-
throw e;
38-
}
31+
@Test
32+
public void requestingLinkOutsideWebRequest() {
33+
34+
Link link = linkTo(methodOn(ControllerLinkBuilderUnitTest.PersonsAddressesController.class, 15)
35+
.getAddressesForCountry("DE")).withSelfRel();
36+
37+
assertThat(link, is(new Link("/people/15/addresses/DE").withSelfRel()));
3938
}
4039

4140
}

src/test/java/org/springframework/hateoas/mvc/ControllerLinkBuilderUnitTest.java

+2-17
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.junit.Test;
2929
import org.junit.rules.ExpectedException;
3030
import org.mockito.Mockito;
31+
3132
import org.springframework.hateoas.Identifiable;
3233
import org.springframework.hateoas.Link;
3334
import org.springframework.hateoas.TemplateVariable;
@@ -39,7 +40,6 @@
3940
import org.springframework.web.bind.annotation.RequestBody;
4041
import org.springframework.web.bind.annotation.RequestMapping;
4142
import org.springframework.web.bind.annotation.RequestParam;
42-
import org.springframework.web.context.request.RequestContextHolder;
4343
import org.springframework.web.util.UriComponents;
4444
import org.springframework.web.util.UriComponentsBuilder;
4545

@@ -53,6 +53,7 @@
5353
* @author Greg Turnquist
5454
* @author Kevin Conaway
5555
* @author Oliver Trosien
56+
* @author Greg Turnquist
5657
*/
5758
public class ControllerLinkBuilderUnitTest extends TestUtils {
5859

@@ -461,22 +462,6 @@ public void linksToMethodWithRequestParamImplicitlySetToFalse() {
461462
assertThat(link.getHref(), endsWith("/bar"));
462463
}
463464

464-
/**
465-
* @see #342
466-
*/
467-
@Test
468-
public void mentionsRequiredUsageWithinWebRequestInException() {
469-
470-
exception.expect(IllegalStateException.class);
471-
exception.expectMessage("request");
472-
exception.expectMessage("Spring MVC");
473-
474-
RequestContextHolder.setRequestAttributes(null);
475-
476-
linkTo(methodOn(ControllerLinkBuilderUnitTest.PersonsAddressesController.class, 15).getAddressesForCountry("DE"))
477-
.withSelfRel();
478-
}
479-
480465
/**
481466
* @see #398
482467
*/

0 commit comments

Comments
 (0)