日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

jakarta ee_适用于Java EE / Jakarta EE开发人员的Micronaut

發(fā)布時間:2023/12/3 java 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jakarta ee_适用于Java EE / Jakarta EE开发人员的Micronaut 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

jakarta ee

城鎮(zhèn)中有一個名為Micronaut的新微服務框架。 在本文中,我將從Java EE / Jakarta EE的角度討論如何冒險使用Micronaut框架。 我是Java EE開發(fā)人員,因此使用諸如Eclipse MicroProfile之類的解決方案開發(fā)微服務更接近我的專業(yè)知識,但是Micronaut吸引了我的注意力,因為它具有以下功能:

–使用Java,Groovy或Kotlin開發(fā)

–易于通過Spock或JUnit進行測試..完全集成的測試

–嵌入式服務器和編譯時HTTP客戶端

–易于打包的Docker

–快速啟動時間,低內存消耗

–完全React

作為內心的企業(yè)開發(fā)人員,我的第一個想法通常是數據庫,因為我編寫的大多數應用程序都使用RDBMS。 我發(fā)現將Micronaut與RDBMS一起使用的示例數量很少,因此我認為為該用例創(chuàng)建另一個示例可能對我有用。 在此示例中,我使用PostgreSQL。 但是,大多數其他RDBMS也受支持。 本文并不意味著對安裝Micronaut或利用所有許多Micronaut功能進行完整的說明。 相反,它是那些希望開始使用帶有關系數據庫的Micronaut的入門指南……尤其適合那些具有Java EE / Jakarta EE背景的人。

在我的特殊情況下,我對快速完善可完全測試,可擴展和高效的微服務感興趣。 盡管我可以使用MicroProfile或標準Java EE做到這一點,但我認為學習一些新知識并具有使用Groovy或Kotlin的能力將很有趣。 我還想將Java EE / Jakarta EE放在上面……所以我正在使用JPA處理數據。 Micronaut的許多示例都使用Groovy和GORM來實現持久性……但是我可能不會在我的任何應用程序中使用它。

該示例是使用Apache NetBeans 9.0和Micronaut隨附的命令行界面(CLI)開發(fā)的 。 該特定示例是針對Micronaut 1.0.0.M4編寫的。 在這種情況下,我保持簡單,只使用一個基本數據庫表在PostgreSQL數據庫中進行持久化。

首先,我通過發(fā)出以下命令利用CLI創(chuàng)建了一個應用程序:

mn create-app org.acme.books --features hibernate-jpa,jdbc-tomcat

這只是在名為“ books”的目錄中為我的應用程序創(chuàng)建了一個框架,Application.java主類將放置在org.acme.books包中。 默認情況下,應用程序支持一些基本功能,但是在這種情況下,我添加了對Tomcat連接池的支持。 通過Java Persistence API(JPA)創(chuàng)建數據庫連接時,將利用此功能。 默認應用程序也會在支持Gradle構建系統的情況下生成。 因此,將創(chuàng)建一個build.gradle,即將在其中進行依賴項管理的文件。 請注意,也可以使用Apache Maven構建系統來生成應用程序,但是在Micronaut 1.0.0.M4下運行Maven項目時遇到了問題,因此在這個示例中我堅持使用Gradle。

如果使用Apache NetBeans 9.0,則可以安裝“ Groovy and Grails”和“ Gradle”插件(當前在NetBeans 8.2插件中心提供)以提供打開項目的支持。 一旦完成,就可以在NetBeans中打開項目并開始開發(fā)。 安裝插件并在Apache NetBeans中打開項目后,完整的項目結構應如下圖所示:

為了提供對PostgreSQL數據庫的支持,我在build.gradle中添加了依賴項:

compile group: 'org.postgresql', name: 'postgresql', version: '42.2.5'

接下來,我打開了application.yml文件,并為該應用程序添加了數據源。 這是替換傳統Java EE應用程序中的persistence.xml的文件。 同樣,通過此文件添加了JPA支持,指示哪個包包括實體類以及Hibernate的配置。 端口8080也已設置,因為默認情況下Micronaut將選擇一個隨機端口來啟動服務器。 application.xml的完整資源如下:

micronaut:application:name: books#Uncomment to set server portserver:port: 8080---datasources:default:url: jdbc:postgresql://localhost/postgresusername: postgrespassword: yourpassworddriverClassName: org.postgresql.DriverconnectionTimeout: 4000jpa:default:packages-to-scan:- 'org.acme.domain'properties:hibernate:hbm2ddl:auto: updateshow_sql: true

現在配置已不復存在,我可以開始有趣的部分了……開發(fā)。 在此示例中,我創(chuàng)建了一項基本服務,該服務允許創(chuàng)建,讀取,更新或刪除BOOK表中的記錄。 org.acme包中自動生成的Application類,用于啟動服務。

package org.acme;import io.micronaut.runtime.Micronaut;public class Application {public static void main(String[] args) {Micronaut.run(Application.class);}}

要開始開發(fā),請在應用程序內創(chuàng)建兩個用于組織源代碼的軟件包。 首先,創(chuàng)建org.acme.domain,它將包含實體類。 接下來,創(chuàng)建org.acme.book,其中將包含實現類。 在org.acme.domain包中創(chuàng)建一個Book.java類,它將是包含數據庫標準JPA映射的實體類。 在這種情況下,請注意,我將java.time.LocalDate用于日期字段,并將數據庫序列生成器用于主鍵填充。 來源如下:

package org.acme.domain;import java.time.LocalDate;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.SequenceGenerator;import javax.persistence.Table;import javax.validation.constraints.NotNull;/*** JPA Mappings for the BOOK database table.*/@Entity@Table(name="BOOK")public class Book {@Id@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="book_generator")@SequenceGenerator(name="book_generator",sequenceName="book_s", allocationSize=1)private Long id;@Column(name="PUBLISH_DATE")@NotNullprivate LocalDate publishDate;@Column(name="TITLE")@NotNullprivate String title;@Column(name="AUTHOR_FIRST")@NotNullprivate String authorFirst;@Column(name="AUTHOR_LAST")@NotNullprivate String authorLast;private Long pages;public Book(){}public Book(@NotNull Long id, @NotNull LocalDate publishDate, @NotNull String title, String authorFirst, String authorLast, Long pages){this.id = id;this.publishDate = publishDate;this.title = title;this.authorFirst = authorFirst;this.authorLast = authorLast;this.pages = pages;}public Book(@NotNull LocalDate publishDate, @NotNull String title, String authorFirst, String authorLast, Long pages){this.publishDate = publishDate;this.title = title;this.authorFirst = authorFirst;this.authorLast = authorLast;this.pages = pages;}/*** @return the id*/public Long getId() {return id;}/*** @param id the id to set*/public void setId(Long id) {this.id = id;}/*** @return the publishDate*/public LocalDate getPublishDate() {return publishDate;}/*** @param publishDate the publishDate to set*/public void setPublishDate(LocalDate publishDate) {this.publishDate = publishDate;}/*** @return the title*/public String getTitle() {return title;}/*** @param title the title to set*/public void setTitle(String title) {this.title = title;}/*** @return the authorFirst*/public String getAuthorFirst() {return authorFirst;}/*** @param authorFirst the authorFirst to set*/public void setAuthorFirst(String authorFirst) {this.authorFirst = authorFirst;}/*** @return the authorLast*/public String getAuthorLast() {return authorLast;}/*** @param authorLast the authorLast to set*/public void setAuthorLast(String authorLast) {this.authorLast = authorLast;}/*** @return the pages*/public Long getPages() {return pages;}/*** @param pages the pages to set*/public void setPages(Long pages) {this.pages = pages;}@Overridepublic String toString() {return "Book{" +"id=" + id +", publishDate='" + publishDate + '\'' +", title='" + title + '\'' +", authorFirst='" + authorFirst + '\'' +", authorLast='" + authorLast + '\'' +", pages='" + pages +'}';}}

在Micronaut應用程序中,需要將HTTP請求和響應封裝在Serializable類中進行處理,因此,生成一些簡單的“純舊Java對象”(POJO)來封裝將在數據庫操作中使用的數據是有意義的。 在同一個org.acme.domain包中,我創(chuàng)建了兩個此類,BookSaveOperation.java和BookUpdateOperation.java。 這些類將定義將數據從HTTP請求傳遞到控制器類所需的字段。 BookSaveOperation.java的源如下(有關完整源,請參見GitHub存儲庫):

package org.acme.domain;import java.time.LocalDate;import javax.validation.constraints.NotBlank;import javax.validation.constraints.NotNull;/**** @author Josh Juneau*/public class BookSaveOperation implements java.io.Serializable {@NotNullprivate LocalDate publishDate;@NotNull@NotBlankprivate String title;@NotNull@NotBlankprivate String authorFirst;@NotNull@NotBlankprivate String authorLast;private Long pages;public BookSaveOperation(){}public BookSaveOperation(LocalDate publishDate, String title,String authorFirst, String authorLast, Long pages){this.publishDate = publishDate;this.title = title;this.authorFirst = authorFirst;this.authorLast = authorLast;this.pages = pages;}// ...// getters and setters// ...}

應用程序業(yè)務邏輯發(fā)生在一個類中,該類非常類似于EJB或DAO實現,并且該類必須實現定義了每個業(yè)務邏輯方法的接口。 在這種情況下,我創(chuàng)建了一個接口org.acme.book.BookRepository.java,并定義了一些標準的操作方法:

package org.acme.book;import java.time.LocalDate;import java.util.List;import java.util.Optional;import org.acme.domain.Book;/****/public interface BookRepository {Book save(LocalDate publishDate, String title, String authorFirst, String authorLast, Long pages);Optional<Book> findById(Long id);void deleteById(Long id);List<Book> findAll();int update(Long id, LocalDate publishDate, String title, String authorFirst, String authorLast, Long pages);}

接下來,在名為org.acme.book.BookRepositoryImpl.java的類中實現該接口,并注釋為@Singleton。 由于這是將實現業(yè)務邏輯的類,因此請注入PersistenceContext,該持久性上下文提供將用于執(zhí)行數據庫操作的JPA EntityManager。 只需實現BookRepository界面中概述的每個操作,并使用@Transactional(io.micronaut.spring.tx.annotation.Transactional)進行標記,就意味著僅對那些不會修改任何數據的方法進行只讀。 BookRepositoryImpl.java的源如下:

package org.acme.book;import io.micronaut.configuration.hibernate.jpa.scope.CurrentSession;import io.micronaut.spring.tx.annotation.Transactional;import java.time.LocalDate;import java.util.List;import java.util.Optional;import javax.inject.Singleton;import javax.persistence.EntityManager;import javax.persistence.PersistenceContext;import org.acme.domain.Book;/*** Business logic for the service.*/@Singletonpublic class BookRepositoryImpl implements BookRepository {@PersistenceContextprivate EntityManager entityManager;public BookRepositoryImpl(@CurrentSession EntityManager entityManager) {this.entityManager = entityManager;}@Override@Transactionalpublic Book save(LocalDate publishDate, String title, String authorFirst, String authorLast, Long pages) {Book book = new Book(publishDate, title, authorFirst, authorLast, pages);entityManager.persist(book);return book;}@Override@Transactional(readOnly = true)public Optional<Book> findById(Long id) {return Optional.ofNullable(entityManager.find(Book.class, id));}@Transactional(readOnly = true)public List<Book> findAll() {return entityManager.createQuery("SELECT b FROM Book b", Book.class).getResultList();}@Override@Transactionalpublic int update(Long id, LocalDate publishDate, String title, String authorFirst, String authorLast, Long pages) {return entityManager.createQuery("UPDATE Book b SET publishDate = :publishDate, title = :title, " +"authorFirst = :authorFirst, authorLast = :authorLast, pages = :pages where id = :id").setParameter("publishDate", publishDate).setParameter("title", title).setParameter("authorFirst", authorFirst).setParameter("authorLast", authorLast).setParameter("pages", pages).setParameter("id", id).executeUpdate();}@Override@Transactionalpublic void deleteById(Long id) {findById(id).ifPresent(book -> entityManager.remove(book));}}

為了從Java EE角度解釋Micronaut應用程序基礎結構,我將比較該實現與一個簡單的JAX-RS應用程序。 Micronaut利用io.micronaut.http.annotation.Controller類來執(zhí)行服務的請求-響應處理。 這非常類似于JAX-RS控制器類,但有一些細微的差異。 這讓我想起了Eclipse Krazo項目或Java EE的MVC 1.0。 例如,Micronaut而不是使用JAX-RS注釋javax.ws.rs.GET,javax.ws.rs.POST或javax.ws.rs.Path注釋方法,而是使用io.micronaut.http.annotation.Get和io.micronaut.http.annotation.Post等。 每個方法的URI路徑都可以通過@ Get,@ Post,@ Put,@ Delete批注直接聲明。 每個控制器類都將實現服務的功能并處理請求-響應生命周期。 通過@Inject批注或構造函數注入將用于持久性的業(yè)務邏輯(包含在BookRepositoryImpl類中)注入到控制器類中。 在此示例的源代碼中,使用了構造函數注入。

package org.acme.book;import org.acme.domain.Book;import io.micronaut.http.HttpHeaders;import io.micronaut.http.HttpResponse;import io.micronaut.http.annotation.Body;import io.micronaut.http.annotation.Controller;import io.micronaut.http.annotation.Delete;import io.micronaut.http.annotation.Get;import io.micronaut.http.annotation.Post;import io.micronaut.http.annotation.Put;import io.micronaut.validation.Validated;import javax.validation.Valid;import java.net.URI;import java.util.List;import org.acme.domain.BookSaveOperation;import org.acme.domain.BookUpdateOperation;@Validated@Controller("/books")public class BookController {protected final BookRepository bookRepository;public BookController(BookRepository bookRepository) {this.bookRepository = bookRepository;}@Get("/")public List<Book> list() {return bookRepository.findAll();}@Put("/")public HttpResponse update(@Body @Valid BookUpdateOperation operation) {bookRepository.update(operation.getId(), operation.getPublishDate(),operation.getTitle(), operation.getAuthorFirst(), operation.getAuthorLast(), operation.getPages());return HttpResponse.noContent().header(HttpHeaders.LOCATION, location(operation.getId()).getPath());}@Get("/{id}")Book show(Long id) {return bookRepository.findById(id).orElse(null);}@Delete("/{id}")HttpResponse delete(Long id) {bookRepository.deleteById(id);return HttpResponse.noContent();}@Post("/")HttpResponse<Book> save(@Body @Valid BookSaveOperation operation) {Book book = bookRepository.save(operation.getPublishDate(), operation.getTitle(),operation.getAuthorFirst(), operation.getAuthorLast(), operation.getPages());return HttpResponse.created(book).headers(headers -> headers.location(location(book)));}protected URI location(Book book) {return location(book.getId());}protected URI location(Long id) {return URI.create("/books/" + id);}}

測試應用

Micronaut可以使用Spock或JUnit以及嵌入式服務器輕松進行測試,從而可以輕松地為每個控制器創(chuàng)建測試。 在這種情況下,我利用JUnit來測試應用程序。 我在名為org.acme.BookControllerTest的項目的測試文件夾內創(chuàng)建了一個測試類。

package org.acme;import io.micronaut.context.ApplicationContext;import io.micronaut.core.type.Argument;import io.micronaut.http.HttpHeaders;import io.micronaut.http.HttpRequest;import io.micronaut.http.HttpResponse;import io.micronaut.http.HttpStatus;import io.micronaut.http.client.HttpClient;import io.micronaut.runtime.server.EmbeddedServer;import java.time.LocalDate;import java.util.ArrayList;import java.util.List;import org.acme.domain.Book;import org.acme.domain.BookSaveOperation;import org.acme.domain.BookUpdateOperation;import org.junit.AfterClass;import static org.junit.Assert.assertEquals;import org.junit.BeforeClass;import org.junit.Test;/*** Test cases for BookController*/public class BookControllerTest {private static EmbeddedServer server;private static HttpClient client;private? Book book;HttpRequest request;HttpResponse response;Long id;List<Long> bookIds = new ArrayList<>();@BeforeClasspublic static void setupServer() {server = ApplicationContext.run(EmbeddedServer.class);client = server.getApplicationContext().createBean(HttpClient.class, server.getURL());}@AfterClasspublic static void stopServer() {if (server != null) {server.stop();}if (client != null) {client.stop();}}@Testpublic void testInsertBooks() {request = HttpRequest.POST("/books", new BookSaveOperation(LocalDate.now(), "Java EE 8 Recipes", "Josh", "Juneau", new Long(750)));response = client.toBlocking().exchange(request);assertEquals(HttpStatus.CREATED, response.getStatus());request = HttpRequest.POST("/books", new BookSaveOperation(LocalDate.now(), "Java 9 Recipes", "Josh", "Juneau", new Long(600)));response = client.toBlocking().exchange(request);id = entityId(response, "/books/");assertEquals(HttpStatus.CREATED, response.getStatus());}@Testpublic void testBookRetrieve() {request = HttpRequest.GET("/books");List<Book> books = client.toBlocking().retrieve(request, Argument.of(List.class, Book.class));// Populate a book instance for laterfor(Book b:books){book = b;}assertEquals(2, books.size());}@Testpublic void testBookOperations() {request = HttpRequest.GET("/books");List<Book> books = client.toBlocking().retrieve(request, Argument.of(List.class, Book.class));// Populate a book instance for laterfor(Book b:books){book = b;}request = HttpRequest.PUT("/books/", new BookUpdateOperation(book.getId(),book.getPublishDate(),"Java 10 Recipes",book.getAuthorFirst(),book.getAuthorLast(),book.getPages()));response = client.toBlocking().exchange(request);assertEquals(HttpStatus.NO_CONTENT, response.getStatus());request = HttpRequest.GET("/books/" + book.getId());book = client.toBlocking().retrieve(request, Book.class);assertEquals("Java 10 Recipes", book.getTitle());testDelete();}public void testDelete(){request = HttpRequest.GET("/books");List<Book> books = client.toBlocking().retrieve(request, Argument.of(List.class, Book.class));// Populate a book instance for laterfor(Book b:books){request = HttpRequest.DELETE("/books/" + b.getId());response = client.toBlocking().exchange(request);assertEquals(HttpStatus.NO_CONTENT, response.getStatus());}}Long entityId(HttpResponse response, String path) {String value = response.header(HttpHeaders.LOCATION);if (value == null) {return null;}int index = value.indexOf(path);if (index != -1) {return Long.valueOf(value.substring(index + path.length()));}return null;}}

考試邏輯導論

在運行@BeforeClass的方法中,將創(chuàng)建HTTP服務器和客戶端。 同樣,測試完成執(zhí)行后,將調用以@AfterClass注釋的方法,如果服務器正在運行,它將停止服務器。

在textInsertBooks()方法中,通過將填充有數據的新BookSaveOperation對象傳遞給可通過@Post命名的“ / books”路徑訪問的服務,來創(chuàng)建兩個新的書記錄。 在這種情況下,將調用控制器方法BookController.save()。 看一下save()方法,您可以看到該方法只是將BookSaveOperation的內容傳遞給BookRepository.save()業(yè)務方法(利用該接口),從而持久化對象。 最后,返回HttpResponse。

testBookRetrieve()方法調用可通過包含@Get名稱的“ / books”路徑使用的服務。 依次調用BookController.list()方法,該方法在BookRepository上執(zhí)行findAll(),返回Book對象的List。

testBookOperations()方法負責對記錄進行更新。 首先,從BookController中檢索Book對象的列表,然后通過使用要更新的內容填充BookUpdateOperation對象,通過BookController.update()方法更新其中一本書。

**請記住,BookSaveOperation.java和BookUpdateOperation.java對象只是用于移動數據的POJO。

最后,調用testDelete()方法,該方法遍歷Book對象的List,通過對“ / books”路徑的服務調用來調用BookController.delete()方法,并調用指定為@Delete的方法。

要執(zhí)行測試,只需在NetBeans中右鍵單擊該項目并選擇“ Test”,或使用命令行使用以下命令來調用

./gradlew test

如果尚未創(chuàng)建數據庫表,則將為您生成該表。 請注意,您可能需要根據環(huán)境修改application.yml中的數據庫配置。

運行服務

Micronaut是獨立的,允許使用基于Netty構建的嵌入式服務器執(zhí)行服務。 可以通過右鍵單擊Apache NetBeans中的項目并選擇“運行”來完成。 您也可以轉到命令行并使用以下命令進行調用:

./gradlew run

您應該在終端或Apache NetBeans輸出面板的輸出中看到托管服務器的URL。

摘要

作為Java EE開發(fā)人員,我不得不說Micronaut確實有不同的開發(fā)方法。 它與Spring Boot或Grails并沒有太大的區(qū)別,但是又有足夠的區(qū)別,以至于我花了一些時間找到解決方法。 最后,我發(fā)現它是一個易于使用的框架,它具有快速開發(fā)服務或計劃任務的巨大潛力,同時仍然利用Java EE / Jakarta EE的一些概念。

我還沒有使用很多功能,例如通過Micronaut框架創(chuàng)建計劃任務,以及使用Groovy或Kotlin而不是Java進行開發(fā)。 我希望在以后的文章中繼續(xù)介紹有關Java EE和Jakarta EE開發(fā)人員的更多信息,他們有興趣開始使用Micronaut。

GitHub項目:https://github.com/juneau001/micronaut-books

翻譯自: https://www.javacodegeeks.com/2018/09/micronaut-for-java-ee-jakarta-ee-developers.html

jakarta ee

總結

以上是生活随笔為你收集整理的jakarta ee_适用于Java EE / Jakarta EE开发人员的Micronaut的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 手机看片国产 | 亚洲免费成人在线 | 久久久午夜视频 | 激情久久综合 | xxxx久久| 黄色第一网站 | 66亚洲一卡2卡新区成片发布 | av电影在线观看不卡 | a√在线| 啪视频免费 | 影音先锋国产 | 日本黄网站在线观看 | 亚洲1区 | 国产精品无码在线播放 | 狠狠操欧美 | 亚洲国产电影在线观看 | 日本在线一 | 农村脱精光一级 | 在线免费观看亚洲 | 亚洲国产成人va在线观看天堂 | 久久在线免费 | 91中文字幕在线观看 | 神马午夜91| 99视频免费在线观看 | 最新黄网 | 警察高h荡肉呻吟男男 | 午夜国产福利 | 国产精品乱子伦 | 碧蓝之海动漫在线观看免费高清 | 天天躁夜夜躁 | 一本色道久久88 | 久草超碰在线 | 中文字幕伊人 | 中文字幕手机在线视频 | 另类一区 | 国产第20页| 91叼嘿视频| 日韩免费毛片 | 日韩天堂网| 少妇h视频 | 久久久久久一级片 | 九九热九九热 | 综合久久久久综合 | wwww日本60| 17c国产精品| 亚洲色图欧美视频 | 7799精品视频天天看 | 成年人av在线 | 日本免费一区二区三区视频 | 涩天堂 | 色综合色综合 | 日韩性大片| 国产色黄 | 黄色国产一级片 | 国产精品久久毛片 | 香蕉久久精品 | 国产一区二区三区在线 | 亚洲成人精品在线观看 | 逼逼av网站| 91成人短视频在线观看 | 黄色一级大片在线免费看国产一 | 亚洲乱码国产乱码精品精 | 91久久精品国产91久久性色tv | 在线涩涩| youjizz国产精品 | 黄色一级影片 | 德国经典free性复古xxxx | 久久久精品国产免费爽爽爽 | 国产精品xxx| 中文字幕av在线免费观看 | 91精品国产综合久久久蜜臀粉嫩 | 黄色网址进入 | 精品国产a | 欧美午夜精品一区二区蜜桃 | av片在线看 | 天天操中文字幕 | 国产91美女视频 | 久草精品视频 | 亚洲第一页色 | 少妇把腿扒开让我舔18 | 波多野结衣影片 | 99热这里只有精品久久 | 日本欧美在线播放 | 天天想你在线观看完整版电影高清 | 日韩欧美亚洲一区 | 久久午夜无码鲁丝片午夜精品 | 99热在线国产 | 欧美性色黄大片手机版 | 久久久999久久久 | 精品日本视频 | 国产欧美日韩一区 | 中文字幕乱码中文字幕 | 亚洲免费综合 | 日本三级免费 | 一本大道东京热无码 | 国产精品一区二区毛片 | 国产a级大片 | 国产偷亚洲偷欧美偷精品 | 欧美性受xxxx黑人xyx性 |