SlideShare ist ein Scribd-Unternehmen logo
1 von 96
Downloaden Sie, um offline zu lesen
Java e HTML5:
Do Desktop/Web ao Mobile
Loiane Groner
@loiane
http://loiane.com
http://loiane.training
• 10+ XP TI
• Java, JavaScript/HTML5, Sencha,
Phonegap/Ionic, Angular
• Blog: http://loiane.com
• Cursos: http://loiane.training
• Meus livros:
Ferramentas de um dev Java/HTML5
• JavaEE
• HTML
• CSS
• JavaScript
• IDE favorita
• NetBeans, Eclipse, IntelliJ IDEA
Desenvolvedor FrontEnd
Desenvolvedor BackEnd Servidor
PartevisívelnositewebParte“mágica”,nãovisívelaousuário
http://www.alticreation.com/uploads/iceberg-front-end-back-end-developers.jpg
Plataforma JavaEE para HTML5:
• JSON
• WebSocket
• Concurrency
• Batch
• WebServices RESTful
• JSON: JavaScript Object Notation
• JSON: JavaScript Object Notation
• É uma forma de trocar dados entre frontend
e backend representados por chave-valor
• JSON: JavaScript Object Notation
• É uma forma de trocar dados entre frontend
e backend representados por chave-valor
• Exemplo: var meuObjeto = {nome : ‘Meu
Nome’, idade: 21};
• JSON: JavaScript Object Notation
• É uma forma de trocar dados entre frontend
e backend representados por chave-valor
• Exemplo: var meuObjeto = {nome : ‘Meu
Nome’, idade: 21};
• API JSON Java permite pasear, transformar e
consultar objectos JSON
• WebSocket: protocolo de aplicação que
fornece comunicação dupla entre 2 pontos
TCP
• API Java fornece funcionalidade através de
annotations
• Concurrency: API Java que fornece
funcionalidade de comunicação assíncrona
• Concurrency: API Java que fornece
funcionalidade de comunicação assíncrona
• Batch: API Java que fornece funcionalidade de
tarefas batch
• Webservices RESTful: JAX-RS
URL Verbo HTTP Desc
api/contatos GET obtém lista de contatos
api/contatos/:id GET
obtém dados de contato
específico
api/contatos POST cria contato
api/contatos/:id PUT atualiza contato
api/contatos/:id DELETE deleta contato
@Entity
@Table(name = "contact")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Contact.findAll", query = "SELECT c FROM Contact c"),
@NamedQuery(name = "Contact.findById", query = "SELECT c FROM Contact c WHERE c.id = :id"),
@NamedQuery(name = "Contact.findByEmail", query = "SELECT c FROM Contact c WHERE c.email = :email"),
@NamedQuery(name = "Contact.findByName", query = "SELECT c FROM Contact c WHERE c.name = :name"),
@NamedQuery(name = "Contact.findByPhone", query = "SELECT c FROM Contact c WHERE c.phone = :phone")})
public class Contact implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 255)
@Column(name = "email")
private String email;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 255)
@Column(name = "name")
private String name;
//…
}
@Stateless
@Path("contact")
public class ContactFacadeREST extends AbstractFacade<Contact> {
@POST
@Override
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public void create(Contact entity) {
super.create(entity);
}
@PUT
@Path("{id}")
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public void edit(@PathParam("id") Integer id, Contact entity) {
super.edit(entity);
}
@DELETE
@Path("{id}")
public void remove(@PathParam("id") Integer id) {
super.remove(super.find(id));
}
@GET
@Path("{id}")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Contact find(@PathParam("id") Integer id) {
return super.find(id);
}
@GET
@Override
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public List<Contact> findAll() {
return super.findAll();
}
}
@JsonAutoDetect
@Entity
@Table(name="CONTACT")
public class Contact {
@Id
@GeneratedValue
@Column(name="id")
private int id;
@Column(name="name", nullable=false)
private String name;
@Column(name="phone", nullable=false)
private String phone;
@Column(name="email", nullable=false)
private String email;
}
@Repository
public class ContactDAO {
private HibernateTemplate hibernateTemplate;
@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
hibernateTemplate = new HibernateTemplate(sessionFactory);
}
public List<Contact> getContacts(int start, int limit) {
DetachedCriteria criteria = DetachedCriteria.forClass(Contact.class);
return hibernateTemplate.findByCriteria(criteria, start, limit);
}
public void deleteContact(int id){
Object record = hibernateTemplate.load(Contact.class, id);
hibernateTemplate.delete(record);
}
}
@Controller
public class ContactController {
private ContactService contactService;
@RequestMapping(value="/contact/view.action")
public @ResponseBody Map<String,? extends Object> view(@RequestParam int start, @RequestParam int limit) throws Exception {
try{
List<Contact> contacts = contactService.getContactList(start,limit);
int total = contactService.getTotalContacts();
return ExtJSReturn.mapOK(contacts, total);
} catch (Exception e) {
return ExtJSReturn.mapError("Error retrieving Contacts from database.");
}
}
@RequestMapping(value="/contact/create.action")
public @ResponseBody Map<String,? extends Object> create(@RequestBody ContactWrapper data) throws Exception {
try{
List<Contact> contacts = contactService.create(data.getData());
return ExtJSReturn.mapOK(contacts);
} catch (Exception e) {
return ExtJSReturn.mapError("Error trying to create contact.");
}
}
}
http://aprendizweb.com.br/wp-content/uploads/2015/03/frontend-e-back-end.jpg
http://www-scf.usc.edu/~chenemil/itp104/images/html5features.jpg
Plataforma HTML5
<canvas>
<video>
<audio>
Plataforma HTML5
<canvas>
<video>
<audio>
CSS3
Animações
Transformações
Plataforma HTML5
<canvas>
<video>
<audio>
CSS3
Animações
Transformações
Sencha Ext JS
Angular
Backbone
Knockout
Ember
Plataforma HTML5
<canvas>
<video>
<audio>
CSS3
Animações
Transformações
Sencha Ext JS
Angular
Backbone
Knockout
Ember
Pré-processadores
Sass, Less
Emmet
Dart
Plataforma HTML5
<canvas>
<video>
<audio>
CSS3
Animações
Transformações
Sencha Ext JS
Angular
Backbone
Knockout
Ember
Pré-processadores
Sass, Less
Emmet
Dart
Mobile Híbrido
Phonegap/Cordova
Ionic
Plataforma HTML5
<canvas>
<video>
<audio>
CSS3
Animações
Transformações
Sencha Ext JS
Angular
Backbone
Knockout
Ember
Pré-processadores
Sass, Less
Emmet
Dart
Mobile Híbrido
Phonegap/Cordova
Ionic
Desktop Híbrido
TideSDK
AppJS
Node web-kit
Electron
APIs REST
JSON
Aplicação moderna
DOM
App Server
Browser
+
jQuery + Backbone
http://www.the4cast.com/wp-content/uploads/2014/06/web-starterkit.jpg
APIs REST
Banco de Dados
JSON JSON
import {bootstrap} from '@angular/platform-browser-dynamic';
import { HTTP_PROVIDERS } from '@angular/http';
import {AppComponent} from './app.component';
bootstrap(AppComponent, [HTTP_PROVIDERS]);
import {Component} from '@angular/core';
import {ContactsComponent} from './contacts/contacts.component';
@Component({
selector: 'my-app',
directives: [ContactsComponent],
template: '<contacts-grid></contacts-grid>'
})
export class AppComponent { }
export class Contact {
id: number;
name: string;
phone: string;
email: string;
}
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class ContactsService {
constructor(private http: Http) { }
getContacts() {
return this.http.get('http://localhost:8080/contacts-spring-mvc/contact/view.action?
start=0&limit=250')
.map((res: Response) => res.json().data);
}
}
import {Component, OnInit} from '@angular/core';
import {AgGridNg2} from 'ag-grid-ng2/main';
import {Contact} from './contact.model';
import {ContactsService} from './contacts.service';
@Component({
selector: 'contacts-grid',
directives: [AgGridNg2],
providers: [ContactsService],
template: `
<ag-grid-ng2 #agGrid style="height:100%;width:583px" class="ag-fresh"
[gridOptions]="gridOptions"
[rowData]="contacts">
</ag-grid-ng2 >
`
})
export class ContactsComponent implements OnInit {
contacts: Contact[] = [];
columnDefs = [
{headerName: 'Name', field: "name", width: 200 },
{headerName: 'Phone', field: "phone" ,width:180},
{headerName: 'Email', field: "email" ,width:200}
];
gridOptions : any = [];
constructor(private contactsService: ContactsService) {
this.gridOptions = {
rowData: this.contacts,
columnDefs: this.columnDefs,
enableColResize: true,
enableSorting: true,
enableFilter: true
}
}
ngOnInit() {
this.contactsService.getContacts()
.subscribe(contacts => this.contacts = contacts);
APIs REST
JSON
MOBILE
App Server
Dispositivo
Móvel
WebView Nativa
import {Component} from '@angular/core';
import { HTTP_PROVIDERS } from '@angular/http';
import {Platform, ionicBootstrap} from 'ionic-angular';
import {StatusBar} from 'ionic-native';
import {TabsPage} from './pages/tabs/tabs';
@Component({
template: '<ion-nav [root]="rootPage"></ion-nav>'
})
export class MyApp {
private rootPage:any;
constructor(private platform:Platform) {
this.rootPage = TabsPage;
platform.ready().then(() => {
StatusBar.styleDefault();
});
}
}
ionicBootstrap(MyApp, [HTTP_PROVIDERS]);
import {Component} from '@angular/core'
import {HomePage} from '../home/home';
import {AboutPage} from '../about/about';
import {ContactPage} from '../contact/contact';
@Component({
templateUrl: 'build/pages/tabs/tabs.html'
})
export class TabsPage {
private tab1Root: any;
private tab2Root: any;
private tab3Root: any;
constructor() {
// this tells the tabs component which Pages
// should be each tab's root Page
this.tab1Root = HomePage;
this.tab2Root = AboutPage;
this.tab3Root = ContactPage;
}
}
<ion-tabs>
<ion-tab [root]="tab3Root" tabTitle="Contatos" tabIcon="contacts"></ion-tab>
<ion-tab [root]="tab1Root" tabTitle="Inicio" tabIcon="home"></ion-tab>
<ion-tab [root]="tab2Root" tabTitle="Sobre" tabIcon="information-circle"></ion-tab>
</ion-tabs>
import {Component, OnInit} from '@angular/core';
import {NavController} from 'ionic-angular';
import {Contact} from '../contact/contact.model';
import {ContactsService} from '../contact/contacts.service';
import {ContactDetailsPage} from '../contact-details/contact-details';
@Component({
templateUrl: 'build/pages/contact/contact.html',
providers: [ContactsService]
})
export class ContactPage implements OnInit {
contacts: Contact[] = [];
constructor(private nav: NavController, private contactsService: ContactsService) {
}
ngOnInit() {
this.contactsService.getContacts()
.subscribe(contacts => this.contacts = contacts);
}
itemSelected(contact){
this.nav.push(ContactDetailsPage, contact);
}
}
<ion-navbar *navbar>
<ion-title>
Contact
</ion-title>
</ion-navbar>
<ion-content>
<ion-list>
<ion-item *ngFor="let contact of contacts" (click)="itemSelected(contact)">
{{contact.name}}
</ion-item>
</ion-list>
</ion-content>
import {Component} from '@angular/core';
import {NavController, NavParams} from 'ionic-angular';
import {Contact} from '../contact/contact.model';
@Component({
templateUrl: 'build/pages/contact-details/contact-details.html'
})
export class ContactDetailsPage {
contact: Contact;
constructor(private nav: NavController, private navParams: NavParams) {
this.contact = this.navParams.data;
}
}
<ion-navbar *navbar>
<ion-title>{{contact.name}}</ion-title>
</ion-navbar>
<ion-content padding class="speaker-detail">
<p>Id: <span>{{contact.id}}</span></p>
<p>Nome: <span>{{contact.name}}</span></p>
<p>Email: <span>{{contact.phone}}</span></p>
<p>Telefone: <span>{{contact.email}}</span></p>
</ion-content>
http://enable-cors.org/
APIs REST
JSON
DESKTOP
App Server
App
Desktop
Wrapper
const electron = require('electron')
const app = electron.app
const BrowserWindow = electron.BrowserWindow
let mainWindow
function createWindow () {
mainWindow = new BrowserWindow({width: 800, height: 600})
mainWindow.loadURL(`file://${__dirname}/index.html`)
mainWindow.webContents.openDevTools()
mainWindow.on('closed', function () {
mainWindow = null
})
}
app.on('ready', createWindow)
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
if (mainWindow === null) {
createWindow()
}
})
electron-packager ./ --platform=darwin --arch=x64
electron-packager ./ --platform=win32 --arch=x64
electron-packager ./ --platform=linux --arch=x64
• SSL
• Unauthorised access (acesso não autorizado)
• Código backend sem validações
• Dados sem criptografia (local e na troca de
dados)
• Mau uso da persistência
https://www.owasp.org
https://github.com/loiane/javaee-html5-js
http://loiane.com
facebook.com/loianegroner
twitter.com/loiane
https://github.com/loiane
youtube.com/loianegroner
http://loiane.training
JavaOne Brasil 2016: JavaEE e HTML5: da web/desktop ao mobile

Weitere ähnliche Inhalte

Was ist angesagt?

Android Scripting
Android ScriptingAndroid Scripting
Android Scripting
Juan Gomez
 

Was ist angesagt? (20)

Internal Android Library Management (DroidCon SF 2016, Droidcon Italy 2016)
Internal Android Library Management (DroidCon SF 2016, Droidcon Italy 2016)Internal Android Library Management (DroidCon SF 2016, Droidcon Italy 2016)
Internal Android Library Management (DroidCon SF 2016, Droidcon Italy 2016)
 
Creating mobile apps - an introduction to Ionic (Engage 2016)
Creating mobile apps - an introduction to Ionic (Engage 2016)Creating mobile apps - an introduction to Ionic (Engage 2016)
Creating mobile apps - an introduction to Ionic (Engage 2016)
 
Android Scripting
Android ScriptingAndroid Scripting
Android Scripting
 
Plugin architecture (Extensible Application Architecture)
Plugin architecture (Extensible Application Architecture)Plugin architecture (Extensible Application Architecture)
Plugin architecture (Extensible Application Architecture)
 
iPhone Coding For Web Developers
iPhone Coding For Web DevelopersiPhone Coding For Web Developers
iPhone Coding For Web Developers
 
Titanium Alloy Framework
Titanium Alloy FrameworkTitanium Alloy Framework
Titanium Alloy Framework
 
Appcelerator Titanium Alloy
Appcelerator Titanium Alloy Appcelerator Titanium Alloy
Appcelerator Titanium Alloy
 
What's New in JHipsterLand - Devoxx Poland 2017
What's New in JHipsterLand - Devoxx Poland 2017What's New in JHipsterLand - Devoxx Poland 2017
What's New in JHipsterLand - Devoxx Poland 2017
 
Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)Crash Course in AngularJS + Ionic (Deep dive)
Crash Course in AngularJS + Ionic (Deep dive)
 
When to (use / not use) React Native.
When to (use / not use) React Native.When to (use / not use) React Native.
When to (use / not use) React Native.
 
React Ecosystem
React EcosystemReact Ecosystem
React Ecosystem
 
SONY BBS - React Native
SONY BBS - React NativeSONY BBS - React Native
SONY BBS - React Native
 
Web components Introduction
Web components IntroductionWeb components Introduction
Web components Introduction
 
How native is React Native? | React Native vs Native App Development
How native is React Native? | React Native vs Native App DevelopmentHow native is React Native? | React Native vs Native App Development
How native is React Native? | React Native vs Native App Development
 
Plugins 2.0: The Overview
Plugins 2.0: The OverviewPlugins 2.0: The Overview
Plugins 2.0: The Overview
 
The Open-source Eclipse Plugin for Force.com Development, Summer ‘14
The Open-source Eclipse Plugin for Force.com Development, Summer ‘14The Open-source Eclipse Plugin for Force.com Development, Summer ‘14
The Open-source Eclipse Plugin for Force.com Development, Summer ‘14
 
Putting the Native in React Native - React Native Boston
Putting the Native in React Native - React Native BostonPutting the Native in React Native - React Native Boston
Putting the Native in React Native - React Native Boston
 
So, you want to be a plugin developer?
So, you want to be a plugin developer?So, you want to be a plugin developer?
So, you want to be a plugin developer?
 
[JavaLand 2015] Developing JavaScript Mobile Apps Using Apache Cordova
[JavaLand 2015] Developing JavaScript Mobile Apps Using Apache Cordova[JavaLand 2015] Developing JavaScript Mobile Apps Using Apache Cordova
[JavaLand 2015] Developing JavaScript Mobile Apps Using Apache Cordova
 
Google Cloud Endpointsによる API構築
Google Cloud Endpointsによる API構築Google Cloud Endpointsによる API構築
Google Cloud Endpointsによる API構築
 

Andere mochten auch

Andere mochten auch (20)

Open Source Mobile Experience: Ionic 2
Open Source Mobile Experience: Ionic 2Open Source Mobile Experience: Ionic 2
Open Source Mobile Experience: Ionic 2
 
Exercicios Pilhas (Stacks) - Estruturas de dados e algoritmos com Java
Exercicios Pilhas (Stacks) - Estruturas de dados e algoritmos com JavaExercicios Pilhas (Stacks) - Estruturas de dados e algoritmos com Java
Exercicios Pilhas (Stacks) - Estruturas de dados e algoritmos com Java
 
Exercicios Vetores (Arrays) - Estruturas de dados e algoritmos com Java
Exercicios Vetores (Arrays) - Estruturas de dados e algoritmos com JavaExercicios Vetores (Arrays) - Estruturas de dados e algoritmos com Java
Exercicios Vetores (Arrays) - Estruturas de dados e algoritmos com Java
 
[Curso Java Basico] Exercicios Aulas 47 a 52
[Curso Java Basico] Exercicios Aulas 47 a 52[Curso Java Basico] Exercicios Aulas 47 a 52
[Curso Java Basico] Exercicios Aulas 47 a 52
 
[Curso Java Basico] Exercicios Aulas 36 a 43
[Curso Java Basico] Exercicios Aulas 36 a 43[Curso Java Basico] Exercicios Aulas 36 a 43
[Curso Java Basico] Exercicios Aulas 36 a 43
 
Exercicios Filas (Queues) - Estruturas de dados e algoritmos com Java
Exercicios Filas (Queues) - Estruturas de dados e algoritmos com JavaExercicios Filas (Queues) - Estruturas de dados e algoritmos com Java
Exercicios Filas (Queues) - Estruturas de dados e algoritmos com Java
 
[Curso Java Basico] Exercicios Aulas 44 a 46
[Curso Java Basico] Exercicios Aulas 44 a 46[Curso Java Basico] Exercicios Aulas 44 a 46
[Curso Java Basico] Exercicios Aulas 44 a 46
 
[Curso Java Basico] Exercicios Aula 36
[Curso Java Basico] Exercicios Aula 36[Curso Java Basico] Exercicios Aula 36
[Curso Java Basico] Exercicios Aula 36
 
[Curso Java Basico] Aula 54: Enumeradores como classe (construtor e metodos)
[Curso Java Basico] Aula 54: Enumeradores como classe (construtor e metodos)[Curso Java Basico] Aula 54: Enumeradores como classe (construtor e metodos)
[Curso Java Basico] Aula 54: Enumeradores como classe (construtor e metodos)
 
[Curso Java Basico] Aula 73: Threads: resume, suspend e stop
[Curso Java Basico] Aula 73: Threads: resume, suspend e stop[Curso Java Basico] Aula 73: Threads: resume, suspend e stop
[Curso Java Basico] Aula 73: Threads: resume, suspend e stop
 
[Curso Java Basico] Aula 63: printf
[Curso Java Basico] Aula 63: printf[Curso Java Basico] Aula 63: printf
[Curso Java Basico] Aula 63: printf
 
[Curso Java Basico] Aula 61: Passagem de parametros por valor e referencia
[Curso Java Basico] Aula 61: Passagem de parametros por valor e referencia[Curso Java Basico] Aula 61: Passagem de parametros por valor e referencia
[Curso Java Basico] Aula 61: Passagem de parametros por valor e referencia
 
Curso Java Basico] Aula 66: Garbage Collector (Coletor de Lixo)
Curso Java Basico] Aula 66: Garbage Collector (Coletor de Lixo)Curso Java Basico] Aula 66: Garbage Collector (Coletor de Lixo)
Curso Java Basico] Aula 66: Garbage Collector (Coletor de Lixo)
 
[Curso Java Basico] Aula 64: Classes aninhadas: internas, locais e anonimas
[Curso Java Basico] Aula 64: Classes aninhadas: internas, locais e anonimas[Curso Java Basico] Aula 64: Classes aninhadas: internas, locais e anonimas
[Curso Java Basico] Aula 64: Classes aninhadas: internas, locais e anonimas
 
Curso Java Basico] Aula 67: Criando Threads + metodos start, run e sleep
Curso Java Basico] Aula 67: Criando Threads + metodos start, run e sleepCurso Java Basico] Aula 67: Criando Threads + metodos start, run e sleep
Curso Java Basico] Aula 67: Criando Threads + metodos start, run e sleep
 
[Curso Java Basico - Orientacao a Objetos] Aula 43: Classe Object
[Curso Java Basico - Orientacao a Objetos] Aula 43: Classe Object[Curso Java Basico - Orientacao a Objetos] Aula 43: Classe Object
[Curso Java Basico - Orientacao a Objetos] Aula 43: Classe Object
 
[Curso Java Basico] Aula 55: Enum: metodos value e valueOf
[Curso Java Basico] Aula 55: Enum: metodos value e valueOf[Curso Java Basico] Aula 55: Enum: metodos value e valueOf
[Curso Java Basico] Aula 55: Enum: metodos value e valueOf
 
[Curso Java Basico - Orientacao a Objetos] Aula 42: Palavra chave final
[Curso Java Basico - Orientacao a Objetos] Aula 42: Palavra chave final[Curso Java Basico - Orientacao a Objetos] Aula 42: Palavra chave final
[Curso Java Basico - Orientacao a Objetos] Aula 42: Palavra chave final
 
[Curso Java Basico] Aula 56: Enum: metodos abstratos
[Curso Java Basico] Aula 56: Enum: metodos abstratos[Curso Java Basico] Aula 56: Enum: metodos abstratos
[Curso Java Basico] Aula 56: Enum: metodos abstratos
 
[Curso Java Basico] Aula 57: Wrappers: classes de tipos primitivos
[Curso Java Basico] Aula 57: Wrappers: classes de tipos primitivos[Curso Java Basico] Aula 57: Wrappers: classes de tipos primitivos
[Curso Java Basico] Aula 57: Wrappers: classes de tipos primitivos
 

Ähnlich wie JavaOne Brasil 2016: JavaEE e HTML5: da web/desktop ao mobile

jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
Kiril Iliev
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 

Ähnlich wie JavaOne Brasil 2016: JavaEE e HTML5: da web/desktop ao mobile (20)

jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecture
 
SharePoint Saturday Belgium 2018 - APIs, APIs everywhere!
SharePoint Saturday Belgium 2018 - APIs, APIs everywhere!SharePoint Saturday Belgium 2018 - APIs, APIs everywhere!
SharePoint Saturday Belgium 2018 - APIs, APIs everywhere!
 
APIs, APIs Everywhere!
APIs, APIs Everywhere!APIs, APIs Everywhere!
APIs, APIs Everywhere!
 
SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!
 
AI: Mobile Apps That Understands Your Intention When You Typed
AI: Mobile Apps That Understands Your Intention When You TypedAI: Mobile Apps That Understands Your Intention When You Typed
AI: Mobile Apps That Understands Your Intention When You Typed
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Top 10 Web Security Vulnerabilities
Top 10 Web Security VulnerabilitiesTop 10 Web Security Vulnerabilities
Top 10 Web Security Vulnerabilities
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learned
 
SharePoint Conference 2018 - Build an intelligent application by connecting i...
SharePoint Conference 2018 - Build an intelligent application by connecting i...SharePoint Conference 2018 - Build an intelligent application by connecting i...
SharePoint Conference 2018 - Build an intelligent application by connecting i...
 
Creating an Uber Clone - Part XIII - Transcript.pdf
Creating an Uber Clone - Part XIII - Transcript.pdfCreating an Uber Clone - Part XIII - Transcript.pdf
Creating an Uber Clone - Part XIII - Transcript.pdf
 
Bare-knuckle web development
Bare-knuckle web developmentBare-knuckle web development
Bare-knuckle web development
 
Building a TV show with Angular, Bootstrap, and Web Services
Building a TV show with Angular, Bootstrap, and Web ServicesBuilding a TV show with Angular, Bootstrap, and Web Services
Building a TV show with Angular, Bootstrap, and Web Services
 
European SharePoint Conference 2018 - Build an intelligent application by con...
European SharePoint Conference 2018 - Build an intelligent application by con...European SharePoint Conference 2018 - Build an intelligent application by con...
European SharePoint Conference 2018 - Build an intelligent application by con...
 
Micro app-framework - NodeLive Boston
Micro app-framework - NodeLive BostonMicro app-framework - NodeLive Boston
Micro app-framework - NodeLive Boston
 
Micro app-framework
Micro app-frameworkMicro app-framework
Micro app-framework
 
Aprimorando sua Aplicação com Ext JS 4 - BrazilJS
Aprimorando sua Aplicação com Ext JS 4 - BrazilJSAprimorando sua Aplicação com Ext JS 4 - BrazilJS
Aprimorando sua Aplicação com Ext JS 4 - BrazilJS
 
Engage 2023: Taking Domino Apps to the next level by providing a Rest API
Engage 2023: Taking Domino Apps to the next level by providing a Rest APIEngage 2023: Taking Domino Apps to the next level by providing a Rest API
Engage 2023: Taking Domino Apps to the next level by providing a Rest API
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentation
 
Angular 4 for Java Developers
Angular 4 for Java DevelopersAngular 4 for Java Developers
Angular 4 for Java Developers
 

Kürzlich hochgeladen

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Kürzlich hochgeladen (20)

Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 

JavaOne Brasil 2016: JavaEE e HTML5: da web/desktop ao mobile

  • 1. Java e HTML5: Do Desktop/Web ao Mobile Loiane Groner @loiane http://loiane.com http://loiane.training
  • 2. • 10+ XP TI • Java, JavaScript/HTML5, Sencha, Phonegap/Ionic, Angular • Blog: http://loiane.com • Cursos: http://loiane.training
  • 4. Ferramentas de um dev Java/HTML5
  • 5. • JavaEE • HTML • CSS • JavaScript • IDE favorita • NetBeans, Eclipse, IntelliJ IDEA
  • 6. Desenvolvedor FrontEnd Desenvolvedor BackEnd Servidor PartevisívelnositewebParte“mágica”,nãovisívelaousuário http://www.alticreation.com/uploads/iceberg-front-end-back-end-developers.jpg
  • 7.
  • 8.
  • 9. Plataforma JavaEE para HTML5: • JSON • WebSocket • Concurrency • Batch • WebServices RESTful
  • 10. • JSON: JavaScript Object Notation
  • 11. • JSON: JavaScript Object Notation • É uma forma de trocar dados entre frontend e backend representados por chave-valor
  • 12. • JSON: JavaScript Object Notation • É uma forma de trocar dados entre frontend e backend representados por chave-valor • Exemplo: var meuObjeto = {nome : ‘Meu Nome’, idade: 21};
  • 13. • JSON: JavaScript Object Notation • É uma forma de trocar dados entre frontend e backend representados por chave-valor • Exemplo: var meuObjeto = {nome : ‘Meu Nome’, idade: 21}; • API JSON Java permite pasear, transformar e consultar objectos JSON
  • 14. • WebSocket: protocolo de aplicação que fornece comunicação dupla entre 2 pontos TCP • API Java fornece funcionalidade através de annotations
  • 15.
  • 16. • Concurrency: API Java que fornece funcionalidade de comunicação assíncrona
  • 17. • Concurrency: API Java que fornece funcionalidade de comunicação assíncrona • Batch: API Java que fornece funcionalidade de tarefas batch
  • 19. URL Verbo HTTP Desc api/contatos GET obtém lista de contatos api/contatos/:id GET obtém dados de contato específico api/contatos POST cria contato api/contatos/:id PUT atualiza contato api/contatos/:id DELETE deleta contato
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25. @Entity @Table(name = "contact") @XmlRootElement @NamedQueries({ @NamedQuery(name = "Contact.findAll", query = "SELECT c FROM Contact c"), @NamedQuery(name = "Contact.findById", query = "SELECT c FROM Contact c WHERE c.id = :id"), @NamedQuery(name = "Contact.findByEmail", query = "SELECT c FROM Contact c WHERE c.email = :email"), @NamedQuery(name = "Contact.findByName", query = "SELECT c FROM Contact c WHERE c.name = :name"), @NamedQuery(name = "Contact.findByPhone", query = "SELECT c FROM Contact c WHERE c.phone = :phone")}) public class Contact implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Basic(optional = false) @Column(name = "id") private Integer id; @Basic(optional = false) @NotNull @Size(min = 1, max = 255) @Column(name = "email") private String email; @Basic(optional = false) @NotNull @Size(min = 1, max = 255) @Column(name = "name") private String name; //… }
  • 26. @Stateless @Path("contact") public class ContactFacadeREST extends AbstractFacade<Contact> { @POST @Override @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public void create(Contact entity) { super.create(entity); } @PUT @Path("{id}") @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public void edit(@PathParam("id") Integer id, Contact entity) { super.edit(entity); } @DELETE @Path("{id}") public void remove(@PathParam("id") Integer id) { super.remove(super.find(id)); } @GET @Path("{id}") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Contact find(@PathParam("id") Integer id) { return super.find(id); } @GET @Override @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public List<Contact> findAll() { return super.findAll(); } }
  • 27.
  • 28.
  • 29.
  • 30.
  • 31. @JsonAutoDetect @Entity @Table(name="CONTACT") public class Contact { @Id @GeneratedValue @Column(name="id") private int id; @Column(name="name", nullable=false) private String name; @Column(name="phone", nullable=false) private String phone; @Column(name="email", nullable=false) private String email; }
  • 32. @Repository public class ContactDAO { private HibernateTemplate hibernateTemplate; @Autowired public void setSessionFactory(SessionFactory sessionFactory) { hibernateTemplate = new HibernateTemplate(sessionFactory); } public List<Contact> getContacts(int start, int limit) { DetachedCriteria criteria = DetachedCriteria.forClass(Contact.class); return hibernateTemplate.findByCriteria(criteria, start, limit); } public void deleteContact(int id){ Object record = hibernateTemplate.load(Contact.class, id); hibernateTemplate.delete(record); } }
  • 33. @Controller public class ContactController { private ContactService contactService; @RequestMapping(value="/contact/view.action") public @ResponseBody Map<String,? extends Object> view(@RequestParam int start, @RequestParam int limit) throws Exception { try{ List<Contact> contacts = contactService.getContactList(start,limit); int total = contactService.getTotalContacts(); return ExtJSReturn.mapOK(contacts, total); } catch (Exception e) { return ExtJSReturn.mapError("Error retrieving Contacts from database."); } } @RequestMapping(value="/contact/create.action") public @ResponseBody Map<String,? extends Object> create(@RequestBody ContactWrapper data) throws Exception { try{ List<Contact> contacts = contactService.create(data.getData()); return ExtJSReturn.mapOK(contacts); } catch (Exception e) { return ExtJSReturn.mapError("Error trying to create contact."); } } }
  • 34.
  • 36.
  • 41. Plataforma HTML5 <canvas> <video> <audio> CSS3 Animações Transformações Sencha Ext JS Angular Backbone Knockout Ember Pré-processadores Sass, Less Emmet Dart
  • 42. Plataforma HTML5 <canvas> <video> <audio> CSS3 Animações Transformações Sencha Ext JS Angular Backbone Knockout Ember Pré-processadores Sass, Less Emmet Dart Mobile Híbrido Phonegap/Cordova Ionic
  • 43. Plataforma HTML5 <canvas> <video> <audio> CSS3 Animações Transformações Sencha Ext JS Angular Backbone Knockout Ember Pré-processadores Sass, Less Emmet Dart Mobile Híbrido Phonegap/Cordova Ionic Desktop Híbrido TideSDK AppJS Node web-kit Electron
  • 44.
  • 45.
  • 47. +
  • 48.
  • 51. APIs REST Banco de Dados JSON JSON
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60. import {bootstrap} from '@angular/platform-browser-dynamic'; import { HTTP_PROVIDERS } from '@angular/http'; import {AppComponent} from './app.component'; bootstrap(AppComponent, [HTTP_PROVIDERS]);
  • 61. import {Component} from '@angular/core'; import {ContactsComponent} from './contacts/contacts.component'; @Component({ selector: 'my-app', directives: [ContactsComponent], template: '<contacts-grid></contacts-grid>' }) export class AppComponent { }
  • 62. export class Contact { id: number; name: string; phone: string; email: string; }
  • 63. import { Injectable } from '@angular/core'; import { Http, Response } from '@angular/http'; import 'rxjs/add/operator/map'; @Injectable() export class ContactsService { constructor(private http: Http) { } getContacts() { return this.http.get('http://localhost:8080/contacts-spring-mvc/contact/view.action? start=0&limit=250') .map((res: Response) => res.json().data); } }
  • 64. import {Component, OnInit} from '@angular/core'; import {AgGridNg2} from 'ag-grid-ng2/main'; import {Contact} from './contact.model'; import {ContactsService} from './contacts.service'; @Component({ selector: 'contacts-grid', directives: [AgGridNg2], providers: [ContactsService], template: ` <ag-grid-ng2 #agGrid style="height:100%;width:583px" class="ag-fresh" [gridOptions]="gridOptions" [rowData]="contacts"> </ag-grid-ng2 > ` }) export class ContactsComponent implements OnInit { contacts: Contact[] = []; columnDefs = [ {headerName: 'Name', field: "name", width: 200 }, {headerName: 'Phone', field: "phone" ,width:180}, {headerName: 'Email', field: "email" ,width:200} ]; gridOptions : any = []; constructor(private contactsService: ContactsService) { this.gridOptions = { rowData: this.contacts, columnDefs: this.columnDefs, enableColResize: true, enableSorting: true, enableFilter: true } } ngOnInit() { this.contactsService.getContacts() .subscribe(contacts => this.contacts = contacts);
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73. import {Component} from '@angular/core'; import { HTTP_PROVIDERS } from '@angular/http'; import {Platform, ionicBootstrap} from 'ionic-angular'; import {StatusBar} from 'ionic-native'; import {TabsPage} from './pages/tabs/tabs'; @Component({ template: '<ion-nav [root]="rootPage"></ion-nav>' }) export class MyApp { private rootPage:any; constructor(private platform:Platform) { this.rootPage = TabsPage; platform.ready().then(() => { StatusBar.styleDefault(); }); } } ionicBootstrap(MyApp, [HTTP_PROVIDERS]);
  • 74. import {Component} from '@angular/core' import {HomePage} from '../home/home'; import {AboutPage} from '../about/about'; import {ContactPage} from '../contact/contact'; @Component({ templateUrl: 'build/pages/tabs/tabs.html' }) export class TabsPage { private tab1Root: any; private tab2Root: any; private tab3Root: any; constructor() { // this tells the tabs component which Pages // should be each tab's root Page this.tab1Root = HomePage; this.tab2Root = AboutPage; this.tab3Root = ContactPage; } } <ion-tabs> <ion-tab [root]="tab3Root" tabTitle="Contatos" tabIcon="contacts"></ion-tab> <ion-tab [root]="tab1Root" tabTitle="Inicio" tabIcon="home"></ion-tab> <ion-tab [root]="tab2Root" tabTitle="Sobre" tabIcon="information-circle"></ion-tab> </ion-tabs>
  • 75. import {Component, OnInit} from '@angular/core'; import {NavController} from 'ionic-angular'; import {Contact} from '../contact/contact.model'; import {ContactsService} from '../contact/contacts.service'; import {ContactDetailsPage} from '../contact-details/contact-details'; @Component({ templateUrl: 'build/pages/contact/contact.html', providers: [ContactsService] }) export class ContactPage implements OnInit { contacts: Contact[] = []; constructor(private nav: NavController, private contactsService: ContactsService) { } ngOnInit() { this.contactsService.getContacts() .subscribe(contacts => this.contacts = contacts); } itemSelected(contact){ this.nav.push(ContactDetailsPage, contact); } }
  • 76. <ion-navbar *navbar> <ion-title> Contact </ion-title> </ion-navbar> <ion-content> <ion-list> <ion-item *ngFor="let contact of contacts" (click)="itemSelected(contact)"> {{contact.name}} </ion-item> </ion-list> </ion-content>
  • 77. import {Component} from '@angular/core'; import {NavController, NavParams} from 'ionic-angular'; import {Contact} from '../contact/contact.model'; @Component({ templateUrl: 'build/pages/contact-details/contact-details.html' }) export class ContactDetailsPage { contact: Contact; constructor(private nav: NavController, private navParams: NavParams) { this.contact = this.navParams.data; } }
  • 78. <ion-navbar *navbar> <ion-title>{{contact.name}}</ion-title> </ion-navbar> <ion-content padding class="speaker-detail"> <p>Id: <span>{{contact.id}}</span></p> <p>Nome: <span>{{contact.name}}</span></p> <p>Email: <span>{{contact.phone}}</span></p> <p>Telefone: <span>{{contact.email}}</span></p> </ion-content>
  • 79.
  • 81.
  • 82.
  • 83.
  • 85. const electron = require('electron') const app = electron.app const BrowserWindow = electron.BrowserWindow let mainWindow function createWindow () { mainWindow = new BrowserWindow({width: 800, height: 600}) mainWindow.loadURL(`file://${__dirname}/index.html`) mainWindow.webContents.openDevTools() mainWindow.on('closed', function () { mainWindow = null }) } app.on('ready', createWindow) app.on('window-all-closed', function () { if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', function () { if (mainWindow === null) { createWindow() } })
  • 86. electron-packager ./ --platform=darwin --arch=x64 electron-packager ./ --platform=win32 --arch=x64 electron-packager ./ --platform=linux --arch=x64
  • 87.
  • 88.
  • 89.
  • 90.
  • 91. • SSL • Unauthorised access (acesso não autorizado) • Código backend sem validações • Dados sem criptografia (local e na troca de dados) • Mau uso da persistência
  • 94.