Misc
FileRenderer throw exceptionasyncRequestTimeout enforceSsl javalin-servlet separately (rejected)WebSocket
wsBefore/wsAfter and wsExceptionmaybe formParamMap is good to support nested form data.
Rewriting to be based on Java 8 instead of Kotlin, but still be Kotlin-viable.
Under certain circumstances, pulling 5 kotlin related libs, including sdk might not be acceptable.
I remember there was discussion about it some time ago and I could see couple valid points there.
Java is the language (IMO) that lacks good framework like Javalin, in Kotlin, there are alternatives.
I think (I'm not sure though) that majority of users actually come from Java, and Kotlin users wouldn't probably even notice it, so ...
@kran What is nested form data?
@majorpasza There are mostly upsides to rewriting to Java, except for one thing... It has to be written in Java. I didn't think that was so bad until I actually started rewriting it. I've become very accustomed to Kotlin over the years, and going back to Java was kind of a shock. The majority of users use Kotlin (although it's very close to 50/50), but that's not really an argument. As you say, they wouldn't really notice. Javalin is almost two years old now, and no one has complained about the Kotlin dependencies yet, so it doesn't appear to be a problem. It's probably mainly something which bothers me and other people working on the project. All things considered, I think it's better to spend time on new features and API improvements, compared to a Java rewrite.
@tipsy
form field's name likes: fld[] or fld[name], they should be mapped into array or map, and the key should be just "fld", but not "fld[]" or "fld[name]".
data class student(var name:String = "kangkang", var age : Date? = null)
//request json: {"name":"jan","date":"1553741222"} ps: date is CST Unix timestamp CST:2019-03-28 10:47:02
val student = Context.bodyAsClass(Student::class.java)
println(student.age) //1970-1-1 00:00.000 Date GMT = CST + 8 why?
Can the new version be just a different time zone? Thank you very much for your help.
Hello @tipsy! Great work that you have done! After I use Spark in some projects I would enjoy to use Javalin. I have some issues to use Javalin in Google App Engine. I will appreciate a lot that you implement something like SparkFilter. Thank you.
@kran can you show me in code?
@fuuqiu This is not really related to Javalin, it's Jackson. You can configure your own Jackson mapper by calling JavalinJackson.configure(...)
@inaiat thank you! I'm not sure what "something like SparkFilter would mean in this sense", but it's possible to do this:
@WebServlet(urlPatterns = ["/rest/*"], name = "MyServlet")
class MyServlet : HttpServlet() {
val javalin = EmbeddedJavalin()
.get("/rest") { ctx -> ctx.result("Hello!") }
.createServlet()
override fun service(req: HttpServletRequest, resp: HttpServletResponse) {
javalin.service(req, resp)
}
}
Javalin 3 will make the process of creating a JavalinServlet easier than it currently is.
@tipsy In my apps with sparkjava I use in this way:
@WebFilter(
filterName = "InitFilter", urlPatterns = {"/*"},
initParams = {
@WebInitParam(name = "applicationClass", value = "AppFilter")
})
public class AppFilter extends spark.servlet.SparkFilter {
}
SparkFilter implements javax.servlet.Filter. The implementation of SparkFilter is here: https://github.com/perwendel/spark/blob/master/src/main/java/spark/servlet/SparkFilter.java
Thanks.
@tipsy Thank you very much, I am negligent, I found the relevant configuration of jackson in the configuration, and now it has been modified. If you can add some data class data verification in version 3.0, I think this will be a very good function.
sorry for my weak english.
here is the code.
form:
<form method="post" action="/form">
<input type="checkbox" name="sel[]" value="x"/>
<input type="checkbox" name="sel[]" value="y"/>
<input type="text" name="user[age]" />
<input type="text" name="user[name]"/>
<input type="submit">
</form>
handler:
app.post("/form", ctx -> {
Iterator<Map.Entry<String, List<String>>> iter = ctx.formParamMap().entrySet().iterator();
iter.forEachRemaining(it -> {
System.out.printf("%s => %s\n", it.getKey(), it.getValue().toString());
});
});
output:
sel%5B%5D => [x, y]
user%5Bage%5D => [dfdf]
user%5Bname%5D => [1]
keys are encoded and include [].
in other languages/frameworks, like PHP, the struct is like this:
array(2) {
["sel"]=>array(2) {
[0]=>string(1) "x"
[1]=>string(1) "y"
}
["user"]=>array(2) {
["age"]=>string(2) "11"
["name"]=>string(2) "22"
}
}
@tipsy Support for kotlin coroutines please
Being able to launch coroutines and let them do things async-ly and independent of the req/resp flow would be great
@asad-awadia currently you can do ctx.result(myFuture), why would coroutines be an improvement?
Edit: There's this for converting a coroutine to a future: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-jdk8/kotlinx.coroutines.future/kotlinx.coroutines.-coroutine-scope/future.html
@tipsy
delays(some-time) and then triggers a socket send to the client is extremely handyI'm not saying coroutines aren't nice, but you don't really have to deal with async at all in Javalin (at least that's the idea). You should be able to write all your code with coroutines if you do somthing like ctx.result(futurify{coroutine})? Then Javalin will take care of the future part.
Interoperability and "sameness" are key concerns for Javalin, so I don't want to introduce a concept that will only benefit Kotlin users.
Let me start by saying I love this project. Of all the options available for Java, Javalin is light-weight and easy to work with. I was able to write a simple MVC framework (similar to ASP.NET Core) that uses annotation processing to build Javalin route definitions at compile time. Javalin makes a great core to my web stack.
One of things I found myself doing was using a 404 handler to support my single-page applications. I have to be careful because I am using enableStaticFiles. If a route doesn't match, I need to make sure it looks for a static file first and then fallback on my SPA. The challenge there is I need to ignore 404's returned by my REST API and non-GET requests. A short-hand for this would be useful...
A short-hand for top-level error handling would be nice, too. Right now, I just write this:
app.exception(Exception.class, (e, ctx) -> {
logger.error("Encountered an unhandled exception.", e);
ctx.status(500);
});
Again, that works, but I could see most users not wanting to deal with that. A simple app.unhandledException((e, ctx) -> ...) would be nice. It's more explicit.
Honestly, I love how small this project is. I'd hate to see it get weighed down with features I'd never use. There's plenty of room for little conveniences, though. I feel like there was something else I had on my wish list. If I remember it, I will be sure to share. Thanks!
@jehugaleahsa thank you very much! There is a single page handler already:
app.enableSinglePageMode("path", "filePath") // catch 404s and return file-content as response body
I think it does exactly what you want (?).
For your second point, I'm not sure you save that much?
app.exception(Exception.class, (e, ctx) -> {});
app.unhandledException((e, ctx) -> {});
Why do you think this is better? One of my main goals for 3.0 is to slim down the number of methods on the Javalin class, so I don't think I'll add this one.
Hello,
Is it possible to see code helpers or docs to build micro-services architecture using Javalin ? :)
javalin how to integrated with jpa,redis ,i try to use it for some small system
@Nezteb Swagger support would be great, but I don't have any good ideas for how to solve it. If you want to try I'd be happy to help.
@scorsi Could you be a bit more specific? Are you talking about infrastructure, project structure, or something else?
@kindywu What do you mean support? You can use both of them fine, what would the support include?
@scorsi Could you be a bit more specific? Are you talking about infrastructure, project structure, or something else?
Hey @tipsy,
I'm talking about infrastructure and some code inside Javalin to handle micro-services, something like:
import io.javalin.Context
import io.javalin.Javalin
import io.javalin.apibuilder.ApiBuilder
import io.javalin.apibuilder.ApiBuilder.get
// JAVALIN INTERNAL CODE
interface Microservice {
fun route()
}
fun Javalin.microservice(path: String, microservice: MyMicroservice) {
routes {
ApiBuilder.path(path) { microservice.route() }
}
}
// END OF JAVALIN INTERNAL CODE
object MyMicroservice : Microservice {
override fun route() {
get("/toto", this::getToto)
}
private fun getToto(ctx: Context) {
ctx.result("Hello World")
}
}
fun main() {
val app = Javalin.create().start(7000)
app.microservice("/my-microservice", MyMicroservice)
}
The goal is to have a micro service per jar file (Gradle/Maven project) and to easily implement them like the app function. It should delegate more easily the code.
I don't know if that code is working with different Gradle project since it uses the io.javalin.apibuilder.ApiBuilder.staticJavalin instance.
That code may be bad.
_EDIT:_
Or may be to explain how to do micro-services with multiple Javalin application in a tutorial ? ;)
Hi, what about implementing JSR 380 Bean validation 2.0?
Then we could use some of these goodies:
@NotNull – validates that the annotated property value is not null
@AssertTrue – validates that the annotated property value is true
@Size – validates that the annotated property value has a size between the attributes min and max; can be applied to String, Collection, Map, and array properties
@Min – validates that the annotated property has a value no smaller than the value attribute
@Max – validates that the annotated property has a value no larger than the value attribute
@Email – validates that the annotated property is a valid email address
And this would not have to be necessary:
// validate a json body:
MyObject myObject = ctx.bodyValidator(MyObject.class)
.check(obj -> obj.val > 0 && obj.val < 5)
.getOrThrow();
But I may be missing something and perhaps it is easy to plug my own validation already.
Some links:
[1] https://beanvalidation.org/2.0/
[2] https://www.baeldung.com/javax-validation
@vrozkovec I'm fine with that, but it would have to be an optional dependency. Would you like to submit a PR?
@scorsi I'm having some trouble understanding. You want to create one Javalin-instance per endpoint?
@tipsy when should be PR ready to make it to 3.0?
@vrozkovec The preliminary completion date is set to June, so some time before that. I will be releasing alpha/beta builds though, the first alpha version was released today.
I would like for an easy and simple way to deploy javalin on serverless environments (aws, google...)
Protobuf over rest?
@asad-awadia have a look at this issue: https://github.com/tipsy/javalin/issues/453
What support is required?
@tipsy nvm then lol
Hi, is it possible to add a way to throw my own exception when validating request body instead use getOrThrow in check?
ctx.bodyValidator(MyObject.class)
.check(obj -> obj.val > 0 && obj.val < 5)
.getOrThrow();
@vinigmoraes The API for this has changed a bit with 3.0, the last call is just called get() now. If you'd like, you could add a getOrThrow which takes an exception ?
Would it be possible to make the size of thread-pool (min, max) configurable for the integrated Jetty?
I'd like to use Javalin with Hibernate, but with the default thread-pool size of up to 250, I'm not sure if I want to possibly have 250 Hibernate sessions. Or does this sound stupid?
You can already run on a custom server by calling app.server() @mikoet.
@TobiasWalle If you're okay with it, I'd like to mention you by name in the OpenAPI section of the 3.0 release announcement. Do you have any profile you'd like me to link to (LinkedIn, GitHub, Twitter?). Or would you prefer to stay anonymous?
Is the 3.0 version going to be updated? It’s a good news. Looking forward to the release.Is there a related Telegram group for javalin?
Getting close to release, so closing this issue.
Most helpful comment
Rewriting to be based on Java 8 instead of Kotlin, but still be Kotlin-viable.
Under certain circumstances, pulling 5 kotlin related libs, including sdk might not be acceptable.
I remember there was discussion about it some time ago and I could see couple valid points there.
Java is the language (IMO) that lacks good framework like Javalin, in Kotlin, there are alternatives.
I think (I'm not sure though) that majority of users actually come from Java, and Kotlin users wouldn't probably even notice it, so ...