{"id":98077,"date":"2019-09-16T08:10:17","date_gmt":"2019-09-16T05:10:17","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=98077"},"modified":"2019-09-19T08:56:31","modified_gmt":"2019-09-19T05:56:31","slug":"build-mobile-apps-angular-ionic-4-spring-boot","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2019\/09\/build-mobile-apps-angular-ionic-4-spring-boot.html","title":{"rendered":"Build Mobile Apps with Angular, Ionic 4, and Spring Boot"},"content":{"rendered":"<p><span style=\"font-size: 20px;\"><strong>Friends don\u2019t let friends write user auth. Tired of managing your own users?<\/strong><a href=\"https:\/\/developer.okta.com\/signup\/?utm_campaign=text_website_all_multiple_dev_dev_ionic-4-angular-spring-boot-jhipster_&amp;utm_source=jcg&amp;utm_medium=cpc\"> Try Okta\u2019s API and Java SDKs today. Authenticate, manage, and secure users in any application within minutes.<\/a><\/span><\/p>\n<p>I\u2019m a big fan of Ionic. I started using it several years ago when it was based on AngularJS. As a developer, I really liked it because I knew Angular. I found didn\u2019t have to learn much more to be a productive developer with Ionic.<\/p>\n<p>What is Ionic? I\u2019m glad you asked! Ionic is an open source project that allows you to build mobile apps using web tech.<\/p>\n<p>Technically, this is called a &#8220;hybrid&#8221; app because it\u2019s not using native SDKs. Hybrid mobile apps are distributed just like native apps: they can be installed on mobile devices, and they\u2019re listed in app stores. As an end user, there\u2019s a good chance you can\u2019t tell the difference between a hybrid mobile app and a native mobile app.<\/p>\n<p>Not only that, but Ionic supports PWAs! This means you can deploy the same app to the web that you package up and ship to an app store. Maximum discoverability FTW!<\/p>\n<p>If you know me, you\u2019ll know I\u2019m a big fan of Java, Spring Boot, and JHipster as well. If you don\u2019t know what JHipster is, I\u2019m sorry. That\u2019s my fault. I\u2019ve been doing my best to spread the word, but you somehow missed it. It\u2019s the best thing ever! If you know me from AppFuse, or you\u2019re familiar with Ruby on Rails, it\u2019s that times 10. JHipster is an application generator, and platform, for building Java apps with JavaScript frontends.<\/p>\n<p>Spring Boot is the only backend framework currently supported, with .NET and Node.js implementations currently in development. On the frontend, Angular, React, Vue, React Native, and Ionic are all supported.<\/p>\n<p>In this brief tutorial, I\u2019ll show you to use&nbsp;<a href=\"https:\/\/github.com\/oktadeveloper\/generator-jhipster-ionic\">Ionic for JHipster<\/a>&nbsp;v4 with Spring Boot and JHipster 6.<\/p>\n<p>To complete this tutorial, you\u2019ll need to have Java 8+, Node.js 10+, and Docker installed. You\u2019ll also need to create an&nbsp;<a href=\"https:\/\/developer.okta.com\/signup\/?utm_campaign=text_website_all_multiple_dev_dev_ionic-4-angular-spring-boot-jhipster_&amp;utm_source=jcg&amp;utm_medium=cpc\">Okta developer account<\/a>.<\/p>\n<h2 class=\"wp-block-heading\" id=\"create-a-spring-boot-angular-app-with-jhipster\">Create a Spring Boot + Angular App with JHipster<\/h2>\n<p>You can install JHipster via&nbsp;<a href=\"http:\/\/brewformulas.org\/Jhipster\">Homebrew<\/a>&nbsp;(<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">brew install jhipster<\/code>) or with npm.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;bash\">npm i -g generator-jhipster@6.1.2<\/pre>\n<p>Once you have JHipster installed, you have two choices. There\u2019s the quick way to generate an app (which I recommend), and there\u2019s the tedious way of picking all your options. I don\u2019t care which one you use, but you&nbsp;<strong>must<\/strong>&nbsp;select&nbsp;<strong>OAuth 2.0 \/ OIDC<\/strong>&nbsp;authentication to complete this tutorial successfully.<\/p>\n<p>Here\u2019s the easy way:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">mkdir app &amp;&amp; cd app\n\necho \"application { config { baseName oauth2, authenticationType oauth2, \\\n  buildTool gradle, testFrameworks [protractor] }}\" &gt;&gt; app.jh\n\njhipster import-jdl app.jh<\/pre>\n<p>The hard way is you run&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">jhipster<\/code>&nbsp;and answer a number of questions. There are so many choices when you run this option that you might question your sanity. At last count, I remember reading that JHipster allows 26K+ combinations!<br \/>The project generation process will take a couple of minutes to complete if you\u2019re on fast internet and have a bad-ass laptop. When it\u2019s finished, you should see output like the following.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/create-app-1024x489.png\" alt=\"\" class=\"wp-image-98079\" width=\"768\" height=\"367\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/create-app-1024x489.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/create-app-300x143.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/create-app-768x367.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/create-app.png 1600w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<h3 class=\"wp-block-heading\" id=\"oidc-with-keycloak-and-spring-security\">OIDC with Keycloak and Spring Security<\/h3>\n<p>JHipster has several authentication options: JWT, OAuth 2.0 \/ OIDC, and UAA. With JWT (the default), you store the access token on the client (in local storage). This works but isn\u2019t the most secure. UAA involves using your own OAuth 2.0 authorization server (powered by Spring Security), and OAuth 2.0 \/ OIDC allows you to use Keycloak or Okta.<\/p>\n<p>Spring Security makes Keycloak and Okta integration so incredibly easy it\u2019s silly. Keycloak and Okta are called &#8220;identity providers&#8221; and if you have a similar solution that is OIDC-compliant, I\u2019m confident it\u2019ll work with Spring Security and JHipster.<\/p>\n<p>Having Keycloak set by default is nice because you can use it without having an internet connection.<\/p>\n<p>To log into the JHipster app you just created, you\u2019ll need to have Keycloak up and running. When you create a JHipster project with OIDC for authentication, it creates a Docker container definition that has the default users and roles. Start Keycloak using the following command.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">docker-compose -f src\/main\/docker\/keycloak.yml up -d<\/pre>\n<p>Start your application with&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.\/gradlew<\/code>&nbsp;(or&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.\/mvnw<\/code>&nbsp;if you chose Maven) and you should be able to log in using &#8220;admin\/admin&#8221; for your credentials.<\/p>\n<p>Open another terminal and prove all the end-to-end tests pass:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">npm run e2e<\/pre>\n<p>If your environment is setup correctly, you\u2019ll see output like the following:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">&gt; oauth-2@0.0.0 e2e \/Users\/mraible\/app\n&gt; protractor src\/test\/javascript\/protractor.conf.js\n\n[16:02:18] W\/configParser - pattern .\/e2e\/entities\/**\/*.spec.ts did not match any files.\n[16:02:18] I\/launcher - Running 1 instances of WebDriver\n[16:02:18] I\/direct - Using ChromeDriver directly...\n\n\n  account\n    ? should fail to login with bad password\n    ? should login successfully with admin account (1754ms)\n\n  administration\n    ? should load metrics\n    ? should load health\n    ? should load configuration\n    ? should load audits\n    ? should load logs\n\n\n  7 passing (15s)\n\n[16:02:36] I\/launcher - 0 instance(s) of WebDriver still running\n[16:02:36] I\/launcher - chrome #01 passed\nExecution time: 19 s.\n<\/pre>\n<h2 class=\"wp-block-heading\" id=\"oidc-with-okta-and-spring-security\">OIDC with Okta and Spring Security<\/h2>\n<p>To switch to Okta, you\u2019ll first need to create an OIDC app. If you don\u2019t have an Okta Developer account,&nbsp;<a href=\"https:\/\/developer.okta.com\/signup\/?utm_campaign=text_website_all_multiple_dev_dev_ionic-4-angular-spring-boot-jhipster_&amp;utm_source=jcg&amp;utm_medium=cpc\">now is the time<\/a>!<\/p>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Why Okta instead of Keycloak?<\/strong><\/p>\n<p>Keycloak works great in development, and Okta has free multi-factor authentication, email support, and excellent performance for production. A developer account gets you 1000 monthly active users for free! You can see other free features and our transparent pricing at&nbsp;<a href=\"https:\/\/developer.okta.com\/pricing\/?utm_campaign=text_website_all_multiple_dev_dev_ionic-4-angular-spring-boot-jhipster_&amp;utm_source=jcg&amp;utm_medium=cpc\">developer.okta.com\/pricing<\/a>.<\/p>\n<\/blockquote>\n<p>Log in to your Okta Developer account.<\/p>\n<ul class=\"wp-block-list\">\n<li>In the top menu, click on&nbsp;<strong>Applications<\/strong><\/li>\n<li>Click on&nbsp;<strong>Add Application<\/strong><\/li>\n<li>Select&nbsp;<strong>Web<\/strong>&nbsp;and click&nbsp;<strong>Next<\/strong><\/li>\n<li>Enter&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">JHipster FTW!<\/code>&nbsp;for the Name (this value doesn\u2019t matter, so feel free to change it)<\/li>\n<li>Change the Login redirect URI to be&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\"><a class=\"bare\" href=\"http:\/\/localhost:8080\/login\/oauth2\/code\/oidc\">http:\/\/localhost:8080\/login\/oauth2\/code\/oidc<\/a><\/code><\/li>\n<li>Click&nbsp;<strong>Done<\/strong>, then&nbsp;<strong>Edit<\/strong>&nbsp;and add&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\"><a class=\"bare\" href=\"http:\/\/localhost:8080\/\">http:\/\/localhost:8080<\/a><\/code>&nbsp;as a Logout redirect URI<\/li>\n<li>Click&nbsp;<strong>Save<\/strong><\/li>\n<\/ul>\n<p>These are the steps you\u2019ll need to complete for JHipster. Start your JHipster app using a command like the following:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;bash\">SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER_URI=https:\/\/{yourOktaDomain}\/oauth2\/default \\\n  SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_ID=$clientId \\\n  SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_SECRET=$clientSecret .\/gradlew<\/pre>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p> The above command can be painful to type, so I encourage you to copy\/paste, or set the values as environment variables. You can also configure them in a properties\/YAML file in Spring Boot, but you should&nbsp;<a href=\"https:\/\/developer.okta.com\/blog\/2018\/07\/30\/10-ways-to-secure-spring-boot#8-store-secrets-securely?utm_campaign=text_website_all_multiple_dev_dev_ionic-4-angular-spring-boot-jhipster_&amp;utm_source=jcg&amp;utm_medium=cpc\">never store secrets in source control<\/a>. <div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<\/blockquote>\n<h3 class=\"wp-block-heading\" id=\"create-a-native-app-for-ionic\">Create a Native App for Ionic<\/h3>\n<p>You\u2019ll also need to create a Native app for Ionic. The reason for this is because Ionic for JHipster is configured to use&nbsp;<a href=\"https:\/\/oauth.net\/2\/pkce\/\">PKCE<\/a>&nbsp;(Proof Key for Code Exchange). The current Spring Security OIDC support in JHipster still requires a client secret. PKCE does not.<br \/>Go back to the Okta developer console and follow the steps below:<\/p>\n<ul class=\"wp-block-list\">\n<li>In the top menu, click on&nbsp;<strong>Applications<\/strong><\/li>\n<li>Click on&nbsp;<strong>Add Application<\/strong><\/li>\n<li>Select&nbsp;<strong>Native<\/strong>&nbsp;and click&nbsp;<strong>Next<\/strong><\/li>\n<li>Enter&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Ionic FTW!<\/code>&nbsp;for the Name<\/li>\n<li>Add Login redirect URIs:&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\"><a class=\"bare\" href=\"http:\/\/localhost:8100\/implicit\/callback\">http:\/\/localhost:8100\/implicit\/callback<\/a><\/code>&nbsp;and&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">dev.localhost.ionic:\/callback<\/code><\/li>\n<li>Click&nbsp;<strong>Done<\/strong>, then&nbsp;<strong>Edit<\/strong>&nbsp;and add Logout redirect URIs:&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\"><a class=\"bare\" href=\"http:\/\/localhost:8100\/implicit\/logout\">http:\/\/localhost:8100\/implicit\/logout<\/a><\/code>&nbsp;and&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">dev.localhost.ionic:\/logout<\/code><\/li>\n<li>Click&nbsp;<strong>Save<\/strong><\/li>\n<\/ul>\n<p>You\u2019ll need the client ID from your Native app, so keep your browser tab open or copy\/paste it somewhere.<\/p>\n<h3 class=\"wp-block-heading\" id=\"create-groups-and-add-them-as-claims-to-the-id-token\">Create Groups and Add Them as Claims to the ID Token<\/h3>\n<p>In order to login to your JHipster app, you\u2019ll need to adjust your Okta authorization server to include a&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">groups<\/code>&nbsp;claim.<\/p>\n<p>On Okta, navigate to&nbsp;<strong>Users<\/strong>&nbsp;&gt;&nbsp;<strong>Groups<\/strong>. Create&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">ROLE_ADMIN<\/code>&nbsp;and&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">ROLE_USER<\/code>&nbsp;groups and add your account to them.<\/p>\n<p>Navigate to&nbsp;<strong>API<\/strong>&nbsp;&gt;&nbsp;<strong>Authorization Servers<\/strong>, click the&nbsp;<strong>Authorization Servers<\/strong>&nbsp;tab and edit the&nbsp;<strong>default<\/strong>&nbsp;one. Click the&nbsp;<strong>Claims<\/strong>&nbsp;tab and&nbsp;<strong>Add Claim<\/strong>. Name it &#8220;groups&#8221; or &#8220;roles&#8221; and include it in the ID Token. Set the value type to &#8220;Groups&#8221; and set the filter to be a Regex of&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.*<\/code>. Click&nbsp;<strong>Create<\/strong>.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/add-claim-1024x841.png\" alt=\"\" class=\"wp-image-98080\" width=\"768\" height=\"631\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/add-claim-1024x841.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/add-claim-300x246.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/add-claim-768x631.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/add-claim.png 1226w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<p>Navigate to&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\"><a class=\"bare\" href=\"http:\/\/localhost:8080\/\">http:\/\/localhost:8080<\/a><\/code>, click&nbsp;<strong>sign in<\/strong>&nbsp;and you\u2019ll be redirected to Okta to log in.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/okta-login-1024x635.png\" alt=\"\" class=\"wp-image-98081\" width=\"768\" height=\"476\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/okta-login-1024x635.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/okta-login-300x186.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/okta-login-768x476.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/okta-login.png 1600w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<p>Enter the credentials you used to signup for your account, and you should be redirected back to your JHipster app.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/jhipster-oktafied-1024x635.png\" alt=\"\" class=\"wp-image-98084\" width=\"768\" height=\"476\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/jhipster-oktafied-1024x635.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/jhipster-oktafied-300x186.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/jhipster-oktafied-768x476.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/jhipster-oktafied.png 1600w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<h2 class=\"wp-block-heading\" id=\"generate-entities-for-a-photo-gallery\">Generate Entities for a Photo Gallery<\/h2>\n<p>Let\u2019s enhance this example a bit and create a photo gallery that you can upload pictures to. Kinda like Flickr, but waaayyyy more primitive.<\/p>\n<p>JHipster has a JDL (JHipster Domain Language) feature that allows you to model the data in your app, and generate entities from it. You can use its&nbsp;<a href=\"https:\/\/start.jhipster.tech\/jdl-studio\/\">JDL Studio<\/a>&nbsp;feature to do this online and save it locally once you\u2019ve finished.<\/p>\n<p>I created a data model for this app that has an&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Album<\/code>,&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Photo<\/code>, and&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Tag<\/code>&nbsp;entities and set up relationships between them. Below is a screenshot of what it looks like in JDL Studio.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/photos-jdl-1024x685.png\" alt=\"\" class=\"wp-image-98085\" width=\"768\" height=\"514\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/photos-jdl-1024x685.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/photos-jdl-300x201.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/photos-jdl-768x514.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/photos-jdl.png 1600w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<p>Copy the JDL below and save it in a&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">photos.jdl<\/code>&nbsp;file in the root directory of your project.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:js\">entity Album {\n  title String required,\n  description TextBlob,\n  created Instant\n}\n\nentity Photo {\n  title String required,\n  description TextBlob,\n  image ImageBlob required,\n  taken Instant\n}\n\nentity Tag {\n  name String required minlength(2)\n}\n\nrelationship ManyToOne {\n  Album{user(login)} to User,\n  Photo{album(title)} to Album\n}\n\nrelationship ManyToMany {\n  Photo{tag(name)} to Tag{photo}\n}\n\npaginate Album with pagination\npaginate Photo, Tag with infinite-scroll\n<\/pre>\n<p>You can generate entities and CRUD code (Java for Spring Boot; TypeScript and HTML for Angular) using the following command:<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:bash\">jhipster import-jdl photos.jdl<\/pre>\n<p>When prompted, type&nbsp;<strong>a<\/strong>&nbsp;to update existing files.<\/p>\n<p>This process will create&nbsp;<a href=\"https:\/\/www.liquibase.org\/\">Liquibase<\/a>&nbsp;changelog files (to create your database tables), entities, repositories, Spring MVC controllers, and all the Angular code that\u2019s necessary to create, read, update, and delete your data objects. It\u2019ll even generate Jest unit tests and Protractor end-to-end tests!<\/p>\n<p>When the process completes, restart your app, and confirm that all your entities exist (and work) under the&nbsp;<strong>Entities<\/strong>&nbsp;menu.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/photos-list-1024x554.png\" alt=\"\" class=\"wp-image-98086\" width=\"768\" height=\"416\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/photos-list-1024x554.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/photos-list-300x162.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/photos-list-768x416.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/photos-list.png 1600w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<p>You might notice that the entity list screen is pre-loaded with data. This is done by&nbsp;<a href=\"https:\/\/github.com\/marak\/Faker.js\/\">faker.js<\/a>. To turn it off, edit&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">src\/main\/resources\/config\/application-dev.yml<\/code>, search for&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">liquibase<\/code>&nbsp;and set its&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">contexts<\/code>&nbsp;value to&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">dev<\/code>. I made this change in this example\u2019s code and ran&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.\/gradlew clean<\/code>&nbsp;to clear the database.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">liquibase:\n  # Add 'faker' if you want the sample data to be loaded automatically\n  contexts: dev<\/pre>\n<h2 class=\"wp-block-heading\" id=\"develop-a-mobile-app-with-ionic-and-angular\">Develop a Mobile App with Ionic and Angular<\/h2>\n<p>Getting started with Ionic for JHipster is similar to JHipster. You simply have to install the Ionic CLI, Yeoman, the module itself, and run a command to create the app.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">npm i -g generator-jhipster-ionic@4.0.0 ionic@5.1.0 yo\nyo jhipster-ionic<\/pre>\n<p>If you have your&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">app<\/code>&nbsp;application at&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">~\/app<\/code>, you should run this command from your home directory (<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">~<\/code>). Ionic for JHipster will prompt you for the location of your backend application. Use&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">mobile<\/code>&nbsp;for your app\u2019s name and&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">app<\/code>&nbsp;for the JHipster app\u2019s location.<\/p>\n<p>Type&nbsp;<strong>a<\/strong>&nbsp;when prompted to overwrite&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">mobile\/src\/app\/app.component.ts<\/code>.<\/p>\n<p>Open&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">mobile\/src\/app\/auth\/auth.service.ts<\/code>&nbsp;in an editor, search for&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">data.clientId<\/code>&nbsp;and replace it with the client ID from your Native app on Okta.<\/p>\n<pre class=\"wp-block-preformatted gutter: false;brush:java\">\/\/ try to get the oauth settings from the server\nthis.requestor.xhr({method: 'GET', url: AUTH_CONFIG_URI}).then(async (data: any) =&gt; {\n  this.authConfig = {\n    identity_client: '{yourClientId}',\n    identity_server: data.issuer,\n    redirect_url: redirectUri,\n    end_session_redirect_url: logoutRedirectUri,\n    scopes,\n    usePkce: true\n  };\n  ...\n}<\/pre>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p> When using Keycloak, this change is not necessary. <\/p>\n<\/blockquote>\n<h3 class=\"wp-block-heading\" id=\"add-claims-to-access-token\">Add Claims to Access Token<\/h3>\n<p>In order to authentication successfully with your Ionic app, you have to do a bit more configuration in Okta. Since the Ionic client will only send an access token to JHipster, you need to 1) add a&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">groups<\/code>&nbsp;claim to the access token and 2) add a couple more claims so the user\u2019s name will be available in JHipster.<\/p>\n<p>Navigate to&nbsp;<strong>API<\/strong>&nbsp;&gt;&nbsp;<strong>Authorization Servers<\/strong>, click the&nbsp;<strong>Authorization Servers<\/strong>&nbsp;tab and edit the&nbsp;<strong>default<\/strong>&nbsp;one. Click the&nbsp;<strong>Claims<\/strong>&nbsp;tab and&nbsp;<strong>Add Claim<\/strong>. Name it &#8220;groups&#8221; and include it in the Access Token. Set the value type to &#8220;Groups&#8221; and set the filter to be a Regex of&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">.*<\/code>. Click&nbsp;<strong>Create<\/strong>.<\/p>\n<p>Add another claim, name it&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">given_name<\/code>, include it in the access token, use&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">Expression<\/code>&nbsp;in the value type, and set the value to&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">user.firstName<\/code>. Optionally, include it in the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">profile<\/code>&nbsp;scope. Perform the same actions to create a&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">family_name<\/code>&nbsp;claim and use expression&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">user.lastName<\/code>.<\/p>\n<p>When you are finished, your claims should look as follows.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/claims-1024x560.png\" alt=\"\" class=\"wp-image-98087\" width=\"768\" height=\"420\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/claims-1024x560.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/claims-300x164.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/claims-768x420.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/claims.png 1600w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<p>Run the following commands to start your Ionic app.<\/p>\n<pre class=\"gutter: false;brush:bash\">cd mobile\nionic serve<\/pre>\n<p>You\u2019ll see a screen with a sign-in button. Click on it, and you\u2019ll be redirected to Okta to authenticate.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/ionic-home-and-login-1024x438.png\" alt=\"\" class=\"wp-image-98089\" width=\"768\" height=\"329\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/ionic-home-and-login-1024x438.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/ionic-home-and-login-300x128.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/ionic-home-and-login-768x328.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/ionic-home-and-login.png 1600w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<p>Now that you having log in working, you can use the entity generator to generate Ionic pages for your data model. Run the following commands (in your&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">~\/mobile<\/code>&nbsp;directory) to generate screens for your entities.<\/p>\n<pre class=\"gutter: false;brush:bash\">yo jhipster-ionic:entity album<\/pre>\n<p>When prompted to generate this entity from an existing one, type&nbsp;<strong>Y<\/strong>. Enter&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">..\/app<\/code>&nbsp;as the path to your existing application. When prompted to regenerate entities and overwrite files, type&nbsp;<strong>Y<\/strong>. Enter&nbsp;<strong>a<\/strong>&nbsp;when asked about conflicting files.<\/p>\n<p>Go back to your browser where your Ionic app is running (or restart it if you stopped it). Click on&nbsp;<strong>Entities<\/strong>&nbsp;on the bottom, then&nbsp;<strong>Albums<\/strong>. Click the blue + icon in the bottom corner, and add a new album.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/new-album-1024x735.png\" alt=\"\" class=\"wp-image-98090\" width=\"768\" height=\"551\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/new-album-1024x735.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/new-album-300x215.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/new-album-768x552.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/new-album.png 1600w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<p>Click the \u2714\ufe0f in the top right corner to save your album. You\u2019ll see a success message and it listed on the next screen.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/ionic-albums-1024x735.png\" alt=\"\" class=\"wp-image-98091\" width=\"768\" height=\"551\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/ionic-albums-1024x735.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/ionic-albums-300x215.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/ionic-albums-768x552.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/ionic-albums.png 1600w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<p>Refresh your JHipster app\u2019s album list and you\u2019ll see it there too!<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/jhipster-albums-1024x536.png\" alt=\"\" class=\"wp-image-98092\" width=\"768\" height=\"402\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/jhipster-albums-1024x536.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/jhipster-albums-300x157.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/jhipster-albums-768x402.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/jhipster-albums.png 1600w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<p>Generate code for the other entities using the following commands and the same answers as above.<\/p>\n<pre class=\"gutter: false;brush:bash\">yo jhipster-ionic:entity photo\nyo jhipster-ionic:entity tag<\/pre>\n<h2 class=\"wp-block-heading\" id=\"run-your-ionic-app-on-ios\">Run Your Ionic App on iOS<\/h2>\n<p>To generate an iOS project for your Ionic application, run the following command:<\/p>\n<pre class=\"gutter: false;brush:bash\">ionic cordova prepare ios\n<\/pre>\n<p>When prompted to install the&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">ios<\/code>&nbsp;platform, type&nbsp;<strong>Y<\/strong>. When the process completes, open your project in Xcode:<\/p>\n<pre class=\"gutter: false;brush:bash\">open platforms\/ios\/MyApp.xcworkspace\n<\/pre>\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p> If you don\u2019t have Xcode installed, you can&nbsp;<a href=\"https:\/\/developer.apple.com\/xcode\/\">download it from Apple<\/a>. <\/p>\n<\/blockquote>\n<p>You\u2019ll need to configure code signing in the&nbsp;<strong>General<\/strong>&nbsp;tab, then you should be able to run your app in Simulator.<\/p>\n<p>Log in to your Ionic app, tap&nbsp;<strong>Entities<\/strong>&nbsp;and view the list of photos.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/5-1024x617.png\" alt=\"\" class=\"wp-image-98093\" width=\"768\" height=\"463\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/5-1024x617.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/5-300x181.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/5-768x463.png 768w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<p>Add a photo in the JHipster app at&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\"><a href=\"http:\/\/localhost:8080\/\">http:\/\/localhost:8080<\/a><\/code>.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/6-1024x518.png\" alt=\"\" class=\"wp-image-98094\" width=\"768\" height=\"389\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/6-1024x518.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/6-300x152.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/6-768x388.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/6.png 1600w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<p>To see this new album in your Ionic app, pull down with your mouse to simulate the pull-to-refresh gesture on a phone. Looky there &#8211; it works!<\/p>\n<p>There are some gestures you should know about on this screen. Clicking on the row will take you to a view screen where you can see the photo\u2019s details. You can also swipe left to expose edit and delete buttons.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/77-1024x617.png\" alt=\"\" class=\"wp-image-98095\" width=\"768\" height=\"463\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/77-1024x617.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/77-300x181.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/09\/77-768x463.png 768w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<h2 class=\"wp-block-heading\" id=\"run-your-ionic-app-on-android\">Run Your Ionic App on Android<\/h2>\n<p>Deploying your app on Android is very similar to iOS. In short:<\/p>\n<ol class=\"wp-block-list\">\n<li>Make sure you\u2019re using Java 8<\/li>\n<li>Run&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">ionic cordova prepare android<\/code><\/li>\n<li>Open&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">platforms\/android<\/code>&nbsp;in Android Studio, upgrade Gradle if prompted<\/li>\n<li>Set&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">launchMode<\/code>&nbsp;to&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">singleTask<\/code>&nbsp;in&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">AndroidManifest.xml<\/code><\/li>\n<li>Start your app using Android Studio<\/li>\n<li>While your app is starting, run&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">adb reverse tcp:8080 tcp:8080<\/code>&nbsp;so the emulator can talk to JHipster<\/li>\n<\/ol>\n<p>For more thorough instructions, see my&nbsp;<a href=\"https:\/\/developer.okta.com\/blog\/2019\/06\/20\/ionic-4-tutorial-user-authentication-and-registration#run-your-ionic-4-app-on-android?utm_campaign=text_website_all_multiple_dev_dev_ionic-4-angular-spring-boot-jhipster_&amp;utm_source=jcg&amp;utm_medium=cpc\">Ionic 4 tutorial\u2019s Android section<\/a>.<\/p>\n<h2 class=\"wp-block-heading\" id=\"learn-more-about-ionic-4-and-jhipster-6\">Learn More About Ionic 4 and JHipster 6<\/h2>\n<p>Ionic is a nice way to leverage your web development skills to build mobile apps. You can do most of your development in the browser, and deploy to your device when you\u2019re ready to test it. You can also just deploy your app as a PWA and not both to deploy it to an app store.<\/p>\n<p>JHipster supports PWAs too, but I think Ionic apps&nbsp;<em>look<\/em>&nbsp;like native apps, which is a nice effect. There\u2019s a lot more I could cover about JHipster and Ionic, but this should be enough to get you started.<\/p>\n<p>You can find the source code for the application developed in this post on GitHub at&nbsp;<a href=\"https:\/\/github.com\/oktadeveloper\/okta-ionic4-jhipster-example\">@oktadeveloper\/okta-ionic4-jhipster-example<\/a>.<\/p>\n<p>I\u2019ve written a few other posts on Ionic, JHipster, and Angular. Check them out if you have a moment.<\/p>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2019\/06\/20\/ionic-4-tutorial-user-authentication-and-registration#run-your-ionic-4-app-on-android?utm_campaign=text_website_all_multiple_dev_dev_ionic-4-angular-spring-boot-jhipster_&amp;utm_source=jcg&amp;utm_medium=cpc\">Tutorial: User Login and Registration in Ionic 4<\/a><\/li>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2019\/05\/23\/java-microservices-spring-cloud-config?utm_campaign=text_website_all_multiple_dev_dev_ionic-4-angular-spring-boot-jhipster_&amp;utm_source=jcg&amp;utm_medium=cpc\">Java Microservices with Spring Cloud Config and JHipster<\/a><\/li>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2019\/05\/13\/angular-8-spring-boot-2?utm_campaign=text_website_all_multiple_dev_dev_ionic-4-angular-spring-boot-jhipster_&amp;utm_source=jcg&amp;utm_medium=cpc\">Angular 8 + Spring Boot 2.2: Build a CRUD App Today!<\/a><\/li>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2019\/04\/04\/java-11-java-12-jhipster-oidc?utm_campaign=text_website_all_multiple_dev_dev_ionic-4-angular-spring-boot-jhipster_&amp;utm_source=jcg&amp;utm_medium=cpc\">Better, Faster, Lighter Java with Java 12 and JHipster 6<\/a><\/li>\n<li><a href=\"https:\/\/developer.okta.com\/blog\/2018\/10\/10\/react-native-spring-boot-mobile-app?utm_campaign=text_website_all_multiple_dev_dev_ionic-4-angular-spring-boot-jhipster_&amp;utm_source=jcg&amp;utm_medium=cpc\">Build a Mobile App with React Native and Spring Boot<\/a><\/li>\n<\/ul>\n<p>Give&nbsp;<a href=\"https:\/\/twitter.com\/oktadev\">@oktadev<\/a>&nbsp;a follow on Twitter if you liked this tutorial. You might also want to&nbsp;<a href=\"https:\/\/www.youtube.com\/c\/oktadev\">subscribe to our YouTube channel<\/a>. If you have any questions, please leave a comment or post your question to&nbsp;<a href=\"https:\/\/www.stackoverflow.com\/\">Stack Overflow<\/a>&nbsp;with a&nbsp;<code class=\"highlighter-rouge\" style=\"font-size: 13px;\">jhipster<\/code>&nbsp;tag.<\/p>\n<p><a href=\"https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster?utm_campaign=text_website_all_multiple_dev_dev_ionic-4-angular-spring-boot-jhipster_&amp;utm_source=jcg&amp;utm_medium=cpc\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">&#8220;Build Mobile Apps with Angular, Ionic 4, and Spring Boot&#8221;<\/a>&nbsp;was originally published on the Okta Developer blog on June 24, 2019. <\/p>\n<p><span style=\"font-size: 20px;\"><strong>Friends don\u2019t let friends write user auth. Tired of managing your own users?<\/strong><a href=\"https:\/\/developer.okta.com\/signup\/?utm_campaign=text_website_all_multiple_dev_dev_ionic-4-angular-spring-boot-jhipster_&amp;utm_source=jcg&amp;utm_medium=cpc\"> Try Okta\u2019s API and Java SDKs today. Authenticate, manage, and secure users in any application within minutes.<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Friends don\u2019t let friends write user auth. Tired of managing your own users? Try Okta\u2019s API and Java SDKs today. Authenticate, manage, and secure users in any application within minutes. I\u2019m a big fan of Ionic. I started using it several years ago when it was based on AngularJS. As a developer, I really liked &hellip;<\/p>\n","protected":false},"author":13127,"featured_media":240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[740,1932,30,854],"class_list":["post-98077","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-angular","tag-ionic","tag-spring","tag-spring-boot"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Build Mobile Apps with Angular, Ionic 4, and Spring Boot - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Interested to learn about Mobile Apps? Check our article explaining how to build mobile apps with Angular, Ionic 4, and Spring Boot\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Build Mobile Apps with Angular, Ionic 4, and Spring Boot - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Interested to learn about Mobile Apps? Check our article explaining how to build mobile apps with Angular, Ionic 4, and Spring Boot\" \/>\n<meta property=\"og:url\" content=\"https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2019-09-16T05:10:17+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-09-19T05:56:31+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Matt Raible\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@mraible\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Matt Raible\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/06\\\/24\\\/ionic-4-angular-spring-boot-jhipster#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/09\\\/build-mobile-apps-angular-ionic-4-spring-boot.html\"},\"author\":{\"name\":\"Matt Raible\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/54edd49deb980d7706e2af51514c3f7f\"},\"headline\":\"Build Mobile Apps with Angular, Ionic 4, and Spring Boot\",\"datePublished\":\"2019-09-16T05:10:17+00:00\",\"dateModified\":\"2019-09-19T05:56:31+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/09\\\/build-mobile-apps-angular-ionic-4-spring-boot.html\"},\"wordCount\":2589,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/06\\\/24\\\/ionic-4-angular-spring-boot-jhipster#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"keywords\":[\"Angular\",\"Ionic\",\"Spring\",\"Spring Boot\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/06\\\/24\\\/ionic-4-angular-spring-boot-jhipster#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/09\\\/build-mobile-apps-angular-ionic-4-spring-boot.html\",\"url\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/06\\\/24\\\/ionic-4-angular-spring-boot-jhipster\",\"name\":\"Build Mobile Apps with Angular, Ionic 4, and Spring Boot - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/06\\\/24\\\/ionic-4-angular-spring-boot-jhipster#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/06\\\/24\\\/ionic-4-angular-spring-boot-jhipster#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"datePublished\":\"2019-09-16T05:10:17+00:00\",\"dateModified\":\"2019-09-19T05:56:31+00:00\",\"description\":\"Interested to learn about Mobile Apps? Check our article explaining how to build mobile apps with Angular, Ionic 4, and Spring Boot\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/06\\\/24\\\/ionic-4-angular-spring-boot-jhipster#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/06\\\/24\\\/ionic-4-angular-spring-boot-jhipster\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/06\\\/24\\\/ionic-4-angular-spring-boot-jhipster#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"spring-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/developer.okta.com\\\/blog\\\/2019\\\/06\\\/24\\\/ionic-4-angular-spring-boot-jhipster#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Build Mobile Apps with Angular, Ionic 4, and Spring Boot\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/54edd49deb980d7706e2af51514c3f7f\",\"name\":\"Matt Raible\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/753d82443e50aed1ed2746573af191fe3e45c277ff3bd29873012a1b614355a7?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/753d82443e50aed1ed2746573af191fe3e45c277ff3bd29873012a1b614355a7?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/753d82443e50aed1ed2746573af191fe3e45c277ff3bd29873012a1b614355a7?s=96&d=mm&r=g\",\"caption\":\"Matt Raible\"},\"description\":\"Java Champion and Developer Advocate @okta with a passion for skiing, mtn biking, VWs, &amp; good beer.\",\"sameAs\":[\"https:\\\/\\\/developer.okta.com\",\"https:\\\/\\\/x.com\\\/mraible\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/matt-raible\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Build Mobile Apps with Angular, Ionic 4, and Spring Boot - Java Code Geeks","description":"Interested to learn about Mobile Apps? Check our article explaining how to build mobile apps with Angular, Ionic 4, and Spring Boot","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster","og_locale":"en_US","og_type":"article","og_title":"Build Mobile Apps with Angular, Ionic 4, and Spring Boot - Java Code Geeks","og_description":"Interested to learn about Mobile Apps? Check our article explaining how to build mobile apps with Angular, Ionic 4, and Spring Boot","og_url":"https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2019-09-16T05:10:17+00:00","article_modified_time":"2019-09-19T05:56:31+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","type":"image\/jpeg"}],"author":"Matt Raible","twitter_card":"summary_large_image","twitter_creator":"@mraible","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Matt Raible","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2019\/09\/build-mobile-apps-angular-ionic-4-spring-boot.html"},"author":{"name":"Matt Raible","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/54edd49deb980d7706e2af51514c3f7f"},"headline":"Build Mobile Apps with Angular, Ionic 4, and Spring Boot","datePublished":"2019-09-16T05:10:17+00:00","dateModified":"2019-09-19T05:56:31+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2019\/09\/build-mobile-apps-angular-ionic-4-spring-boot.html"},"wordCount":2589,"commentCount":2,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","keywords":["Angular","Ionic","Spring","Spring Boot"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2019\/09\/build-mobile-apps-angular-ionic-4-spring-boot.html","url":"https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster","name":"Build Mobile Apps with Angular, Ionic 4, and Spring Boot - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster#primaryimage"},"image":{"@id":"https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","datePublished":"2019-09-16T05:10:17+00:00","dateModified":"2019-09-19T05:56:31+00:00","description":"Interested to learn about Mobile Apps? Check our article explaining how to build mobile apps with Angular, Ionic 4, and Spring Boot","breadcrumb":{"@id":"https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","width":150,"height":150,"caption":"spring-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/developer.okta.com\/blog\/2019\/06\/24\/ionic-4-angular-spring-boot-jhipster#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Build Mobile Apps with Angular, Ionic 4, and Spring Boot"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/54edd49deb980d7706e2af51514c3f7f","name":"Matt Raible","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/753d82443e50aed1ed2746573af191fe3e45c277ff3bd29873012a1b614355a7?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/753d82443e50aed1ed2746573af191fe3e45c277ff3bd29873012a1b614355a7?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/753d82443e50aed1ed2746573af191fe3e45c277ff3bd29873012a1b614355a7?s=96&d=mm&r=g","caption":"Matt Raible"},"description":"Java Champion and Developer Advocate @okta with a passion for skiing, mtn biking, VWs, &amp; good beer.","sameAs":["https:\/\/developer.okta.com","https:\/\/x.com\/mraible"],"url":"https:\/\/www.javacodegeeks.com\/author\/matt-raible"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/98077","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/13127"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=98077"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/98077\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/240"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=98077"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=98077"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=98077"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}