Skip to content

Commit c04e5e1

Browse files
committed
MVC Route: @SessionParam fix #1387
1 parent 443b715 commit c04e5e1

10 files changed

Lines changed: 87 additions & 16 deletions

File tree

TODO

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
* review ValueNode return type on Context, some must be Value not ValueNode.
12
* Make Session.toMap() read-only
23
* review toString on Value API (removal of QueryStringValue?)
34
* tests and coverage

jooby/src/main/java/io/jooby/Context.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,15 @@ public interface Context extends Registry {
127127
*/
128128
@Nonnull Session session();
129129

130+
/**
131+
* Find a session attribute using the given name. If there is no session or attribute under that
132+
* name a missing value is returned.
133+
*
134+
* @param name Attribute's name.
135+
* @return Session's attribute or missing.
136+
*/
137+
@Nonnull Value session(@Nonnull String name);
138+
130139
/**
131140
* Find an existing session.
132141
*

jooby/src/main/java/io/jooby/DefaultContext.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ public interface DefaultContext extends Context {
8686
return Value.create(this, name, flash().get(name));
8787
}
8888

89+
@Override default @Nonnull Value session(@Nonnull String name) {
90+
Session session = sessionOrNull();
91+
if (session != null) {
92+
return session.get(name);
93+
}
94+
return Value.missing(name);
95+
}
96+
8997
@Override default @Nonnull Session session() {
9098
Session session = sessionOrNull();
9199
if (session == null) {

jooby/src/main/java/io/jooby/ForwardingContext.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ public ForwardingContext(@Nonnull Context context) {
6565
return ctx.flash(name);
6666
}
6767

68+
@Nonnull @Override public Value session(@Nonnull String name) {
69+
return ctx.session(name);
70+
}
71+
6872
@Nonnull @Override public Session session() {
6973
return ctx.session();
7074
}

modules/jooby-apt/src/main/java/io/jooby/apt/Annotations.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import io.jooby.annotations.PathParam;
2424
import io.jooby.annotations.Produces;
2525
import io.jooby.annotations.QueryParam;
26+
import io.jooby.annotations.SessionParam;
2627
import io.jooby.annotations.TRACE;
2728

2829
import javax.annotation.Nonnull;
@@ -93,6 +94,10 @@ public interface Annotations {
9394
javax.ws.rs.QueryParam.class.getName()
9495
)));
9596

97+
Set<String> SESSION_PARAMS = unmodifiableSet(new LinkedHashSet<>(asList(
98+
SessionParam.class.getName()
99+
)));
100+
96101
/**
97102
* Cookie parameters.
98103
*/

modules/jooby-apt/src/main/java/io/jooby/internal/apt/ParamKind.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import io.jooby.Context;
99
import io.jooby.Formdata;
1010
import io.jooby.Multipart;
11+
import io.jooby.Session;
1112
import io.jooby.apt.Annotations;
1213
import io.jooby.internal.apt.asm.ContextParamWriter;
1314
import io.jooby.internal.apt.asm.NamedParamWriter;
@@ -77,7 +78,26 @@ public enum ParamKind {
7778
return new ContextParamWriter();
7879
}
7980
},
81+
SESSION_ATTRIBUTE_PARAM {
82+
@Override public Set<String> annotations() {
83+
return Annotations.SESSION_PARAMS;
84+
}
8085

86+
@Override public Method valueObject(ParamDefinition param) throws NoSuchMethodException {
87+
if (param.isOptional()) {
88+
return Context.class.getDeclaredMethod("sessionOrNull");
89+
}
90+
return Context.class.getDeclaredMethod("session");
91+
}
92+
93+
@Override public Method singleValue(ParamDefinition param) throws NoSuchMethodException {
94+
return Context.class.getDeclaredMethod("session", String.class);
95+
}
96+
97+
@Override public ParamWriter newWriter() {
98+
return new NamedParamWriter();
99+
}
100+
},
81101
QUERY_PARAM {
82102
@Override public Set<String> annotations() {
83103
return Annotations.QUERY_PARAMS;
@@ -163,18 +183,7 @@ public enum ParamKind {
163183
return new NamedParamWriter();
164184
}
165185
},
166-
SESSION_PARAM {
167-
@Override public Set<String> annotations() {
168-
return Collections.emptySet();
169-
}
170186

171-
@Override public Method valueObject(ParamDefinition param) throws NoSuchMethodException {
172-
if (param.isOptional()) {
173-
return Context.class.getDeclaredMethod("sessionOrNull");
174-
}
175-
return Context.class.getDeclaredMethod("session");
176-
}
177-
},
178187
ROUTE_PARAM {
179188
@Override public Set<String> annotations() {
180189
return Collections.emptySet();

modules/jooby-apt/src/test/java/source/Issue1387.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.jooby.annotations.ContextParam;
44
import io.jooby.annotations.GET;
55
import io.jooby.annotations.Path;
6+
import io.jooby.annotations.SessionParam;
67

78
import java.util.Map;
89

@@ -30,4 +31,14 @@ public Data1387 attributeComplex(@ContextParam Data1387 data) {
3031
public Map<String, Object> attributes(@ContextParam Map<String, Object> attributes) {
3132
return attributes;
3233
}
34+
35+
@GET("/session")
36+
public String session(@SessionParam String userId) {
37+
return userId;
38+
}
39+
40+
@GET("/session/int")
41+
public int session(@SessionParam int userId) {
42+
return userId;
43+
}
3344
}

modules/jooby-apt/src/test/java/tests/Issue1387.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.jooby.Context;
44
import io.jooby.MockContext;
5+
import io.jooby.Session;
56
import io.jooby.apt.MvcHandlerCompilerRunner;
67
import io.jooby.internal.MockContextHelper;
78
import org.junit.jupiter.api.Test;
@@ -48,4 +49,25 @@ public void shouldInjectContextParam() throws Exception {
4849
;
4950
}
5051

52+
@Test
53+
public void shouldInjectSessionParam() throws Exception {
54+
new MvcHandlerCompilerRunner(new source.Issue1387())
55+
.compile("/1387/session", handler -> {
56+
MockContext ctx = MockContextHelper.mockContext();
57+
assertEquals(null, handler.apply(ctx));
58+
59+
Session session = ctx.session();
60+
session.put("userId", "abc");
61+
assertEquals("abc", handler.apply(ctx));
62+
})
63+
.compile("/1387/session/int", handler -> {
64+
MockContext ctx = MockContextHelper.mockContext();
65+
Session session = ctx.session();
66+
session.put("userId", 123);
67+
68+
assertEquals(123, handler.apply(ctx));
69+
})
70+
;
71+
}
72+
5173
}

modules/jooby-test/src/main/java/io/jooby/MockContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ MockContext setMethod(@Nonnull String method) {
8787

8888
@Nonnull @Override public Session session() {
8989
if (session == null) {
90-
session = new MockSession();
90+
session = new MockSession(this);
9191
}
9292
return session;
9393
}

modules/jooby-test/src/main/java/io/jooby/MockSession.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* Mock session.
1717
*/
1818
public class MockSession implements Session {
19+
private MockContext ctx;
1920
private String sessionId;
2021

2122
private Map<String, String> data = new HashMap<>();
@@ -29,7 +30,8 @@ public class MockSession implements Session {
2930
*
3031
* @param sessionId Session ID.
3132
*/
32-
public MockSession(@Nonnull String sessionId) {
33+
public MockSession(@Nonnull MockContext ctx, @Nonnull String sessionId) {
34+
this.ctx = ctx;
3335
this.sessionId = sessionId;
3436
this.creationTime = Instant.now();
3537
this.lastAccessedTime = Instant.now();
@@ -38,8 +40,8 @@ public MockSession(@Nonnull String sessionId) {
3840
/**
3941
* Mock session with a random ID.
4042
*/
41-
public MockSession() {
42-
this(UUID.randomUUID().toString());
43+
public MockSession(@Nonnull MockContext ctx) {
44+
this(ctx, UUID.randomUUID().toString());
4345
}
4446

4547
@Nonnull @Override public String getId() {
@@ -48,7 +50,7 @@ public MockSession() {
4850

4951
@Nonnull @Override public ValueNode get(@Nonnull String name) {
5052
return Optional.ofNullable(data.get(name))
51-
.map(value -> Value.create(null, name, value))
53+
.map(value -> Value.create(ctx, name, value))
5254
.orElse(Value.missing(name));
5355
}
5456

0 commit comments

Comments
 (0)