blob: 2dab6ff122567891df4ffe1f344ae6f61385650f [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Apache TomEE</title>
<meta name="description"
content="Apache TomEE is a lightweight, yet powerful, JavaEE Application server with feature rich tooling." />
<meta name="keywords" content="tomee,asf,apache,javaee,jee,shade,embedded,test,junit,applicationcomposer,maven,arquillian" />
<meta name="author" content="Luka Cvetinovic for Codrops" />
<link rel="icon" href="../../../favicon.ico">
<link rel="icon" type="image/png" href="../../../favicon.png">
<meta name="msapplication-TileColor" content="#80287a">
<meta name="theme-color" content="#80287a">
<link rel="stylesheet" type="text/css" href="../../../css/normalize.css">
<link rel="stylesheet" type="text/css" href="../../../css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="../../../css/owl.css">
<link rel="stylesheet" type="text/css" href="../../../css/animate.css">
<link rel="stylesheet" type="text/css" href="../../../fonts/font-awesome-4.1.0/css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="../../../fonts/eleganticons/et-icons.css">
<link rel="stylesheet" type="text/css" href="../../../css/jqtree.css">
<link rel="stylesheet" type="text/css" href="../../../css/idea.css">
<link rel="stylesheet" type="text/css" href="../../../css/cardio.css">
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-2717626-1']);
_gaq.push(['_setDomainName', 'apache.org']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<div class="preloader">
<img src="../../../img/loader.gif" alt="Preloader image">
</div>
<nav class="navbar">
<div class="container">
<div class="row"> <div class="col-md-12">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
<span>
<img src="../../../img/logo-active.png">
</span>
Apache TomEE
</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right main-nav">
<li><a href="../../../docs.html">Documentation</a></li>
<li><a href="../../../community/index.html">Community</a></li>
<li><a href="../../../security/security.html">Security</a></li>
<li><a href="../../../download-ng.html">Downloads</a></li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div></div>
</div>
<!-- /.container-fluid -->
</nav>
<div id="main-block" class="container main-block">
<div class="row title">
<div class="col-md-12">
<div class='page-header'>
<h1>Configurando JSON-B</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Este exemplo mostra como personalizar jsonb para uma aplicação JAX-RS.
JSONB é o novo padrão <code>javaee-api: 8.0</code> para serialização/desserialização de json.
Poucas anotações são necessárias e o <code>JsonbConfig</code> oferece muitas configurações.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_executando_e_testando_o_endpoint">Executando e testando o Endpoint</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A aplicação pode ser executada com <code>mvn clean install tomee: run</code> e se a porta 8080 estiver disponível, pode invocar o seguinte endpoint:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">$ curl -X GET http://localhost:8080/mp-jsonb-configuration/api/users</code></pre>
</div>
</div>
<div class="paragraph">
<p>que deve responder com o seguinte json:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">[
{
"Id":1,
"Name":"user 1",
"Registration":"2018 - 12 - 28"
},
{
"Id":2,
"Name":"user 2",
"Registration":"2018 - 12 - 28"
}
]</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="__applicationpath">@ApplicationPath</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A classe de ponto de partida JAX-RS</p>
</div>
<div class="paragraph">
<p>A classe de ponto de entrada JAXRS, da seguinte forma, os jaxrs carregarão todas as classes e métodos anotados com <code>@Path</code> sem especificá-los.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("api")
public class JAXRSApplication extends Application {
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="__path_recurso_rest">@Path Recurso Rest</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Classe jaxrs simples com um método GET</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.superbiz.model.User;
@Path("users")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Stateless
public class UserService {
@GET
public List&lt;User&gt; users() {
List&lt;User&gt; users = new ArrayList&lt;&gt;();
User user1 = new User(1, "user 1");
User user2 = new User(2, "user 2");
users.add(user1);
users.add(user2);
return users;
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_configurando_jsonb">Configurando JSONB</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A implementação de <code>ContextResolver&lt;&gt;</code> pode personalizar os padrões de jaxrs; neste exemplo, vamos personalizar a serialização/desserialização JSONB</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.json.bind.JsonbConfig;
import javax.json.bind.config.PropertyNamingStrategy;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
@Provider
public class JSONBConfiguration implements ContextResolver&lt;Jsonb&gt; {
private Jsonb jsonb;
public JSONBConfiguration() {
// jsonbConfig offers a lot of configurations.
JsonbConfig config = new JsonbConfig().withFormatting(true)
.withPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE)
.withDateFormat("yyyy - MM - dd", Locale.ENGLISH);
jsonb = JsonbBuilder.create(config);
}
@Override
public Jsonb getContext(Class&lt;?&gt; type) {
return jsonb;
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p><code>JsonbConfig</code> oferece muitas configurações.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_acessando_o_recurso_rest">Acessando o Recurso Rest</h2>
<div class="sectionbody">
<div class="paragraph">
<p>O teste ativa um aplicativo da web openejb e invoca o endpoint <code>/users</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.openejb.jee.WebApp;
import org.apache.openejb.junit.ApplicationComposer;
import org.apache.openejb.testing.Classes;
import org.apache.openejb.testing.EnableServices;
import org.apache.openejb.testing.Module;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.superbiz.JAXRSApplication;
import org.superbiz.JSONBConfiguration;
@EnableServices(value = "jaxrs")
@RunWith(ApplicationComposer.class)
public class UserServiceTest {
@Module
@Classes({ UserService.class, JAXRSApplication.class, JSONBConfiguration.class })
public WebApp app() {
return new WebApp().contextRoot("test");
}
@Test
public void get() throws IOException {
final String message = WebClient.create("http://localhost:4204").path("/test/api/users").get(String.class);
System.out.println(message);
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy - MM - dd");
// test withDateFormat("yyyy - MM - dd")
Assert.assertTrue(message.contains(sdf.format(new Date())));
// test withFormatting(true)
Assert.assertTrue(message.contains(System.getProperty("line.separator")));
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_executando">Executando</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A execução do exemplo pode ser feita a partir do maven com um simples comando <code>mvn clean install</code>, executando no diretorio <code>mp-jsonb-configuration</code>.</p>
</div>
<div class="paragraph">
<p>Quando executado, você deve ver uma saída semelhante à seguinte:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.superbiz.rest.UserServiceTest
INFO - Created new singletonService org.apache.openejb.cdi.ThreadSingletonServiceImpl@7823a2f9
INFO - Succeeded in installing singleton service
INFO - Cannot find the configuration file [conf/openejb.xml]. Will attempt to create one for the beans deployed.
INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service)
INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager)
INFO - Creating TransactionManager(id=Default Transaction Manager)
INFO - Creating SecurityService(id=Default Security Service)
INFO - Initializing network services
INFO - Creating ServerService(id=cxf-rs)
INFO - Creating ServerService(id=httpejbd)
INFO - Created ServicePool 'httpejbd' with (10) core threads, limited to (200) threads with a queue of (9)
INFO - Initializing network services
INFO - ** Bound Services **
INFO - NAME IP PORT
INFO - httpejbd 127.0.0.1 4204
INFO - -------
INFO - Ready!
INFO - Configuring enterprise application: /home/federico/Documents/PRIVATO/Apache/tomee/examples/mp-jsonb-configuration/UserServiceTest
INFO - Auto-deploying ejb UserService: EjbDeployment(deployment-id=UserService)
INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container)
INFO - Auto-creating a container for bean org.superbiz.rest.UserServiceTest: Container(type=MANAGED, id=Default Managed Container)
INFO - Creating Container(id=Default Managed Container)
INFO - Using directory /tmp for stateful session passivation
INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container)
INFO - Auto-creating a container for bean UserService: Container(type=STATELESS, id=Default Stateless Container)
INFO - Creating Container(id=Default Stateless Container)
INFO - Enterprise application "/home/federico/Documents/PRIVATO/Apache/tomee/examples/mp-jsonb-configuration/UserServiceTest" loaded.
INFO - Creating dedicated application classloader for UserServiceTest
INFO - Assembling app: /home/federico/Documents/PRIVATO/Apache/tomee/examples/mp-jsonb-configuration/UserServiceTest
INFO - Jndi(name=UserServiceLocalBean) --&gt; Ejb(deployment-id=UserService)
INFO - Jndi(name=global/test/UserService!org.superbiz.rest.UserService) --&gt; Ejb(deployment-id=UserService)
INFO - Jndi(name=global/test/UserService) --&gt; Ejb(deployment-id=UserService)
INFO - Created Ejb(deployment-id=UserService, ejb-name=UserService, container=Default Stateless Container)
INFO - Started Ejb(deployment-id=UserService, ejb-name=UserService, container=Default Stateless Container)
INFO - Using readers:
INFO - org.apache.cxf.jaxrs.provider.PrimitiveTextProvider@2f94c4db
INFO - org.apache.cxf.jaxrs.provider.FormEncodingProvider@6b5966e1
INFO - org.apache.cxf.jaxrs.provider.MultipartProvider@65e61854
INFO - org.apache.cxf.jaxrs.provider.SourceProvider@1568159
INFO - org.apache.cxf.jaxrs.provider.JAXBElementTypedProvider@4fcee388
INFO - org.apache.cxf.jaxrs.provider.JAXBElementProvider@6f80fafe
INFO - org.apache.openejb.server.cxf.rs.johnzon.TomEEJsonbProvider@63cd604c
INFO - org.apache.openejb.server.cxf.rs.johnzon.TomEEJsonpProvider@593e824f
INFO - org.apache.cxf.jaxrs.provider.StringTextProvider@72ccd81a
INFO - org.apache.cxf.jaxrs.provider.BinaryDataProvider@6d8792db
INFO - org.apache.cxf.jaxrs.provider.DataSourceProvider@64bc21ac
INFO - Using writers:
INFO - org.apache.johnzon.jaxrs.WadlDocumentMessageBodyWriter@493dfb8e
INFO - org.apache.cxf.jaxrs.nio.NioMessageBodyWriter@5d25e6bb
INFO - org.apache.cxf.jaxrs.provider.StringTextProvider@72ccd81a
INFO - org.apache.cxf.jaxrs.provider.JAXBElementTypedProvider@4fcee388
INFO - org.apache.cxf.jaxrs.provider.PrimitiveTextProvider@2f94c4db
INFO - org.apache.cxf.jaxrs.provider.FormEncodingProvider@6b5966e1
INFO - org.apache.cxf.jaxrs.provider.MultipartProvider@65e61854
INFO - org.apache.cxf.jaxrs.provider.SourceProvider@1568159
INFO - org.apache.cxf.jaxrs.provider.JAXBElementProvider@6f80fafe
INFO - org.apache.openejb.server.cxf.rs.johnzon.TomEEJsonbProvider@63cd604c
INFO - org.apache.openejb.server.cxf.rs.johnzon.TomEEJsonpProvider@593e824f
INFO - org.apache.cxf.jaxrs.provider.BinaryDataProvider@6d8792db
INFO - org.apache.cxf.jaxrs.provider.DataSourceProvider@64bc21ac
INFO - Using exception mappers:
INFO - org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper@361c294e
INFO - org.apache.openejb.server.cxf.rs.EJBExceptionMapper@6fff253c
INFO - org.apache.cxf.jaxrs.validation.ValidationExceptionMapper@7859e786
INFO - org.apache.openejb.server.cxf.rs.CxfRsHttpListener$CxfResponseValidationExceptionMapper@285d851a
INFO - REST Application: http://127.0.0.1:4204/test/api -&gt; org.superbiz.JAXRSApplication@5af28b27
INFO - Service URI: http://127.0.0.1:4204/test/api/users -&gt; EJB org.superbiz.rest.UserService
INFO - GET http://127.0.0.1:4204/test/api/users -&gt; List&lt;User&gt; users()
INFO - Deployed Application(path=/home/federico/Documents/PRIVATO/Apache/tomee/examples/mp-jsonb-configuration/UserServiceTest)
[
{
"Id":1,
"Name":"user 1",
"Registration":"2018 - 12 - 28"
},
{
"Id":2,
"Name":"user 2",
"Registration":"2018 - 12 - 28"
}
]
INFO - Undeploying app: /home/federico/Documents/PRIVATO/Apache/tomee/examples/mp-jsonb-configuration/UserServiceTest
INFO - Stopping network services
INFO - Stopping server services
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.203 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0</code></pre>
</div>
</div>
<div class="sect2">
<h3 id="_dentro_do_jar">Dentro do jar</h3>
<div class="paragraph">
<p><code>javaee-api: 8.0</code> ele incorpora todas as dependências necessárias para ativar um aplicativo REST em funcionamento.</p>
</div>
<div class="paragraph">
<p>Se olharmos para o jar construído pelo maven, veremos que o aplicativo em si é bem pequeno:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">$ jar tvf target/mp-jsonb-configuration-8.0.0-SNAPSHOT.war
0 Fri Dec 28 19:36:10 CET 2018 META-INF/
134 Fri Dec 28 19:36:08 CET 2018 META-INF/MANIFEST.MF
0 Fri Dec 28 19:36:08 CET 2018 WEB-INF/
0 Fri Dec 28 19:36:08 CET 2018 WEB-INF/classes/
0 Fri Dec 28 19:36:08 CET 2018 WEB-INF/classes/org/
0 Fri Dec 28 19:36:08 CET 2018 WEB-INF/classes/org/superbiz/
0 Fri Dec 28 19:36:08 CET 2018 WEB-INF/classes/org/superbiz/model/
0 Fri Dec 28 19:36:08 CET 2018 WEB-INF/classes/org/superbiz/rest/
1165 Fri Dec 28 19:36:06 CET 2018 WEB-INF/classes/org/superbiz/model/User.class
402 Fri Dec 28 19:36:06 CET 2018 WEB-INF/classes/org/superbiz/JAXRSApplication.class
1194 Fri Dec 28 19:36:06 CET 2018 WEB-INF/classes/org/superbiz/rest/UserService.class
1701 Fri Dec 28 19:36:06 CET 2018 WEB-INF/classes/org/superbiz/JSONBConfiguration.class
1224 Fri Dec 28 18:28:32 CET 2018 WEB-INF/web.xml
0 Fri Dec 28 19:36:10 CET 2018 META-INF/maven/
0 Fri Dec 28 19:36:10 CET 2018 META-INF/maven/org.superbiz/
0 Fri Dec 28 19:36:10 CET 2018 META-INF/maven/org.superbiz/mp-jsonb-configuration/
1791 Fri Dec 28 19:10:44 CET 2018 META-INF/maven/org.superbiz/mp-jsonb-configuration/pom.xml
128 Fri Dec 28 19:36:08 CET 2018 META-INF/maven/org.superbiz/mp-jsonb-configuration/pom.properties</code></pre>
</div>
</div>
<div class="paragraph">
<p>Esse jar individual pode ser implantado em qualquer implementação Java EE que atenda aos requisitos. No TomEE, basta colocá-lo no diretório <code>${tomee.home}/webapps/</code>.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-sm-6 text-center-mobile">
<h3 class="white">Be simple. Be certified. Be Tomcat.</h3>
<h5 class="light regular light-white">"A good application in a good server"</h5>
<ul class="social-footer">
<li><a href="https://www.facebook.com/ApacheTomEE/"><i class="fa fa-facebook"></i></a></li>
<li><a href="https://twitter.com/apachetomee"><i class="fa fa-twitter"></i></a></li>
<li><a href="https://plus.google.com/communities/105208241852045684449"><i class="fa fa-google-plus"></i></a></li>
</ul>
</div>
<div class="col-sm-6 text-center-mobile">
<div class="row opening-hours">
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../latest/docs/" class="white">Documentation</a></h5>
<ul class="list-unstyled">
<li><a href="../../../latest/docs/admin/configuration/index.html" class="regular light-white">How to configure</a></li>
<li><a href="../../../latest/docs/admin/file-layout.html" class="regular light-white">Dir. Structure</a></li>
<li><a href="../../../latest/docs/developer/testing/index.html" class="regular light-white">Testing</a></li>
<li><a href="../../../latest/docs/admin/cluster/index.html" class="regular light-white">Clustering</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../latest/examples/" class="white">Examples</a></h5>
<ul class="list-unstyled">
<li><a href="../../../latest/examples/simple-cdi-interceptor.html" class="regular light-white">CDI Interceptor</a></li>
<li><a href="../../../latest/examples/rest-cdi.html" class="regular light-white">REST with CDI</a></li>
<li><a href="../../../latest/examples/ejb-examples.html" class="regular light-white">EJB</a></li>
<li><a href="../../../latest/examples/jsf-managedBean-and-ejb.html" class="regular light-white">JSF</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../community/index.html" class="white">Community</a></h5>
<ul class="list-unstyled">
<li><a href="../../../community/contributors.html" class="regular light-white">Contributors</a></li>
<li><a href="../../../community/social.html" class="regular light-white">Social</a></li>
<li><a href="../../../community/sources.html" class="regular light-white">Sources</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../../security/index.html" class="white">Security</a></h5>
<ul class="list-unstyled">
<li><a href="http://apache.org/security" target="_blank" class="regular light-white">Apache Security</a></li>
<li><a href="http://apache.org/security/projects.html" target="_blank" class="regular light-white">Security Projects</a></li>
<li><a href="http://cve.mitre.org" target="_blank" class="regular light-white">CVE</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="row bottom-footer text-center-mobile">
<div class="col-sm-12 light-white">
<p>Copyright &copy; 1999-2016 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. Apache TomEE, TomEE, Apache, the Apache feather logo, and the Apache TomEE project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.</p>
</div>
</div>
</div>
</footer>
<!-- Holder for mobile navigation -->
<div class="mobile-nav">
<ul>
<li><a hef="../../../latest/docs/admin/index.html">Administrators</a>
<li><a hef="../../../latest/docs/developer/index.html">Developers</a>
<li><a hef="../../../latest/docs/advanced/index.html">Advanced</a>
<li><a hef="../../../community/index.html">Community</a>
</ul>
<a href="#" class="close-link"><i class="arrow_up"></i></a>
</div>
<!-- Scripts -->
<script src="../../../js/jquery-1.11.1.min.js"></script>
<script src="../../../js/owl.carousel.min.js"></script>
<script src="../../../js/bootstrap.min.js"></script>
<script src="../../../js/wow.min.js"></script>
<script src="../../../js/typewriter.js"></script>
<script src="../../../js/jquery.onepagenav.js"></script>
<script src="../../../js/tree.jquery.js"></script>
<script src="../../../js/highlight.pack.js"></script>
<script src="../../../js/main.js"></script>
</body>
</html>