Cookie Store
A função ctx.cookieStore() fornece um conveniente caminho para compartilhar informações entre handlers, request ou até mesmo servidores:
1 2 3 4 |
<span class="n">ctx</span><span class="o">.</span><span class="na">cookieStore</span><span class="o">(</span><span class="n">key</span><span class="o">,</span> <span class="n">value</span><span class="o">);</span> <span class="c1">// store any type of value</span> <span class="n">ctx</span><span class="o">.</span><span class="na">cookieStore</span><span class="o">(</span><span class="n">key</span><span class="o">);</span> <span class="c1">// read any type of value</span> <span class="n">ctx</span><span class="o">.</span><span class="na">clearCookieStore</span><span class="o">();</span> <span class="c1">// clear the cookie-store</span> |
O cookieStore funciona desta maneira:
1. O primeiro handler que combina a entrada do request que irá popular o cookie-store-map com dados guardados no cookie (caso exista).
2. Este map pode agora ser utilizado como um estado entre handlers no mesmo ciclo de request, bastante parecido com o ctx.attribute().
3. No fim do ciclo do request, o cookie-store-map é serializado, base64-encoded e escrito no response como um cookie. Isto permite você dividir o map entre requests e servers (no caso você está executando múltiplos servidores por trás de um load-balancer)
Exemplo:
- Java
- Kotlin
1 2 3 4 5 6 7 8 9 10 11 |
<span class="n">serverOneApp</span><span class="o">.</span><span class="na">post</span><span class="o">(</span><span class="s">"/cookie-storer"</span><span class="o">)</span> <span class="o">{</span> <span class="n">ctx</span> <span class="o">-></span> <span class="n">ctx</span><span class="o">.</span><span class="na">cookieStore</span><span class="o">(</span><span class="s">"string"</span><span class="o">,</span> <span class="s">"Hello world!"</span><span class="o">);</span> <span class="n">ctx</span><span class="o">.</span><span class="na">cookieStore</span><span class="o">(</span><span class="s">"i"</span><span class="o">,</span> <span class="mi">42</span><span class="o">);</span> <span class="n">ctx</span><span class="o">.</span><span class="na">cookieStore</span><span class="o">(</span><span class="s">"list"</span><span class="o">,</span> <span class="nc">Arrays</span><span class="o">.</span><span class="na">asList</span><span class="o">(</span><span class="s">"One"</span><span class="o">,</span> <span class="s">"Two"</span><span class="o">,</span> <span class="s">"Three"</span><span class="o">));</span> <span class="o">}</span> <span class="n">serverTwoApp</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"/cookie-reader"</span><span class="o">)</span> <span class="o">{</span> <span class="n">ctx</span> <span class="o">-></span> <span class="c1">// runs on a different server than serverOneApp</span> <span class="nc">String</span> <span class="n">string</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="na">cookieStore</span><span class="o">(</span><span class="s">"string"</span><span class="o">)</span> <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="na">cookieStore</span><span class="o">(</span><span class="s">"i"</span><span class="o">)</span> <span class="nc">List</span><span class="o"><</span><span class="nc">String</span><span class="o">></span> <span class="n">list</span> <span class="o">=</span> <span class="n">ctx</span><span class="o">.</span><span class="na">cookieStore</span><span class="o">(</span><span class="s">"list"</span><span class="o">)</span> <span class="o">}</span> |
1 2 3 4 5 6 7 8 9 10 11 |
<span class="n">serverOneApp</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="s">"/cookie-storer"</span><span class="p">)</span> <span class="p">{</span> <span class="n">ctx</span> <span class="p">-></span> <span class="n">ctx</span><span class="p">.</span><span class="nf">cookieStore</span><span class="p">(</span><span class="s">"string"</span><span class="p">,</span> <span class="s">"Hello world!"</span><span class="p">)</span> <span class="n">ctx</span><span class="p">.</span><span class="nf">cookieStore</span><span class="p">(</span><span class="s">"i"</span><span class="p">,</span> <span class="m">42</span><span class="p">)</span> <span class="n">ctx</span><span class="p">.</span><span class="nf">cookieStore</span><span class="p">(</span><span class="s">"list"</span><span class="p">,</span> <span class="nf">listOf</span><span class="p">(</span><span class="s">"One"</span><span class="p">,</span> <span class="s">"Two"</span><span class="p">,</span> <span class="s">"Three"</span><span class="p">))</span> <span class="p">}</span> <span class="n">serverTwoApp</span><span class="p">.</span><span class="k">get</span><span class="p">(</span><span class="s">"/cookie-reader"</span><span class="p">)</span> <span class="p">{</span> <span class="n">ctx</span> <span class="p">-></span> <span class="c1">// runs on a different server than serverOneApp</span> <span class="kd">val</span> <span class="py">string</span> <span class="p">=</span> <span class="n">ctx</span><span class="p">.</span><span class="n">cookieStore</span><span class="p"><</span><span class="nc">String</span><span class="p">>(</span><span class="s">"string"</span><span class="p">)</span> <span class="kd">val</span> <span class="py">i</span> <span class="p">=</span> <span class="n">ctx</span><span class="p">.</span><span class="n">cookieStore</span><span class="p"><</span><span class="nc">Int</span><span class="p">>(</span><span class="s">"i"</span><span class="p">)</span> <span class="kd">val</span> <span class="py">list</span> <span class="p">=</span> <span class="n">ctx</span><span class="p">.</span><span class="n">cookieStore</span><span class="p"><</span><span class="nc">List</span><span class="p"><</span><span class="nc">String</span><span class="p">>>(</span><span class="s">"list"</span><span class="p">)</span> <span class="p">}</span> |
Desde que o cliente guarda o cookie, o get request para o serverTwoApp irá ser capaz de recuperar as informações que foram passadas via post para serverOneApp.
Lembre-se que os cookies têm no máximo 4kb.
Context extensions
Context extensions fornece para o desenvolvedor Java uma maneira de estender o objeto Context.
Um dos mais populares recursos do Kotlin é a extension functions. Quando trabalhar com um objeto que não seja Java, você muitas vezes termina fazendo MyUtil.action(object, …).
Se você, por exemplo, quiser serializar um objeto e configurar o resultado no Context, você pode fazer:
1 2 |
<span class="n">app</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"/"</span><span class="o">,</span> <span class="n">ctx</span> <span class="o">-></span> <span class="nc">MyMapperUtil</span><span class="o">.</span><span class="na">serialize</span><span class="o">(</span><span class="n">ctx</span><span class="o">,</span> <span class="n">myMapper</span><span class="o">,</span> <span class="n">myObject</span><span class="o">));</span> <span class="c1">// three args, what happens where?</span> |
Com context extensions você pode adicionar extensões no context:
1 2 |
<span class="n">app</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"/"</span><span class="o">,</span> <span class="n">ctx</span> <span class="o">-></span> <span class="n">ctx</span><span class="o">.</span><span class="na">use</span><span class="o">(</span><span class="nc">MyMapper</span><span class="o">.</span><span class="na">class</span><span class="o">).</span><span class="na">serialize</span><span class="o">(</span><span class="n">object</span><span class="o">));</span> <span class="c1">// use MyMapper to serialize object</span> |
Context extensions deve ser adicionado antes de ser utilizado, isto pode tipicamente ser feito primeiro (before) no filtro do seu app:
1 2 |
<span class="n">app</span><span class="o">.</span><span class="na">before</span><span class="o">(</span><span class="n">ctx</span> <span class="o">-></span> <span class="n">ctx</span><span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="nc">MyMapper</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="k">new</span> <span class="nc">MyMapper</span><span class="o">(</span><span class="n">ctx</span><span class="o">,</span> <span class="n">otherDependency</span><span class="o">));</span> |
WebSockets
Javalin é muito intuitivo para utilizar o WebSockets. Você declara um endpoint com um caminho e configura um diferente event handlers no lambda:
- Java
- Kotlin
1 2 3 4 |
<span class="n">app</span><span class="o">.</span><span class="na">ws</span><span class="o">(</span><span class="s">"/websocket/:path"</span><span class="o">,</span> <span class="n">ws</span> <span class="o">-></span> <span class="o">{</span> <span class="n">ws</span><span class="o">.</span><span class="na">onConnect</span><span class="o">(</span><span class="n">ctx</span> <span class="o">-></span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Connected"</span><span class="o">));</span> <span class="o">});</span> |
1 2 3 4 |
<span class="n">app</span><span class="p">.</span><span class="nf">ws</span><span class="p">(</span><span class="s">"/websocket/:path"</span><span class="p">)</span> <span class="p">{</span> <span class="n">ws</span> <span class="p">-></span> <span class="n">ws</span><span class="p">.</span><span class="nf">onConnect</span> <span class="p">{</span> <span class="n">ctx</span> <span class="p">-></span> <span class="nf">println</span><span class="p">(</span><span class="s">"Connected"</span><span class="p">)</span> <span class="p">}</span> <span class="p">}</span> |
Há no total cinco eventos suportados:
1 2 3 4 5 6 |
<span class="n">ws</span><span class="o">.</span><span class="na">onConnect</span><span class="o">(</span><span class="nc">WsConnectContext</span><span class="o">)</span> <span class="n">ws</span><span class="o">.</span><span class="na">onError</span><span class="o">(</span><span class="nc">WsErrorContext</span><span class="o">)</span> <span class="n">ws</span><span class="o">.</span><span class="na">onClose</span><span class="o">(</span><span class="nc">WsCloseContext</span><span class="o">)</span> <span class="n">ws</span><span class="o">.</span><span class="na">onMessage</span><span class="o">(</span><span class="nc">WsMessageContext</span><span class="o">)</span> <span class="n">ws</span><span class="o">.</span><span class="na">onBinaryMessage</span><span class="o">(</span><span class="nc">WsBinaryMessageContext</span><span class="o">)</span> |
Os diferentes sabores de WsContext expõe diferentes coisas, como por exemplo, WsMessageContext tem o método .message() o qual dá a mensagem que o cliente mandou. As diferenças entre os diferentes contexts é pequena.
Deixe um comentário