avaje / avaje-jex Goto Github PK
View Code? Open in Web Editor NEWWeb routing for Jetty, Grizzly, JDK Http server
License: Apache License 2.0
Web routing for Jetty, Grizzly, JDK Http server
License: Apache License 2.0
Refer to javalin/javalin#894
This is a bit of a blow but inner is not a good long term name for this ...
/**
* Write the stream as a JSON stream with new line delimiters
* {@literal application/x-json-stream}.
*
* @param stream The stream of beans to write as json
*/
<E> Context jsonStream(Stream<E> stream);
/**
* Write the stream as a JSON stream with new line delimiters
* {@literal application/x-json-stream}.
*
* @param iterator The iterator of beans to write as json
*/
<E> Context jsonStream(Iterator<E> iterator);
Note that when using Iterator
internally it will check if the instance implements AutoCloseable
and if so will close the iterator when all elements have been written. Stream implements AutoCloseable so that also gets closed.
So when a JsonService is not explicitly set, if Jackson is present then that is used, if avaje-jsonb is present then it is used.
For people who don't know what avaje-jsonb is, TLDR - it's a source code generation approach to json binding (so light and fast). It comes with it's own underlying parser/generator but can also use jackson-core under the hood for people wanting to use that (heavier, slower but it's jackson core with a few more features and people love jackson etc).
Turn it off via ex.config.health = false;
Jex.create()
.configure(jex -> {
jex.config.health = false;
})
...
Jex.create()
.configure(it -> {
it.jetty.virtualThreads = true; // Use Loom
})
.routing(routing -> {
routing.get("/", ctx -> ctx.text("hello there"))
...
})
.port(7001)
.start();
public static void main(String[] args) {
BootJex.start();
}
package io.avaje.jex;
/**
* Start Jex using {@code @Controller} and avaje-inject, avaje-http, avaje-config.
* <p>
* - avaje-http generates the adapter for the {@code @Controller}
* - avaje-inject generates dependency injection wiring
* - avaje-config reads external configuration (application.properties|yaml, application-test.properties|yaml).
*/
public interface BootJex {
/**
* Start Jex server using {@code @Controller} with avaje-inject, avaje-http, avaje-config.
*
* <pre>{@code
* public static void main(String[] args) {
*
* BootJex.start();
* }
* }</pre>
*/
static void start() {
BootJexState.start();
}
}
Noting that the included org/eclipse/jetty/http/encoding.properties didn't get loaded when using the java module system - jpms.
Initially this leaves a question around applying filters on not found requests.
@Inject HttpClientContext client
@InjectTest
class HelloControllerTest {
@Inject HttpClientContext client;
@Test
void hello() {
HttpResponse<String> hello = client.request().path("hello")
.GET()
.asString();
assertThat(hello.statusCode()).isEqualTo(200);
}
}
HelloApi
is a java interface annotated with @Client
+ @Get
, @Post
etc ...import io.avaje.inject.test.InjectTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@InjectTest
class HelloController2Test {
@Inject static HelloApi client;
@Test
void hello() {
String hi = client.hi();
assertThat(hi).isEqualTo("hisay+yo");
}
@Test
void hello2() {
String hi = client.hi();
assertThat(hi).isEqualTo("hisay+yo");
}
}
This drops the need for 2 jetty dependencies - jetty-servlet
and jetty-security
Session support adjusts to chain the underlying handler
contextPath()
adjusted to return ""
Downsides, well, it isn't a HttpServlet
now so use of standard http servlet filters is more painful (but people would generally be using jex filters anyway so ...).
https://www.eclipse.org/jetty/documentation/jetty-11/programming-guide/index.html#pg-server-http-connector-protocol-http3
Jetty has a full implementation of HTTP3 (the only other implementation I have seen since flupke).
Refer jetty/jetty.project#6001
For jetty-10 and beyond, the default is changed to disallow all three. It is now configurable in a new UriCompliance class that can be set on HttpConfiguration
// RouteSplatTest
@Test
void when_utf8Encoded() {
String path = URLEncoder.encode("java/kotlin", StandardCharsets.UTF_8)
+ "/two/" + URLEncoder.encode("x/y", StandardCharsets.UTF_8);
HttpResponse<String> res = pair.request().path(path).get().asString();
assertThat(res.body()).isEqualTo("splats:[java/kotlin, x/y]");
assertThat(res.statusCode()).isEqualTo(200);
}
var app = Jex.create()
.routing(routing -> routing
.get("/*/one", ctx -> ctx.text("splat:" + ctx.splat(0)))
.get("/*/two/*", ctx -> ctx.text("splats:" + ctx.splat(0) +" and " + ctx.splat(1)))
.get("/*/two/*", ctx -> ctx.text("splats:" + ctx.splats()))
);
import io.avaje.jex.Role;
/**
* Create an App specific enum that implements Role.
*/
public enum AppRoles implements Role {
ADMIN,
USER
}
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Create an app specific Role annotation that uses the
* app specific role enum.
*/
@Target(value={METHOD, TYPE})
@Retention(value=RUNTIME)
public @interface Roles {
/**
* Specify the permitted roles (using app specific enum).
*/
AppRoles[] value() default {};
}
.routing(routing -> routing
.get(ctx -> ctx.text("get"))
.get("/multi", ctx -> ... ).withRoles(AppRoles.ADMIN, AppRoles.USER)
.get("/user", ctx -> ... ).withRoles(AppRoles.USER)
);
.accessManager((handler, ctx, permittedRoles) -> {
final String role = ctx.queryParam("role");
if (role == null || !permittedRoles.contains(AppRoles.valueOf(role))) {
ctx.status(401).text("Unauthorized");
} else {
ctx.attribute("authBy", role);
handler.handle(ctx);
}
})
Refer to #44
Refer to javalin/javalin#1045
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.