Aplikasi Web dengan IoC Starter. Pemetaan permintaan dasar menggunakan konteks ioc, ioc web dan ioc orm

gambar

Pendahuluan


Sejak rilis pertama, banyak waktu telah berlalu ( tautan ke artikel sebelumnya ). Apa yang berubah?


  • peningkatan stabilitas sistem secara keseluruhan;
  • menerapkan pemuatan komponen yang malas;
  • Sistem pendengar dasar bawaan
  • dukungan bawaan untuk pemrograman berorientasi aspek (untuk masalah penyelesaian kesulitan sedang, jika tidak saya sarankan Anda untuk menggunakan pustaka AspectJ lainnya)
  • bootloader RequestFactory baru
  • pekerjaan terintegrasi dengan cache berdasarkan EhCache, Guava
  • work with stream terintegrasi (baik inisialisasi melalui penjelasan @SimpleTask dan langsung bekerja dengan pool)

** Modul


  • modul untuk bekerja dengan database (ORM ringan dengan dukungan untuk JPA, Transaksi, Driver NO-SQL - Orient, metode Crud, sistem repositori, dan permintaan yang dibuat secara otomatis dari fungsi kelas repositori)
  • Modul moncong web (pemetaan tautan melalui anotasi, dukungan untuk produsen / konsumen kustom, Halaman Rendering Template Kecepatan, Permintaan Keamanan Dasar, Sesi, Cookie, SSL) berdasarkan Netty 4.1.30.Final

Struktur kerangka kerja
struct


"Ini, tentu saja, semuanya baik-baik saja," Anda berkata, "tetapi ternyata semuanya bekerja?"
"Ya, itu berhasil. Aku meminta potongan."


Contoh proses implementasi


Untuk mengimplementasikan contoh, saya akan menggunakan Maven 3 dan Intelijj Idea 2018.2.


1) Hubungkan dependensi:


<?xml version="1.0" encoding="UTF-8"?> <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>example-webapp</artifactId> <groupId>org.ioc</groupId> <packaging>jar</packaging> <version>0.0.1</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <.source>1.8</source> <target>1.8</target> </configuration> <executions> <execution> <id>default-testCompile</id> <phase>test-compile</phase> <goals> <goal>testCompile</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.ioc</groupId> <artifactId>context-factory</artifactId> <version>2.2.4.STABLE</version> </dependency> <dependency> <groupId>org.ioc</groupId> <artifactId>orm-factory</artifactId> <version>2.2.4.STABLE</version> </dependency> <dependency> <groupId>org.ioc</groupId> <artifactId>web-factory</artifactId> <version>2.2.4.STABLE</version> </dependency> </dependencies> <repositories> <repository> <id>context</id> <url>https://raw.github.com/GenCloud/ioc_container/context</url> </repository> <repository> <id>cache</id> <url>https://raw.github.com/GenCloud/ioc_container/cache</url> </repository> <repository> <id>threading</id> <url>https://raw.github.com/GenCloud/ioc_container/threading</url> </repository> <repository> <id>orm</id> <url>https://raw.github.com/GenCloud/ioc_container/orm</url> </repository> <repository> <id>web</id> <url>https://raw.github.com/GenCloud/ioc_container/web</url> </repository> </repositories> </project> 

** Dia belum pindah ke pusat pakar, sayangnya.


Struktur proyek:
struktur
Pola MVC standar, bukan?


Buat titik masuk ke aplikasi:


 package org.examples.webapp; import org.ioc.annotations.context.ScanPackage; import org.ioc.annotations.modules.CacheModule; import org.ioc.annotations.modules.DatabaseModule; import org.ioc.annotations.modules.ThreadingModule; import org.ioc.annotations.modules.WebModule; import org.ioc.context.starter.IoCStarter; @WebModule @CacheModule @ThreadingModule @DatabaseModule @ScanPackage(packages = {"org.examples.webapp"}) public class AppMain { public static void main(String[] args) { IoCStarter.start(AppMain.class); } } 

** Penjelasan:
Annotation @ScanPackages - mendefinisikan paket kontekstual untuk mengidentifikasi komponen (pada orang umum - "sampah").
Annotation @WebModule - berfungsi untuk menghubungkan dan menginisialisasi pabrik web.
Annotation @CacheModule - digunakan untuk menghubungkan dan menginisialisasi pabrik cache, ini digunakan untuk operasi ORM yang benar (dalam versi yang akan datang, anotasi tidak akan diperlukan).
Annotation @ThreadingModule - digunakan untuk menghubungkan dan menginisialisasi pabrik thread, digunakan untuk operasi yang benar dari pabrik web (dalam versi yang akan datang, anotasi tidak akan diperlukan).
Annotation @DatabaseModule - Digunakan untuk menghubungkan dan menginisialisasi pabrik ORM.
Semua pabrik memiliki konfigurator default, yang dapat Anda ubah sendiri dengan mendefinisikan ulang fungsi pengaturan yang digunakan oleh pabrik (di setiap modul penjelasan kelas konfigurator didefinisikan ulang - Kelas <?> AutoConfigurationClass () default WebAutoConfiguration.class ), atau menonaktifkan konfigurasi apa pun menggunakan penjelasan @Kecualikan di main ruang kelas.
Utilitas IoCStarter adalah kelas penginisialisasi konteks utama.


Yah, semuanya tampaknya siap, konteksnya diinisialisasi, web bekerja pada port default 8081, tetapi tidak ada tautan, dan ketika kita pergi ke situs, itu benar-benar tidak memberi kita apa-apa. Baiklah, lanjutkan.


Mari kita buat file konfigurasi untuk modul kita. Secara default, semua konfigurasi dimuat dari {working_dir} /configs/default_settings.properties - kami akan membuatnya di sepanjang jalur yang sesuai.


 # Threading ioc.threads.poolName=shared ioc.threads.availableProcessors=4 ioc.threads.threadTimeout=0 ioc.threads.threadAllowCoreTimeOut=true ioc.threads.threadPoolPriority=NORMAL # Event dispather # -  ()    ( ) ioc.dispatcher.availableDescriptors=4 # Cache #   (EhFactory|GuavaFactory) cache.factory=org.ioc.cache.impl.EhFactory # Datasource #   (-, -  ) #LOCAL, LOCAL_SERVER, REMOTE datasource.orient.database-type=LOCAL #   datasource.orient.url=./database #    (   ) datasource.orient.database=orient #   datasource.orient.username=admin #   datasource.orient.password=admin #       (create, dropCreate, refresh, none) datasource.orient.ddl-auto=dropCreate #   ,      datasource.orient.showSql=true # Web server #     web.server.port=8081 #   SSL  web.server.ssl-enabled=false # in seconds #   ( 7200 . = 2 ) web.server.security.session.timeout=300 #  - web.server.velocity.input.encoding=UTF-8 web.server.velocity.output.encoding=UTF-8 #  - web.server.velocity.resource.loader=file #   web.server.velocity.resource.loader.class=org.apache.velocity.runtime.resource.loader.FileResourceLoader #    - web.server.velocity.resource.loading.path=./public 

Selanjutnya, kita memerlukan entitas pengguna dan repositori pengelolanya:
Penerapan TblAccount Entity:


 package org.examples.webapp.domain.entity; import org.ioc.web.security.user.UserDetails; import javax.persistence.*; import java.util.Collections; import java.util.List; @Entity public class TblAccount implements UserDetails { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private long id; @Column(name = "username") private String username; @Column(name = "password") private String password; @Transient private String repeatedPassword; public String getRepeatedPassword() { return repeatedPassword; } public void setRepeatedPassword(String repeatedPassword) { this.repeatedPassword = repeatedPassword; } @Override public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @Override public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public List<String> getRoles() { return Collections.singletonList("ROLE_USER"); } } 

** Penjelasan:
Semuanya standar seperti halnya dengan semua kerangka kerja pendukung JPA. Memetakan entitas menggunakan @. Entitas , membuat Kunci Utama menggunakan penjelasan @ .Id , memetakan kolom menggunakan penjelasan @Column. dan mewarisi dari UserDetails untuk mengidentifikasi entitas dalam modul Keamanan .


Penerapan TblAccountRepository Entity Repository:


 package org.examples.webapp.domain.repository; import org.examples.webapp.domain.entity.TblAccount; import org.ioc.annotations.context.IoCRepository; import org.ioc.orm.repositories.CrudRepository; import javax.transaction.Transactional; @IoCRepository public interface TblAccountRepository extends CrudRepository<TblAccount, Long> { @Transactional TblAccount findByUsernameEq(String username); } 

** Penjelasan:
Annotation @IoCRepository - berfungsi untuk menentukan berdasarkan konteks bahwa kelas adalah repositori dan perlu diproses “secara berbeda” .
Mendukung fungsi CRUD standar:


  • Entity fetch (ID id) - mendapatkan entitas tipe Entity dari database, atau dari cache dengan Primary Key;
  • List fetchAll () - mendapatkan semua entitas dari tipe Entitas, preloading mereka ke dalam cache;
  • membatalkan penyimpanan (Entitas entitas) - membuat / memperbarui entitas tipe Entity baik di database maupun di cache;
  • void delete (Entity entity) - menghapus entitas tipe Entity baik dari database maupun dari cache;
  • boolean exist (ID id) - memeriksa apakah ada entitas dalam database menggunakan Kunci Utama.
    Semua permintaan CRUD terjadi dalam transaksi.

Ini mendukung pembuatan kueri secara otomatis dengan mengesampingkan fungsi dengan kata kunci, seperti pada implementasi di atas ( TblAccount findByUsernameEq (String username) ) dan memanggil kueri yang terdaftar ( NamedQuery )


Function findByUsernameEq (String username) - mencari entitas berdasarkan bidang nama pengguna . Permintaan yang Dihasilkan:


  select * from tbl_account where username = 'username' 

Selanjutnya, kita memerlukan level untuk mengelola logika bisnis.
Implementasi AccountService:


 package org.examples.webapp.service; import org.examples.webapp.domain.entity.TblAccount; import org.examples.webapp.domain.repository.TblAccountRepository; import org.examples.webapp.responces.IMessage; import org.ioc.annotations.context.IoCComponent; import org.ioc.annotations.context.IoCDependency; import org.ioc.web.model.http.Request; import org.ioc.web.security.configuration.SecurityConfigureAdapter; import org.ioc.web.security.encoder.bcrypt.BCryptEncoder; import org.ioc.web.security.user.UserDetails; import org.ioc.web.security.user.UserDetailsProcessor; import java.util.Objects; import static org.examples.webapp.responces.IMessage.Type.ERROR; import static org.examples.webapp.responces.IMessage.Type.OK; @IoCComponent public class AccountService implements UserDetailsProcessor { @IoCDependency private TblAccountRepository tblAccountRepository; @IoCDependency private BCryptEncoder bCryptEncoder; @IoCDependency private SecurityConfigureAdapter securityConfigureAdapter; @Override public UserDetails loadUserByUsername(String username) { return tblAccountRepository.findByUsernameEq(username); } public void save(TblAccount tblAccount) { tblAccountRepository.save(tblAccount); } public void delete(TblAccount tblAccount) { tblAccountRepository.delete(tblAccount); } public IMessage tryCreateUser(String username, String password, String repeatedPassword) { if (username == null || username.isEmpty() || password == null || password.isEmpty() || repeatedPassword == null || repeatedPassword.isEmpty()) { return new IMessage(ERROR, "Invalid request parameters!"); } if (!Objects.equals(password, repeatedPassword)) { return new IMessage(ERROR, "Repeated password doesn't match!"); } final UserDetails userDetails = loadUserByUsername(username); if (userDetails != null) { return new IMessage(ERROR, "Account already exists!"); } final TblAccount account = new TblAccount(); account.setUsername(username); account.setPassword(bCryptEncoder.encode(password)); save(account); return new IMessage(OK, "Successfully created!"); } public IMessage tryAuthenticateUser(Request request, String username, String password) { if (username == null || username.isEmpty() || password == null || password.isEmpty()) { return new IMessage(ERROR, "Invalid request parameters!"); } final UserDetails userDetails = loadUserByUsername(username); if (userDetails == null) { return new IMessage(ERROR, "Account not found!"); } if (!bCryptEncoder.match(password, userDetails.getPassword())) { return new IMessage(ERROR, "Password does not match!"); } securityConfigureAdapter.getContext().authenticate(request, userDetails); return new IMessage(OK, "Successfully authenticated"); } public IMessage logout(Request request) { if (securityConfigureAdapter.getContext().removeAuthInformation(request)) { return new IMessage(OK, "/"); } return new IMessage(ERROR, "Credentials not found or not authenticated!"); } } 

** Penjelasan:
Annotation @IoCComponent - berfungsi untuk menginisialisasi kelas sebagai komponen.
Annotation @IoCDependency - Digunakan untuk menyuntikkan dependensi ke instance kelas.
Utilitas BCryptEncoder adalah implementasi dari BCrypt codec untuk enkripsi kata sandi (sejauh ini satu-satunya codec).
Contoh sistem SecurityConfigureAdapter - digunakan untuk bekerja dengan permintaan pemetaan dan sesi pengguna.
Fungsi UserDetails loadUserByUsername - fungsi yang diwariskan UserDetailsProcessor , berfungsi untuk memuat pengguna ke dalam sesi dan mengatur flag otentikasi (di masa depan untuk pemetaan standar otorisasi dalam Keamanan )
Fungsi IMessage tryCreateUser adalah fungsi pembuatan pengguna.
Fungsi IMessage tryAuthenticateUser - fungsi otentikasi pengguna.
Fungsi logout IMessage adalah fungsi untuk menghapus sesi dari pengguna yang diotorisasi.
Kelas IMessage adalah kelas utilitas untuk menampilkan informasi yang kita butuhkan di browser (json response).


 package org.examples.webapp.responces; public class IMessage { private final String message; private final Type type; public IMessage(String message) { this.message = message; type = Type.OK; } public IMessage(Type type, String message) { this.message = message; this.type = type; } public String getMessage() { return message; } public Type getType() { return type; } public enum Type { OK, ERROR } } 

Sekarang Anda membutuhkan implementasi tautan itu sendiri (pemetaan permintaan):


 package org.examples.webapp.mapping; import org.examples.webapp.domain.entity.TblAccount; import org.examples.webapp.responces.IMessage; import org.examples.webapp.service.AccountService; import org.ioc.annotations.context.IoCDependency; import org.ioc.annotations.web.IoCController; import org.ioc.web.annotations.Credentials; import org.ioc.web.annotations.MappingMethod; import org.ioc.web.annotations.RequestParam; import org.ioc.web.annotations.UrlMapping; import org.ioc.web.model.ModelAndView; import org.ioc.web.model.http.Request; @IoCController @UrlMapping("/") public class MainMapping { @IoCDependency private AccountService accountService; @UrlMapping public ModelAndView index() { final ModelAndView modelAndView = new ModelAndView(); modelAndView.setView("index"); return modelAndView; } @UrlMapping(value = "signup", method = MappingMethod.POST) public IMessage createUser(@RequestParam("username") String username, @RequestParam("password") String password, @RequestParam("repeatedPassword") String repeatedPassword) { return accountService.tryCreateUser(username, password, repeatedPassword); } @UrlMapping(value = "signin", method = MappingMethod.POST) public IMessage auth(Request request, @RequestParam("username") String username, @RequestParam("password") String password) { return accountService.tryAuthenticateUser(request, username, password); } @UrlMapping("signout") public IMessage signout(Request request) { return accountService.logout(request); } @UrlMapping("loginPage") public ModelAndView authenticated(@Credentials TblAccount account) { final ModelAndView modelAndView = new ModelAndView(); modelAndView.setView("auth"); modelAndView.addAttribute("account", account); return modelAndView; } } 

** Penjelasan:
Annotation @IoCController - berfungsi untuk mengidentifikasi kelas dalam konteks sebagai pengontrol (browser request mapper)
Annotation @UrlMapping - menunjukkan bahwa perlu untuk menganalisis suatu fungsi / kelas untuk keberadaan permintaan yang diproses oleh penangan saluran.
Parameter:


  • nilai - permintaan yang kita butuhkan;
  • metode - metode http untuk pemrosesan (GET, POST, PUT, dll.);
  • mengkonsumsi - jenis http mime untuk memeriksa keberadaan permintaan dari tipe tertentu (opsional);
  • menghasilkan - tipe konten http untuk mengembalikan tipe konten tertentu dalam respons (Tipe-Konten: teks / html; charset = utf-8, Tipe-Konten: multipart / formulir-data; batas = sesuatu, dll. opsional;

Annotation @RequestParam - berfungsi untuk menentukan nama parameter yang diterima dari permintaan. Karena tidak mungkin untuk mendapatkan nama parameter metode saat ini dengan cara refleksi standar, saya terlalu malas untuk menghubungkan ketergantungan javaassist tambahan, untuk dukun dengan asm. Oleh karena itu, metode penentuan nama parameter untuk menanamkan nilai parameter ini diperoleh dari permintaan. Ada analog untuk tipe GET - @PathVariable - prinsip operasi yang sama (tidak kompatibel dengan POST ).
Penjelasan @Kredensial - berfungsi untuk menyisipkan data saat ini dari pengguna yang diotorisasi, jika tidak, akan menjadi nol jika informasi pengguna yang diotorisasi tidak ada dalam sesi.
Sistem kelas Permintaan adalah informasi terkini tentang permintaan masuk, yang berisi koka, tajuk, dan saluran pengguna, yang nantinya dapat dikirim ke Push Message ... yang sudah memiliki semacam fantasi dalam hal ini.
Kelas utilitas ModelAndView adalah model halaman dengan nama sumber daya tanpa ekstensi, dan atribut untuk disematkan dalam sumber daya.


Tampaknya semuanya, tetapi tidak - Anda harus mengkonfigurasi pemetaan permintaan yang tersedia untuk pengguna.


 package org.examples.webapp.config; import org.ioc.annotations.configuration.Property; import org.ioc.annotations.configuration.PropertyFunction; import org.ioc.web.security.configuration.HttpContainer; import org.ioc.web.security.configuration.SecurityConfigureProcessor; import org.ioc.web.security.encoder.Encoder; import org.ioc.web.security.encoder.bcrypt.BCryptEncoder; import org.ioc.web.security.filter.CorsFilter; import org.ioc.web.security.filter.CsrfFilter; @Property public class SecurityConfig implements SecurityConfigureProcessor { @Override public void configure(HttpContainer httpContainer) { httpContainer. configureRequests(). anonymousRequests("/", "/signup", "/signin"). resourceRequests("/static/**"). authorizeRequests("/loginPage", "ROLE_USER"). authorizeRequests("/signout", "ROLE_USER"). and(). configureSession(). expiredPath("/"); } @PropertyFunction public CsrfFilter csrfFilter() { return new CsrfFilter(); } @PropertyFunction public CorsFilter corsFilter() { return new CorsFilter(); } @PropertyFunction public Encoder encoder() { return new BCryptEncoder(); } } 

** Penjelasan:
@Property annotation - memberi tahu konteksnya bahwa ini adalah file konfigurasi dan perlu diinisialisasi.
Annotation @PropertyFunction - menginformasikan penganalisa konfigurasi bahwa fungsi ini mengembalikan beberapa jenis dan harus menginisialisasi sebagai komponen (bin).
Antarmuka SecurityConfigureProcessor - utilitas yang digunakan untuk mengkonfigurasi pemetaan permintaan.
Kelas model HttpContainer adalah utilitas yang menyimpan pemetaan permintaan yang ditentukan oleh pengguna.
Kelas CsrfFilter adalah filter permintaan yang tidak valid (implementasi mekanika CSRF).
Kelas CorsFilter adalah filter Berbagi Sumber Daya Silang-Asal.


Fungsi AnonymousRequests - menerima berbagai permintaan tanpa batas, tidak memerlukan pengguna yang sah dan pengecekan peran (ROLE_ANONYMOUS).
Fungsi resourceRequests - mengambil array permintaan yang tidak terbatas, secara khusus berfungsi untuk menentukan jalur mana file sumber daya akan menjadi yang tidak memerlukan pemrosesan kompleks (css, js, gambar, dll.).
Function authorizeRequests - mengambil dalam array permintaan yang tidak terbatas, membutuhkan pengguna yang berwenang dan peran khusus yang melekat dalam pengguna.
Fungsi ExpiredPath - ketika membersihkan sesi yang telah berakhir pada waktunya, pengguna diarahkan oleh pemetaan ini (redirect link).


Ya, ada halaman, skrip, dan gaya situs (saya tidak akan masuk lebih dalam).


Judul spoiler

index.vm - halaman utama


 <html> <head> <meta charset="utf-8"/> <title>IoC Test</title> <link rel="stylesheet" href="/static/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/css/style.css"/> <link rel="stylesheet" href="/static/css/pnotify.custom.min.css"/> <link rel="stylesheet" href="/static/css/pnotify.css"/> <link rel="stylesheet" href="/static/css/pnotify.buttons.css"/> </head> <body> <div class="container"> <h1>IoC Starter Test</h1> <br> <h4>Create user</h4> <br> <form id="creation"> <label for="username">Username: </label> <input type="text" id="username" name="username" class="color-input-field"/> <label for="password">Password: </label> <input type="password" id="password" name="password" class="color-input-field"/> <label for="repeatedPassword">Repeate: </label> <input type="password" id="repeatedPassword" name="repeatedPassword" class="color-input-field"/> <button type="button" class="btn btn-success btn-create">Sing up!</button> </form> <h4>Authenticate</h4> <br> <form id="auth"> <label for="username">Username: </label> <input type="text" id="username" name="username" class="color-input-field"/> <label for="password">Password: </label> <input type="password" id="password" name="password" class="color-input-field"/> <button type="button" class="btn btn-danger btn-auth">Sing in!</button> </form> </div> <script type="text/javascript" src="/static/js/jquery.js"></script> <script type="text/javascript" src="/static/js/bootstrap.min.js"></script> <script type="text/javascript" src="/static/js/scripts.js"></script> <script type="text/javascript" src="/static/js/pnotify.js"></script> <script type="text/javascript" src="/static/js/pnotify.buttons.js"></script> </body> </html> 

auth.vm - untuk menampilkan pengguna yang diotorisasi


 <html> <head> <meta charset="utf-8"/> <title>IoC Test</title> <link rel="stylesheet" href="/static/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/css/style.css"/> <link rel="stylesheet" href="/static/css/pnotify.custom.min.css"/> <link rel="stylesheet" href="/static/css/pnotify.css"/> <link rel="stylesheet" href="/static/css/pnotify.buttons.css"/> </head> <body> <div class="container"> <h1>Authorized page</h1> <br> <h4>Test auth data</h4> <div id="auth_data"> #if($!account) <h4>Hello @$!account.username, You successfully authenticated!</h4> <br> <button type="button" class="btn btn-success btn-logout">Logout!</button> #end </div> </div> <script type="text/javascript" src="/static/js/jquery.js"></script> <script type="text/javascript" src="/static/js/bootstrap.min.js"></script> <script type="text/javascript" src="/static/js/scripts.js"></script> <script type="text/javascript" src="/static/js/pnotify.js"></script> <script type="text/javascript" src="/static/js/pnotify.buttons.js"></script> </body> </html> 

scripts.js - controller, untuk mengirim dan menerima informasi permintaan ke server


 $(function () { $(".btn-create").click(function () { var cooki = cookie(); document.cookie = 'CSRF-TOKEN=' + cooki; $.ajax({ url: "/signup", data: $('#creation').serialize(), headers: {'X-CSRF-TOKEN': cooki}, crossDomain: true, xhrFields: { withCredentials: true }, type: "POST" }).done(function (data) { switch (data.type) { case 'OK': new PNotify({ title: 'Success', text: data.message, type: 'success', hide: false }); break; case 'ERROR': new PNotify({ title: 'Error', text: data.message, type: 'error', hide: false }); break; } }); }); $(".btn-auth").click(function () { var cooki = cookie(); document.cookie = 'CSRF-TOKEN=' + cooki; $.ajax({ url: "/signin", data: $('#auth').serialize(), headers: {'X-CSRF-TOKEN': cooki}, crossDomain: true, xhrFields: { withCredentials: true }, type: "POST" }).done(function (data) { switch (data.type) { case 'OK': new PNotify({ title: 'Success', text: data.message, type: 'success', hide: false }); setTimeout(function () { window.location = "/loginPage"; }, 5000); break; case 'ERROR': new PNotify({ title: 'Error', text: data.message, type: 'error', hide: false }); break; } }); }); $(".btn-logout").click(function () { $.ajax({ url: "/signout", crossDomain: true, xhrFields: { withCredentials: true }, type: "GET" }).done(function (data) { switch (data.type) { case 'OK': new PNotify({ title: 'Success', text: 'Logouting...', type: 'success', hide: false }); setTimeout(function () { window.location = data.message; }, 5000); break; case 'ERROR': new PNotify({ title: 'Error', text: data.message, type: 'error', hide: false }); break; } }); }); }); function cookie(a) { return a // if the placeholder was passed, return ? ( // a random number from 0 to 15 a ^ // unless b is 8, Math.random() // in which case * 16 // a random number from >> a / 4 // 8 to 11 ).toString(16) // in hexadecimal : ( // or otherwise a concatenated string: [1e7] + // 10000000 + -1e3 + // -1000 + -4e3 + // -4000 + -8e3 + // -80000000 + -1e11 // -100000000000, ).replace( // replacing /[018]/g, // zeroes, ones, and eights with cookie // random hex digits ) } 

Kompilasi, jalankan semua yang kita miliki.
Jika semuanya benar, kita akan melihat sesuatu seperti ini di akhir unduhan:


Log

[21.10.18 22: 29: 51: 990] INFO web.model.mapping.MappingContainer: Metode yang dipetakan [/], metode = [GET], ke [public org.ioc.web.model.ModelAndView org.examples.webapp .mapping.MainMapping.index ()]
[21.10.18 22: 29: 51: 993] INFO web.model.mapping.MappingContainer: Metode yang dipetakan [/ pendaftaran], metode = [POST], ke [public org.examples.webapp.respon.IMessage org.examples. webapp.mapping.MainMapping.createUser (java.lang.String, java.lang.String, java.lang.String)]
[21.10.18 22: 29: 51: 993] INFO web.model.mapping.mappingContainer: Metode yang dipetakan [/ masuk], metode = [POST], ke [public org.examples.webapp.respon.IMessage org.examples. webapp.mapping.MainMapping.auth (org.ioc.web.model.http.Request, java.lang.String, java.lang.String)]
[21.10.18 22: 29: 51: 993] INFO web.model.mapping.MappingContainer: Metode yang dipetakan [/ signout], method = [GET], ke [public org.examples.webapp.respon.IMessage org.examples. webapp.mapping.MainMapping.signout (org.ioc.web.model.http.Request)]
[21.10.18 22: 29: 51: 995] INFO web.model.mapping.MappingContainer: Metode yang dipetakan [/ loginPage], metode = [GET], ke [public org.ioc.web.model.ModelAndView org.examples. webapp.mapping.MainMapping.authenticated (org.examples.webapp.domain.entity.TblAccount)]
[21.10.18 22: 29: 51: 997] INFO ioc.web.factory.HttpInitializerFactory: Server Http dimulai pada port: 8081 (http)


Hasil:
1) Halaman depan
indeks
2) Pendaftaran
pendaftaran
3) Otentikasi
auth
4) Halaman dengan hasil otorisasi (redirect setelah memasukkan login dan kata sandi dengan benar)
hasil
5) Menghapus informasi otorisasi dari sesi dan mengarahkan pengguna ke halaman awal
gambar
6) Suatu upaya oleh pengguna yang tidak sah untuk sampai ke halaman dengan informasi otentikasi sesi
gambar


Akhirnya


Proyek ini berkembang, “kontributor” dan ide-ide orisinal dipersilakan, karena sulit untuk melakukan proyek ini sendirian.
Repositori proyek .
Konteks
Pabrik ORM
Pabrik web
Contohnya
Contoh terkini dari artikel
Juga di repositori terdapat beberapa contoh penggunaan semua fungsi dalam modul 'contoh' , dan seperti yang mereka katakan, "Selamat mencoba, bersenang-senang", terima kasih atas perhatian Anda.

Source: https://habr.com/ru/post/id427247/


All Articles