使用Java和JSF构建一个简单的CRUD应用

使用Okta的身份管理平台轻松部署您的应用程序 使用Okta的API在几分钟之内即可对任何应用程序中的用户进行身份验证,管理和保护。 今天尝试Okta。

JavaServer Faces(JSF)是用于构建Web应用程序的Java框架,其中心是作为用户界面构建块的组件。 JSF受益于丰富的工具和供应商生态系统,以及开箱即用的组件和库,它们增加了更多的功能。

为什么使用JSF代替JavaServer Pages(JSP)? 主要有两个原因:首先,JSF具有更多的模板功能,因为它遇到标签时不会直接编写视图。 相反,您可以将视图构建为XML,然后可以对其进行预处理,然后再将其输出为HTML。 这意味着您可以随着应用程序的增长重新使用并更好地组织代码。 其次,JSF为您提供了完整的MVC架构,而JSP只是一种脚本语言,它抽象了手工编写Servlet的过程。

在此背景下,让我们创建一个简单的应用程序,以展示JSF的强大功能。 在本教程中,我们将构建一个简单的Web应用程序,以管理由数据库支持的您喜欢的书籍的列表,并使用Okta安全地访问您的应用程序。

使用JSF创建CRUD应用程序

首先,我们将使用TomEE Maven原型生成项目:

$ mvn archetype:generate \-DarchetypeGroupId=org.apache.openejb.maven \-DarchetypeArtifactId=tomee-webapp-archetype \-DarchetypeVersion=1.7.1

遵循交互式生成过程,使用以下参数生成应用程序:

Define value for property 'groupId': com.okta.developer
Define value for property 'artifactId': jsf-crud
Define value for property 'version' 1.0-SNAPSHOT: : 1.0-SNAPSHOT
Define value for property 'package' com.okta.developer: : com.okta.developer
Confirm properties configuration:
groupId: com.okta.developer
artifactId: jsf-crud
version: 1.0-SNAPSHOT
package: com.okta.developer
Y: : Y

然后cd转化项目,构建和运行,看到它在行动:

$ cd jsf-crud # or the artifactId you used to generate the project
$ mvn package
$ mvn tomee:run

在您的JSF应用程序中创建一本书

现在,将您的首选浏览器指向http://localhost:8080/ 。 您应该看到用于创建书籍的表单。

要添加书籍,只需输入书名,然后点击添加即可 。 您将进入成功页面,并能够查看数据库中的书籍列表。 此表单页面由src/main/webapp/book.xhtml生成,结果页面由src/main/webapp/result.xhtml

book.xhtml是一个简单的表单,将其字段连接到com.okta.developer.presentation.BookBean类。 例如:

<h:inputText value='#{bookBean.bookTitle}'/>

对于操作,例如提交表单,我们直接绑定到“ bean”类中的方法。 该特定形式将触发类中的add()方法:

<h:commandButton action="#{bookBean.add}" value="Add"/>

BookBean.add()方法创建一个新的Book实例,并将其标题设置为我们存储在bookTitle字段中的bookTitle (请记住,它已绑定到表单的输入字段):

public String add() {Book book = new Book();book.setBookTitle(bookTitle);bookService.addBook(book);return "success";
}

然后,它要求bookService将图书持久bookService到数据库中,就像我们在com.okta.developer.application.BookService类中看到的com.okta.developer.application.BookService

public void addBook(Book book) {entityManager.persist(book);
}

但是返回的"success"字符串呢? 它在文件src/main/webapp/WEB-INF/faces-config.xml

<navigation-rule><from-view-id>/book.xhtml</from-view-id><navigation-case><from-outcome>success</from-outcome><to-view-id>/result.xhtml</to-view-id></navigation-case>
</navigation-rule>

这意味着当/book.xhtml文件success时,JSF会将用户发送到视图/result.xhtml 。 在result.xhtml文件中,我们还看到一个绑定到Bean中的方法的按钮:

<h:commandButton action="#{bookBean.fetchBooks}" value="View books present"/>

这将执行类中的方法fetchBooks() 。 在src/main/java/com/okta/developer/presentation/BookBean.java文件中,我们看到fetchBooks()委托给bookService的方法,该方法将结果存储到booksAvailable字段中,然后返回字符串“ success” 。

public String fetchBooks() {booksAvailable=bookService.getAllBooks();return "success";
}

阅读您的JSF应用程序中的书

getAllBooks()方法中, com.okta.developer.application.BookService类查询数据库,以获取所有不带过滤器的Book实例:

public List<Book> getAllBooks() {CriteriaQuery<Book> cq = entityManager.getCriteriaBuilder().createQuery(Book.class);cq.select(cq.from(Book.class));return entityManager.createQuery(cq).getResultList();
}

凉。 但是页面实际上如何显示图书信息? 在result.xhtml文件中,找到ui:repeat标签:

<ui:repeat value="#{bookBean.booksAvailable}" var="book">#{book.bookTitle} <br/>
</ui:repeat>

<ui:repeat>标记迭代每个value ,在这种情况下, #{bookBean.booksAvailable}是我们刚刚从fetchBooks()方法分配的字段。 集合的每个元素都可以通过标签的var属性中的名称来引用(在本例中为book )。

<ui:repeat>标记内的所有内容都将对集合中的每个元素重复。 在这里,它只使用插值符号#{book.bookTitle}和换行符( <br/> )输出书名。

我们只介绍了CRUD应用程序的C reate和R ead方法。 太棒了! 现在让我们尝试与U PDATE一本书。

更新记录

src/main/webapp文件夹中创建一个edit.xhtml文件,以包含用于更新数据库中Book的表单。 它看起来与“创建”表单非常相似:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"xmlns:f="http://java.sun.com/jsf/core"xmlns:h="http://java.sun.com/jsf/html"><h:body bgcolor="white"><f:view><h1>Update book</h1><h:form><h:panelGrid columns="2"><h:outputText value='Enter book title'/><h:inputText value='#{bookBean.bookTitle}'/><h:outputText value='Update'/><h:commandButton action="#{bookBean.update}" value="Update"/></h:panelGrid><input type="hidden" name="bookId" value='#{param.bookId}'/></h:form></f:view>
</h:body>
</html>

现在,通过更改<ui:repeat>标记的内容,从文件src/main/webapp/result.xhtml的书籍列表中添加指向此页面的链接:

<ui:repeat value="#{bookBean.booksAvailable}" var="book"><h:link value="#{book.bookTitle}" outcome="edit"><f:param name="bookId" value="#{book.bookId}"/></h:link><br/>
</ui:repeat>

现在,列表中的每本书都是该书编辑页面的链接。

但是,如果您尝试单击该链接,则会看到该表单在页面加载时显示为空。 让我们解决这个问题,并在表单呈现之前加载书名。 要从我们的bean中的URL获取bookId ,请在pom.xml文件中包括以下依赖项:

<dependencies>...<dependency><groupId>javax</groupId><artifactId>javaee-web-api</artifactId><version>6.0</version><scope>provided</scope></dependency>...
</dependencies>

编辑src/main/java/com/okta/developer/application/BookService.java文件,并将以下方法添加到BookService类以从数据库中加载书籍:

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Root;...public Book getBook(Integer bookId) {CriteriaBuilder cb = entityManager.getCriteriaBuilder();CriteriaQuery<Book> cq = cb.createQuery(Book.class);Root<Book> book = cq.from(Book.class);cq.select(book);cq.where(cb.equal(book.get("bookId"), bookId));return entityManager.createQuery(cq).getSingleResult();
}

并将以下逻辑添加到BookBean以在页面渲染之前加载书籍:

import javax.annotation.PostConstruct;
import javax.faces.context.FacesContext;...private Integer bookId;
private Book book;@PostConstruct
public void postConstruct() {String bookIdParam = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("bookId");if (bookIdParam != null) {bookId = Integer.parseInt(bookIdParam);book = bookService.getBook(bookId);bookTitle = book.getBookTitle();}
}

现在,让我们创建一个将更改保存到数据库的方法,在BookService类中使用以下方法:

public void update(Book book) {entityManager.merge(book);
}

另外,将update方法添加到BookBean类中:

public String update() {book.setBookTitle(bookTitle);bookService.update(book);return "success";
}

为了正确地将用户重定向到列表页面,请将以下导航规则添加到文件src/main/webapp/faces-config.xml

<navigation-rule><from-view-id>/edit.xhtml</from-view-id><navigation-case><from-outcome>success</from-outcome><to-view-id>/result.xhtml</to-view-id></navigation-case>
</navigation-rule>

现在我们已经完成了书的更新,让我们继续进行“删除”部分。

删除记录

上一节介绍了最困难的部分-在bean中装入一本书。 添加删除按钮将更加容易。

将列表中每个条目的删除链接添加到文件src/main/webapp/result.xhtml的编辑页面:

<ui:repeat value="#{bookBean.booksAvailable}" var="book"><h:link value="#{book.bookTitle}" outcome="edit"><f:param name="bookId" value="#{book.bookId}"/></h:link><!-- Delete link: --><h:outputText value=" ("/><h:link value="Delete" outcome="delete"><f:param name="bookId" value="#{book.bookId}"/></h:link><h:outputText value=")"/><br/>
</ui:repeat>

现在,在src/main/webapp/delete.xhtml创建删除确认页面:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"xmlns:f="http://java.sun.com/jsf/core"xmlns:h="http://java.sun.com/jsf/html"><h:body bgcolor="white"><f:view><h1>Delete book?</h1><h:form><h:panelGrid columns="2"><h:outputText value='Book title'/><h:inputText value='#{bookBean.bookTitle}' readonly="true"/><h:outputText value='Delete'/><h:commandButton action="#{bookBean.delete}" value="Confirm Delete"/></h:panelGrid><input type="hidden" name="bookId" value='#{param.bookId}'/></h:form></f:view>
</h:body>
</html>

并在BookBean类中添加适当的删除处理程序:

public String delete() {bookService.delete(book);return "success";
}

接下来,在BookService类中处理删除:

import javax.persistence.Query;...public void delete(Book book) {Query query = entityManager.createQuery("DELETE FROM Book b WHERE b.bookId = :bookId");query.setParameter("bookId", book.getBookId());query.executeUpdate();
}

并且不要忘记在删除后通过将以下内容添加到src/main/webapp/faces-config.xml将您的用户重定向回列表:

<navigation-rule><from-view-id>/delete.xhtml</from-view-id><navigation-case><from-outcome>success</from-outcome><to-view-id>/result.xhtml</to-view-id></navigation-case>
</navigation-rule>

做完了! 我告诉你删除会更容易。

所以,现在我们可以在c reate,U PDATE,R EAD和d elete我们的书籍的CRUD应用程序。

改善用户界面

CRUD应用程序工作正常,但该应用程序看起来不太好。 让我们通过PrimeFaces改善我们的应用程序用户界面。

首先,将其作为依赖项添加到我们的pom.xml

<dependencies>...<dependency><groupId>org.primefaces</groupId><artifactId>primefaces</artifactId><version>7.0</version></dependency>...
</dependencies>

现在,我们可以在视图中使用任何PrimeFaces组件,方法是将其命名空间声明为html标记,如下所示:

<html xmlns="http://www.w3.org/1999/xhtml"xmlns:f="http://java.sun.com/jsf/core"xmlns:h="http://java.sun.com/jsf/html"xmlns:p="http://primefaces.org/ui">

有关更深入的概述,请阅读其站点中的每个PrimeFaces组件 。

首先,让我们从BookBean类中删除图书清单,然后创建一个BookList类。 页面加载后,这将立即加载书单。 使用以下内容创建文件src/main/java/com/okta/developer/presentation/BookList.java

package com.okta.developer.presentation;import com.okta.developer.application.BookService;
import com.okta.developer.entities.Book;import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.List;@Named
public class BookList {@Injectprivate BookService bookService;private List<Book> booksAvailable;@PostConstructpublic void postConstruct() {booksAvailable = bookService.getAllBooks();}public List<Book> getBooksAvailable() {return booksAvailable;}
}

BookBean类中删除以下与booksAvailable字段相关的代码块:

private List<Book> booksAvailable;public List<Book> getBooksAvailable() {return booksAvailable;
}public void setBooksAvailable(List<Book> booksAvailable) {this.booksAvailable = booksAvailable;
}public String fetchBooks() {booksAvailable=bookService.getAllBooks();return "success";
}

我们还要更改目标网页。 让我们提供书单,而不是通过表单添加一本书。 为此,编辑index.jsp以将重定向更改为result.jsf

<%@ page session="false" %>
<%response.sendRedirect("result.jsf");
%>

这是我的文件现在的样子。 浏览PrimeFaces组件库时 ,请随时进行调整。

文件: src/main/webapp/book.xhtml使用p:panelp:panelGrid

<?xml version="1.0" encoding="UTF-8"?>
<!-- File: book.xhtml -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"xmlns:h="http://java.sun.com/jsf/html"xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body><h:form><p:panel header="Create Book"><p:panelGrid columns="1" layout="grid"><p:outputLabel for="book-title" value="Enter book title"/><p:inputText id="book-title" value='#{bookBean.bookTitle}'/><p:commandButton value="Create" action="#{bookBean.add}" ajax="false"/></p:panelGrid><!-- We will use this later<input type="hidden" value="${_csrf.token}" name="${_csrf.parameterName}"/>--></p:panel></h:form>
</h:body>
</html>

文件: src/main/webapp/delete.xhtml使用p:panelp:panelGrid

<?xml version="1.0" encoding="UTF-8"?>
<!-- File: delete.xhtml -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"xmlns:h="http://java.sun.com/jsf/html"xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body><h:form><p:panel header="Delete Book?"><p:panelGrid columns="1" layout="grid"><p:outputLabel for="book-title" value="Book title"/><p:inputText id="book-title" value='#{bookBean.bookTitle}' readonly="true"/><p:commandButton value="Confirm Delete" action="#{bookBean.delete}" ajax="false"/></p:panelGrid><input type="hidden" name="bookId" value='#{param.bookId}'/><!-- We will use this later<input type="hidden" value="${_csrf.token}" name="${_csrf.parameterName}"/>--></p:panel></h:form>
</h:body>
</html>

文件: src/main/webapp/edit.xhtml使用p:panelp:panelGrid

<?xml version="1.0" encoding="UTF-8"?>
<!-- File: edit.xhtml -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"xmlns:h="http://java.sun.com/jsf/html"xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body><h:form><p:panel header="Update Book"><p:panelGrid columns="1" layout="grid"><p:outputLabel for="book-title" value="Enter new book title"/><p:inputText id="book-title" value='#{bookBean.bookTitle}'/><p:commandButton value="Update" action="#{bookBean.update}" ajax="false"/></p:panelGrid><input type="hidden" name="bookId" value='#{param.bookId}'/><!-- We will use this later<input type="hidden" value="${_csrf.token}" name="${_csrf.parameterName}"/>--></p:panel></h:form>
</h:body>
</html>

文件: src/main/webapp/result.xhtml使用p:dataList而不是ui:repeat

<?xml version="1.0" encoding="UTF-8"?>
<!-- File: result.xhtml -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"xmlns:f="http://java.sun.com/jsf/core"xmlns:h="http://java.sun.com/jsf/html"xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body><h:link outcome="book" value="Create Book"/><p:dataList value="#{bookList.booksAvailable}" var="book" type="ordered"><f:facet name="header">Book List</f:facet>#{book.bookTitle}<h:outputText value=" ("/><p:link value="Edit" outcome="edit"><f:param name="bookId" value="#{book.bookId}"/></p:link><h:outputText value=" | "/><p:link value="Delete" outcome="delete"><f:param name="bookId" value="#{book.bookId}"/></p:link><h:outputText value=")"/></p:dataList>
</h:body>
</html>

在启用PrimeFaces的情况下运行应用程序

使用mvn package tomee:run重新启动应用程序。 该应用现在看起来会更好一些! 查看书籍清单:

使用Okta保护您的应用程序

目前,任何人都可以访问我们出色的Book应用程序并更改数据库。 为避免这种情况,让我们使用Spring Security库在应用程序中添加一个安全层,并通过Okta对用户进行身份验证。

首先,立即注册一个永久免费的开发者帐户! 完成后,请完成以下步骤以创建OIDC应用程序。

  1. 登录到您的开发者帐户在developer.okta.com
  2. 导航到应用程序 ,然后单击添加应用程序
  3. 选择网站 ,然后单击下一步。
  4. 为应用程序命名(例如Java JSF Secure CRUD
  5. 添加以下内容作为“登录”重定向URI:
    • http://localhost:8080/login/oauth2/code/okta
  6. 点击完成

现在,使用您的Client IDClient Secret创建文件src/main/resources/application.properties ,您可以在刚创建的应用程序的General选项卡上找到它们。

okta.client-id={clientId}
okta.client-secret={clientSecret}
okta.issuer-uri=https://{yourOktaDomain}/oauth2/default

让我们在您的pom.xml文件中添加Spring Security作为依赖项:

<properties>...<spring-security.version>5.1.6.RELEASE</spring-security.version><spring.version>5.1.6.RELEASE</spring.version>
</properties><dependencyManagement><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-framework-bom</artifactId><version>${spring.version}</version><scope>import</scope><type>pom</type></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-bom</artifactId><version>${spring-security.version}</version><scope>import</scope><type>pom</type></dependency></dependencies>
</dependencyManagement><dependencies>...<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-oauth2-client</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-oauth2-resource-server</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-oauth2-jose</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.9.9</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.9.3</version></dependency>
</dependencies>

为了让Spring Security正确地控制您的应用程序安全,它需要知道哪些请求需要身份验证。 为此,我们将创建文件src/main/java/com/okta/developer/SecurityConfiguration.java来告诉Spring Security保护所有URL并使用CSRF令牌保护表单:

public SecurityConfiguration(@Value("${okta.issuer-uri}") String issuerUri,@Value("${okta.client-id}") String clientId,@Value("${okta.client-secret}") String clientSecret) {this.issuerUri = issuerUri;this.clientId = clientId;this.clientSecret = clientSecret;}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.sessionManagement() // Always create a session.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)

接下来,创建文件src/main/java/com/okta/developer/SecurityWebApplicationInitializer.java类以在应用程序中启用Spring Security:

package com.okta.developer;import org.springframework.security.web.context.*;public class SecurityWebApplicationInitializerextends AbstractSecurityWebApplicationInitializer {public SecurityWebApplicationInitializer() {super(SecurityConfiguration.class);}
}

由于已启用CSRF保护,因此需要将令牌添加到每个<h:form>标签。 只需在表单中添加该行(我在使用PrimeFaces的文件中将那些注释掉了):

<input type="hidden" value="${_csrf.token}" name="${_csrf.parameterName}"/>

做完了! 转到http://localhost:8080 ,您将被重定向到Okta登录表单,并且仅在成功通过身份验证后才能使用该应用程序。

想要与朋友分享应用程序? 太酷了,转到Okta开发人员控制台页面,转到“ 用户”并为其创建一个帐户。 现在,您还具有功能齐全的安全管理工具,您可以在其中启用/禁用用户,检查用户何时登录到您的应用程序,重置其密码等。

享受您的全新安全书本应用程序吧!

了解有关Java,JSF和用户身份验证的更多信息!

如果您想使用Okta学习有关Java,JSF和用户身份验证的更多信息,我们还有其他很棒的文章供您继续阅读:

  • 使用Java EE和OIDC构建Java REST API
  • 您应该使用哪个Java SDK?
  • 教程:用Java创建和验证JWT
  • 以第一语言学习Java

有什么问题吗 要求未来的职位? 将它们放入评论中! 并且不要忘记在Twitter上关注@oktadev并在Youtube 上进行订阅 。

该应用程序的完整源代码可在GitHub上找到: oktadeveloper / okta-java-jsf-crud-example 。

使用Okta的身份管理平台轻松部署您的应用程序 使用Okta的API在几分钟之内即可对任何应用程序中的用户进行身份验证,管理和保护。 今天尝试Okta。


翻译自: https://www.javacodegeeks.com/2019/11/build-a-simple-crud-app-with-java-and-jsf.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/340360.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ftp 传输速度_ftp上传工具下载,8款优秀的ftp上传工具下载软件

FTP上传工具现在有很多种&#xff0c;而且各有各的特点&#xff0c;至于FTP上传工具哪个好用呢&#xff1f;小编认为萝卜白菜各有所爱&#xff0c;看个人喜好&#xff0c;还结合服务器和各种功能方面的需求。小编用的就是iis7服务器管理工具&#xff0c;比较方便而且功能不错&a…

c语言实践教程实验题答案,C语言课后实验教程习题答案

第5章以后的答案第五章答案-1-1. 【答案】&#xff1a; (1) m1 n2 (2) m2 n3 (3) a>0 并且a2. 【答案】&#xff1a;(2)for (i0;i<10;i) {……} 3. 【答案】&#xff1a;32 4. 【答案】&#xff1a; main() {char x ;int y;printf("please input :");scanf(&qu…

t分布 u分布 卡方分布_中心极限定理|z分布|t分布|卡方分布

生物统计学抽样分布&#xff1a;n个样本会得到n个统计量&#xff0c;将这n个统计量作为总体&#xff0c;该总体的分布即是抽样分布根据辛钦大数定律&#xff0c;从一个非正态分布的总体中抽取的含量主n的样本&#xff0c;当n充分大时&#xff0c;样本平均数渐近服从正态分布。因…

java ee打印功能_Java EE:异步构造和功能

java ee打印功能介绍 Java EE具有许多API和构造以支持异步执行。 从可伸缩性和性能的角度来看&#xff0c;这是至关重要的。 让我们假设2个模块相互交互。 当模块A &#xff08;发送方&#xff09;以同步方式向模块B &#xff08;接收方&#xff09;发送消息时&#xff0c;通信…

驱动备份工具哪个好_大庆seo排名优化推广公司工具哪个好

工具哪个好g81915seo排名优化推广公司大庆,网站成立时&#xff0c;搜索引擎比较完善&#xff0c;基本上不需要长期优化。然而&#xff0c;近年来&#xff0c;搜索引擎优化的频率开始增加&#xff0c;这让人们有点好奇。搜索引擎优化的目的是什么&#xff1f;为什么会受到企业的…

c语言动画原理,动画详解十大经典排序算法(C语言版)

排序算法是程序员必备的基础知识&#xff0c;弄明白它们的原理和实现很有必要。本文中将通过非常细节的动画展示出算法的原理&#xff0c;配合代码更容易理解。概述由于待排序的元素数量不同&#xff0c;使得排序过程中涉及的存储器不同&#xff0c;可将排序方法分为两类&#…

rust如何改睡袋_腐蚀rust怎么做睡袋 | 手游网游页游攻略大全

发布时间&#xff1a;2016-05-07腐蚀是一款FPS僵尸类生存游戏,这款游戏中玩家可以体验到非常自由的游戏方式,玩家需要寻找生存的资源,同时也需要及时预防僵尸和其他不怀还以的玩家的入侵,下面是新手全面攻略分享. 新手全面攻略玩法详解 [Rust游戏介绍] ...标签&#xff1a;游戏…

测量时间:从Java到内核再到

问题陈述 当您深入研究时&#xff0c;即使是最基本的问题也会变得很有趣。 今天&#xff0c;我想深入研究一下Java时间。 我们将从Java API的最基础知识开始&#xff0c;然后逐步降低堆栈&#xff1a;通过OpenJDK源代码glibc一直到Linux内核。 我们将研究各种环境下的性能开销&…

小程序 const moment = require('moment')_C++大作业-XXX管理程序

理工科大一往往会学习C/C&#xff0c;期末会有大作业。这篇文章就是一个简单的C大作业程序。我也是大一&#xff0c;所以觉着哪里写得不好欢迎在评论区提出。程序总体上讲是个“总分总”结构。一 实现这个程序要八步。第一步 程序的功能设计程序的目标有两个。一是辅助我备考四…

c语言osversioninfoex,xi52qian

头文件 一. 对终端的操作相关头文件#include 1. 输入istream2. 输出ostream3. iostream继承istream和ostream 所以它具有输入输出功能。为了方便这个库定义了下列三个标准流对象&#xff1a;1. cin 代表标准输入istream类对象一般地cin使我们能够从用户终端读入数据。2. cout …

go hive skynet_云风的skynet在国内外来看究竟算什么水平?可以一统国内游戏服务端框架吗?...

它和云风过往放出来的东西一样&#xff0c;是非常具有实践性的&#xff0c;可以解决实际开发问题的。目前我所在的手游项目使用 Erlang 进行服务器端开发的&#xff0c;如果重新开始&#xff0c;我会选择使用 skynet。游戏服务器开发中的难点&#xff0c;上面 无瞳已经提到了两…

数据库 测试数据生成_测试数据生成器和对象母亲:另一种外观

数据库 测试数据生成在测试中构造对象通常是一项艰巨的工作&#xff0c;通常会产生大量可重复且难以阅读的代码。 有两种用于处理复杂测试数据的常见解决方案&#xff1a; Object Mother和Test Data Builder 。 两者都有优点和缺点&#xff0c;但是&#xff08;巧妙地&#xff…

电脑机器人_视频|电话积分换平板电脑和扫地机器人?女子拿回家后……-

报警人小王(左二)讲述事情经过。沙坪坝警方供图 华龙网-新重庆客户端 发华龙网-新重庆客户端11月9日11时讯(记者 张勇)“警察叔叔&#xff0c;这个店好坑人哦&#xff0c;我好气愤&#xff01;”11月6日11时许&#xff0c;重庆市沙坪坝区一名年轻女子拨打110报警电话称&#xf…

位置环PID模糊C语言,PID和位置环

EDA365欢迎您登录&#xff01;您需要 登录 才可以下载或查看&#xff0c;没有帐号&#xff1f;注册x所谓PID 自动控制&#xff0c;是对一个确定系统的- -个过程量的自动调节过程:* q* }3 B" * V P# H1)举例说&#xff0c;直流电机的速度&#xff0c;就是-一个过程量&#…

seata xid是什么_阿里开源的分布式事务框架 Seata

1. Seata 概述Seata 是 Simple Extensible Autonomous Transaction Architecture 的简写&#xff0c;由 feascar 改名而来。Seata 是阿里开源的分布式事务框架&#xff0c;属于二阶段提交模式。目前github上已经有 12267 颗星了&#xff0c;也很活跃&#xff0c;最新的提交时间…

python输入print跳到documentation-习题 48: 更复杂的用户输入

习题 48: 更复杂的用户输入 你的游戏可能一路跑得很爽&#xff0c;不过你处理用户输入的方式肯定让你不胜其烦了。每一个房间都需要一套自己的语句&#xff0c;而且只有用户完全输入正确后才能执行。你需要一个设备&#xff0c;它可以允许用户以各种方式输入语汇。例如下面的机…

有关有效企业测试的视频课程

我已经制作了一些有关有效企业测试的视频。 我仍然在现实世界项目中看到这个主题的巨大重要性。 这是我在测试Enterprise Java项目中的经验以及一些示例。 1.介绍和有效的Maven使用 在此视频中&#xff0c;我将介绍测试过程&#xff0c;并演示如何使用Maven在标准企业项目中构…

android自定义弹出对话框,使用FlyDialog实现自定义Android弹窗对话框

前言学习的时候要用到弹窗&#xff0c;但是又觉得i同自带的弹窗样式有点不太美观&#xff0c;搜索资料后发现了FlycoDialog这个开源库,效果很好&#xff0c;而且实现起来也比较方便。先列举一些比较好看的效果:NormalListDialogActionSheetDialog这篇文章主要来讲一下他的自定义…

nacos 本地测试_Nacos集群配置实例(windows下测试)

1、首先 fork 一份 nacos 的代码到自己的 github 库&#xff0c;然后把代码 clone 到本地。git地址&#xff1a;https://github.com/alibaba/nacos.git2、然后将你的项目导入到ideal编辑器中(找到子项目distribution)3、添加集群节点&#xff1a;找到文件distribution->conf…

Android手机如何修改Mac地址,安卓手机怎么修改mac地址

有些时候我们如果绑定了某个mac&#xff0c;那么其他用mac就无法上网&#xff0c;应该怎么修改呢?学习啦小编从网上搜集整理了3种修改安卓手机mac 地址的方法。修改安卓手机mac 地址的方法修改安卓手机mac 地址的方法第一种&#xff1a;软件法下面介绍一款软件 叫物理地址修改…