在15分钟内使用Spring Boot和Spring Security构建一个Web应用程序

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。

开发人员知道保护Web应用程序安全可能会很麻烦。 正确地做是很难的。 最糟糕的是,“正确”是一个移动的目标。 安全协议会更改。 在依赖项中发现漏洞,并发布了补丁程序。 必须生成大量通常很复杂的样板代码。 在过去的十年中,软件即服务的范式已经泛滥成灾,尽管我喜欢和下一个开发人员一样重新发明轮子(因为显然,我会比他们雇用的yahoo更好地编写它),但是安全是一个领域在这里,我很乐意将这项工作分担给专家。 输入Okta。

在本教程中,您将使用Spring Boot来构建带有用户注册系统和登录系统的简单Web应用程序。 它具有以下功能:

  • 登录和注册页面
  • 密码重置工作流程
  • 根据组成员身份限制访问

下载Spring Boot Web App示例项目

您首先需要的是免费的Okta帐户。 如果您还没有,请前往developer.okta.com并注册!

下一步是从GitHub下载本教程的示例项目。

git clone https://github.com/oktadeveloper/okta-spring-simple-app-example.git spring-app

该项目使用Gradle作为构建工具以及Thymeleaf模板系统。

运行初始Web应用

从GitHub存储库下载示例代码后,使用以下git命令git checkout tags/Start Start标记: git checkout tags/Start

目前,该应用程序尚未受到任何保护。 没有启用任何授权或身份验证(即使build.gradle文件中包含必需的依赖build.gradle )。 继续并运行示例,方法是打开一个终端,然后从项目根目录运行命令./gradlew bootRunbootRun命令是Gradle Spring Boot插件提供的任务,已添加到build.gradle中的build.gradle文件中。部分)。

在您喜欢的浏览器中导航到http://localhost:8080 ,您应该看到以下内容:

网络应用

如果您点击“受限”按钮:

网络应用

为您的Spring Boot + Spring Security Web App添加项目依赖项

项目依赖关系在build.gradle文件中定义(请参见下文)。 这个文件中有很多事情要做,本教程不会尝试向您解释Gradle构建系统。 随时检查他们的文档 。 我只想指出几件事。

首先,请注意,我们包括了okta-spring-boot-starter 。 该项目大大简化了Okta与Spring Boot应用程序的集成。 如果没有此启动程序,完全可以使用Okta和Spring Boot。 实际上,直到引入“组”和“角色”为止,两者之间的差异很小(主要涉及application.yml更改)。 但是,一旦开始尝试集成组和角色,Okta Spring Boot Starter会节省大量代码。 如果您想更深入一点,请看一下Okta Spring Boot Starter GitHub项目 。

其余的依赖关系涉及Spring和Spring Boot。 您会注意到org.springframework.boot依赖项都没有版本号。 这是因为Spring io.spring.dependency-management Gradle插件完成了一些幕后魔术。 Spring Boot版本由build.gradle文件顶部附近的构建脚本属性springBootVersion设置。 基于此版本号,Spring依赖性管理插件决定要包括的依赖性版本。

我们还引入了org.springframework.boot Gradle插件,该插件添加了我们将用于运行应用程序的bootRun任务。

  • spring-boot-starter-securityspring-boot-starter-web是Spring Boot的核心依赖项。
  • 必须使用spring-security-oauth2-autoconfigure才能使用@EnableOAuth2Sso批注,该批注用于将OAuth和Single Sign-On挂接到我们的应用程序中。
  • spring-boot-starter-thymeleafthymeleaf-extras-springsecurity4引入了Thymeleaf模板系统,并将其与Spring Security集成。
buildscript {  ext {  springBootVersion = '2.0.5.RELEASE'  }  repositories {  mavenCentral()  }  dependencies {  classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")  }  
}  apply plugin: 'java'  
apply plugin: 'eclipse'  
apply plugin: 'org.springframework.boot'  
apply plugin: 'io.spring.dependency-management'  group = 'com.okta.springboot'  
version = '0.0.1-SNAPSHOT'  
sourceCompatibility = 1.8  repositories {  mavenCentral()  
}  dependencies {  compile('com.okta.spring:okta-spring-boot-starter:0.6.0')  compile('org.springframework.boot:spring-boot-starter-security')  compile('org.springframework.boot:spring-boot-starter-web')  compile('org.springframework.boot:spring-boot-starter-thymeleaf')  compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity4')  compile('org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.5.RELEASE')  testCompile('org.springframework.boot:spring-boot-starter-test')  "testCompile('org.springframework.security:spring-security-test')  
}  /*  This is required to resolve a logging dependency conflict between the okta-spring-boot-starter and the various spring dependencies. */
configurations.all {  exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'  exclude group: 'org.springframework.boot', module: 'logback-classic'  
}

了解您的Spring Boot应用程序

Java Web应用程序只有三个类文件和几个模板。 显然,Spring Boot在后台进行了大量繁重的工作,但是我们的类文件中发生了什么?

应用程序入口点在SpringSimpleApplication类中:

@SpringBootApplication  
public class SpringSimpleApplication {  public static void main(String[] args) {  SpringApplication.run(SpringSimpleApplication.class, args);  }  
}

这里发生了两个重要的事情,这些事情使事情发生了变化:1)我们使用@SpringBootApplication批注,以及2)我们的main方法调用SpringApplication.run()方法。 这是整个Spring / Spring Boot系统的入口。

SpringSecurityWebAppConfig类是一种使用Java代码配置Spring Boot处理Web应用程序安全性的方式。 在这里,我们使用HttpSecurity对象从所有端点中删除授权。 默认情况下,Spring Boot的行为是相反的:所有端点都需要授权。

@Configuration  
public class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter {  @Override  protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().permitAll();          }
}

@Configuration注释告诉Spring我们正在使用该类作为编程配置的源,从而允许我们重写configure()方法。

最后一个Java类SimpleAppController是我们唯一的控制器对象。 Spring Boot Web应用程序中的控制器是URL请求映射到Java代码的地方。 @Controller注释告诉Spring此类是一个控制器。

@Controller  
class SimpleAppController {  @RequestMapping("/")  String home() {  return "home";  }  @RequestMapping("/restricted")  String restricted() {  return "restricted";  }  }

使用@RequestMapping批注在类方法和URL之间建立连接。

我们有两个映射:

  1. “家庭”映射
  2. “受限”映射

请记住,一开始实际上没有任何“限制”,所以不要为此感到困惑。 您将锁定该映射一点。

还要注意,这些类返回一个简单的文本字符串,但这会自动变成完整的html文件。 这是build.gradle文件中包含的Thymeleaf依赖项的一部分。 这些字符串被假定为模板文件名,默认情况下是类路径上templates目录中的路径。

因此,“ home”被映射到src/main/resources/templates/home.html模板文件。 当将Web应用程序打包到最终的jar中时,会将整个资源文件夹复制到类路径中,以便可以在运行时访问templates目录。

为OAuth 2.0单一登录设置Okta

现在,您将为我们的应用设置授权。 Okta使这个超级容易。 您应该已经注册了一个免费的developer.okta.com帐户。 现在,您将创建一个OpenID Connect(OIDC)应用程序,以与OAuth 2.0单一登录(SSO)一起使用。

如果您还不熟悉它们的话,可能会有很多术语和缩写。 很简单, OAuth 2.0是授权的行业标准-一种标准化且经过测试的方法,授权服务器和应用程序可以通过该方法进行通信以促进用户授权。 OpenID Connect是OAuth 2.0之上的一层,用于标准化和简化授权过程以及提供用户验证。 它们一起为应用程序与提供身份验证和授权服务的远程服务器(例如Okta)进行交互提供了一种行之有效的方法。

要创建OIDC应用,请打开Okta开发人员信息中心。 单击“ 应用程序”顶部菜单项,然后单击“ 添加应用程序”

您应该看到以下屏幕。 单击“ Web”选项的图标。 单击下一步

网络应用

您需要更新一些初始配置选项。 首先将名称更改为更具描述性的名称。 我使用了“ Okta Spring Boot简单Web应用程序”。 接下来,将登录重定向URI更新为http://localhost:8080/login 。 单击完成

网络应用

这将带您进入新应用程序的常规配置选项卡。 向下滚动并记下客户端ID和客户端密码。 稍后您将需要这些。

网络应用

这就是为Okat设置Okta所需要做的一切! 现在,让我们返回Spring Boot应用程序,并将新的OIDC应用程序挂接到Spring Boot应用程序中。

为单点登录(SSO)配置Spring Boot应用

现在,您需要配置Spring Boot应用程序以与Okta服务器进行交互。 这非常容易。 我们需要做两件事:

  1. 添加@EnableOAuth2Sso批注
  2. 更新application.yml配置

首先将@EnableOAuth2Sso批注添加到SpringSecurityWebAppConfig类。

@EnableOAuth2Sso  
@Configuration  
public class WebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {  @Override  protected void configure(HttpSecurity http) throws Exception {  http.authorizeRequests().anyRequest().permitAll();          }  
}

@EnableOAuth2Sso批注会做很多事情。 值得深入了解正在发生的事情。 您可以查看有关注解本身的Spring文档 ,以及它们的Spring Boot和OAuth2教程 。

我想指出的一件事(公元前这使我烦恼了一阵子,而我只是想出了这一点)是,您可以将此注释放在项目中的其他类上。 但是,如果这样做,请注意Spring将创建一个WebSecurityConfigurerAdapter并将其添加到安全链中。 由于我们还将创建一个WebSecurityConfigurerAdapter,因此将有两个,并且您将收到有关链订单冲突的错误。 这是因为两个WebSecurityConfigurerAdapters在默认情况下将使用相同的链顺序。 您可以通过在自定义类中添加@Order(101)批注来解决此错误。 但是,更好的方法是将@EnableOAuth2Sso批注添加到我们的WebSecurityConfigurerAdapter类WebSecurityConfigurerAdapter ,Spring将使用该类而不是创建重复的类。

您需要进行的第二个更改是更新src/main/resources/application.yml文件,为来自Okta OIDC应用程序的OAuth SSO值填写一些Okta特定的配置选项。

您需要从上面创建的应用程序中填写您的客户ID和客户机密。 您还需要更改发行者URL,以使其反映您的Okta预览URL,例如dev-123456.oktapreview.com

server:  port: 8080  spring:  resources: static-locations: "classpath:/static/"  okta:  oauth2: issuer: https://{yourOktaDomain}/oauth2/default  clientId: {yourClientId}  clientSecret: {yourClientSecret}rolesClaim: groups

完善我们的权限

现在,您将要更新SpringSecurityWebAppConfig类,以便拥有一个公共主页和一个受限制的“受限制”页面。 我们通过对HttpSecurity对象使用Spring的流畅API来实现此目的。

import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@EnableOAuth2Sso  
@Configuration  
public class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter {  @Override  protected void configure(HttpSecurity http) throws Exception {  http.authorizeRequests()  .antMatchers("/").permitAll() // allow all at home page.antMatchers("/img/**").permitAll()  // allow all to access static images.anyRequest().authenticated();  // authenticate everything else!}  
}

重新启动您的应用程序,现在您应该能够:

  1. 无需认证即可查看主页
  2. 未经身份验证就无法看到/restricted页面
  3. 能够使用Okta单一登录进行身份验证

本教程中的这一点与GitHub存储库中的OktaOAuthSSO标签相对应。

看看Thymeleaf模板

总体而言,Thymeleaf模板是很容易解释的,但是我确实想指出几件事。 Thymeleaf模板是完全有效HTML5,这很好。 如果您想深入了解,可以访问他们的网站和他们的文档 。

我想指出的是模板如何引入身份验证信息。 为此,我们使用了thymeleaf-extras-springsecurity插件。 这是包含在build.gradle文件中的以下行:

compile ("org.thymeleaf.extras:thymeleaf-extras-springsecurity4")

并且作为主<html>标记上的XML名称空间属性包含在模板文件中。

xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"

这个插件使我们可以检查是否使用带有自定义SPEL表达式(Spring表达式语言)的th:if属性对用户进行了身份验证。 它还允许我们插入身份验证属性。 在下面,您将看到一个跨度<span th:text="${#authentication.name}"></span> ,该<span th:text="${#authentication.name}"></span>用于插入已验证用户的名称。

<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">  
<head>  <!--/*/ <th:block th:include="fragments/head :: head"/> /*/-->  
</head>  
<body>  
<div class="container-fluid">  <div class="row">  <div class="box col-md-6 col-md-offset-3">  <div class="okta-header">  <img src="img/logo.png"/>  </div>  <!--/* displayed if account IS NOT null, indicating that the user IS logged in */-->  <div th:if="${#authorization.expression('isAuthenticated()')}">  <h1 th:inline="text">Hello, <span th:text="${#authentication.name}"></span>!</h1>  <a href="/restricted" class="btn btn-primary">Restricted</a>  </div>  <!--/* displayed if account IS null, indicating that the user IS NOT logged in */-->  <div th:unless="${#authorization.expression('isAuthenticated()')}">  <h1>Who are you?</h1>  <a href="/restricted" class="btn btn-primary">Restricted</a>  </div>  </div>  </div>  
</div>  
</body>  
</html>

thymeleaf-extras-springsecurity插件还具有其他一些不错的功能。 如果您想更深入一点,请查看GitHub上的项目存储库 。

通过组成员身份安全访问

本教程的下一步是使用将在Okta上创建和定义的用户组添加基于组的身份验证。 一个非常常见的示例是让网站的“管理”部分和网站的“用户”部分,以及可能向所有人开放的公共主页。 在此示例中,“管理员”和“用户”将对应于两个不同的组,其中经过身份验证的用户可以是其成员。 我们要做的是能够基于用户组成员身份限制对URL端点的访问,并能够将用户分配给这些组。

旁注:小组与角色。 有什么不同?

  • “组”是用户的集合,并且权限已分配给该组。 一般来说,至少在整个会话期间,组成员资格是相对静态的。
  • “角色”是用户在该角色下执行操作时可以继承的一组权限。 角色本质上通常更具动态性。 用户可以具有许多角色。 经常根据复杂的标准激活或停用角色,并且在整个用户会话中经常可能会更改角色。

实际上,对于简单的授权系统,它们非常相似。 主要区别在于,组基于个人身份进行分类,而角色则基于允许的活动进行分类。 您可能会在狂野的互联网上看到无视这种差异的应用程序和教程,因为它们在功能上有些微妙。 (但是现在您知道了。您可以进入所涉及的教程的评论主题,并撰写评论以纠正作者。)

在Okta中配置授权组

转到您的developer.okta.com仪表板。 从顶部菜单中,转到“ 用户” ,然后单击“ 组”

网络应用

单击添加组按钮。

将组命名为“ Admin”并对其进行描述(我放了“ Administrators”,无论您在这里实际输入什么,都无所谓,只是描述性的)。

单击组名称以打开组,然后单击添加成员按钮。 将您的用户添加到Admin组。

接下来,添加一个不是管理员的新用户。

  • 从顶部菜单转到“ 用户 ”,然后单击“ 人员”
  • 单击添加人
  • 填写弹出表单:
    • 名:不

接下来您需要做的是向默认授权服务器添加一个“组”声明。

  • 从顶部菜单转到API ,然后单击“ 授权服务器
  • 单击默认授权服务器。
  • 单击“ 索赔”选项卡。
  • 点击添加声明按钮。
  • 更新弹出表单以匹配下面的图像
    • 名称:团体
网络应用

您在这里所做的就是告诉Okta在发送给您的应用程序的访问令牌中包含“组”声明。 这是Okta的OAuth方法,用于向您的应用程序告知您已通过身份验证的用户所属的组。 令人困惑的是,这些在Spring应用程序端被称为“权威”,这是OAuth服务器与应用程序通信的组/角色/特权的抽象术语。

现在我们有两个用户。 您的主要用户(已添加到Admin组中)和一个新用户(不在admin组中)。 我们还配置了Okta,将群组声明添加到访问令牌中。 现在,我们要做的就是对应用程序代码进行一些更改!

更新您的Spring Boot + Spring Security App以使用基于组的授权

Okta Spring Boot Starter真正开始发挥作用。 通常,如果您想将我们发送令牌的安全组和组声明映射到应用程序中的组,则必须编写一两个提取程序类来处理提取操作,也许还要编写一个组类。 Okta Spring Boot Starter可以为您完成所有这些工作!

您要做的第一件事是在SpringSecurityWebAppConfig类中添加以下注释。

@EnableGlobalMethodSecurity(prePostEnabled = true)

像这样:

import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;@EnableOAuth2Sso  
@Configuration  
@EnableGlobalMethodSecurity(prePostEnabled = true)  
public class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter {  /* class contents omitted for brevity */
}

此注释启用了我们将要使用的下一个注释@PreAuthorize注释。 该注释使我们可以使用Spring Expression Language(SpEL)谓词来确定控制器方法是否得到授权。 谓词表达式会在应用程序甚至进入控制器方法之前执行(因此需要“预先”授权)。

SimpleAppController类中,添加一个名为admin的新方法,如下所示:

import org.springframework.security.access.prepost.PreAuthorize;@Controller  
class SimpleAppController {  /* other controllers omitted for clarity */ @RequestMapping("/admin")  @PreAuthorize("hasAuthority('Admin')")  String admin() {  return "admin";  }  }

概括一下,此方法执行以下操作:

  • /admin url端点创建一个映射;
  • /admin端点分配基于SpEL的授权方案;
  • 并简单地返回Thymeleaf模板的名称,假设该/templates位于/templates目录中(我们将在下一个目录中创建)。

创建新的管理模板页面。 在src/main/resources/templates目录中,创建一个名为admin.html的新文件,其内容如下:

<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">  
<head>  <!--/*/ <th:block th:include="fragments/head :: head"/> /*/-->  
</head>  
<body>  
<div class="container-fluid">  <div class="row">  <div class="box col-md-6 col-md-offset-3">  <div class="okta-header">  <img src="img/logo.png"/>  </div>  <h1>Welcome to the admin page!</h1>  <a href="/" class="btn btn-primary">Go Home</a>  </div>  </div>  
</div>  
</body>  
</html>

您可能会问自己@PreAuthorize批注中使用的SpEL表达式是什么意思。 为什么SpEL表达式具有hasAuthority而不具有hasGroup ? 正确的答案有些复杂,这与Spring在不同上下文中调用权限特权和权限有关,可以在应用程序中将其映射到组和角色。 当使用Spring Boot和OAuth时,“权限”通常等同于“角色”,这很好。 但是您说我们使用的是群组,而不是角色? 对。 实际上,在这种情况下,这没关系,因为Okta知道我们在谈论群组,而应用程序知道我们在谈论群组,并且在中间,我们仅使用group声明和Authority字段来传达文本代表用户所属组的字符串。

有用的提示:

如果要检查Spring Boot App正在接收的身份验证信息,可以在return语句之前的控制器方法之一中添加以下行。

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

确实在此行上或其后设置一个断点,然后使用允许您检查身份验证对象的调试器运行该应用程序。 这是学习和调试问题的好方法。

试用您的新Spring Boot + Spring Security Web App!

就是这样。 您应该能够重新启动应用程序并以两个不同的用户身份登录。 只有添加到“管理员”组的用户才能访问“管理员”页面。 您必须直接导航到http:// localhost:8080 / admin(因为我们没有添加链接或按钮)。 如果您尝试与其他用户一起导航到管理页面,则会看到漂亮的whitelabel错误页面,其中显示403 /未经授权的错误。

请记住,在用户之间切换时,您必须停止应用程序,注销您的developer.okta.com帐户,然后重新启动应用程序。 您也可以在浏览器中使用隐身窗口。

本教程的这一部分与GroupsAuth标记相对应,您可以使用以下命令git checkout tags/GroupsAuth

了解有关Spring Boot,Spring Security和安全用户管理的更多信息

您在这里取得了一些实际进展。 您了解了如何创建一个简单的Spring Boot应用程序以及如何使用Thymeleaf模板。 您已经了解到Okta使OAuth 2.0 Single Sign-On集成到您的应用中有多么容易。 您已经了解了如何使用WebSecurityConfigurerAdapter子类和http.authorizeRequests() API来限制对控制器端点的访问。

最后,您已经了解了如何在Okta上创建组和用户,如何将它们绑定到Spring Boot应用程序中,以及如何使用@PreAuthorize批注根据组成员身份配置授权。

如果您想查看这个完整的项目,可以在Github上找到该仓库: https : //github.com/moksamedia/okta-spring-simple-app 。

如果您想了解有关Spring Boot,Spring Security或Okta的更多信息,请查看以下任何出色的教程:

  • Spring Boot,OAuth 2.0和Okta入门
  • 15分钟内将单一登录添加到您的Spring Boot Web App
  • 使用多重身份验证保护您的Spring Boot应用程序安全
  • 使用Spring Boot和GraphQL构建安全的API

如果您想深入研究,请查看Okta Spring Boot Starter GitHub页面 。

如果您对此帖子有任何疑问,请在下面添加评论。 有关更多精彩内容, 请在Twitter上关注@oktadev , 在Facebook上关注我们,或订阅我们的YouTube频道 。

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。

“使用Spring Boot和Spring Security在15分钟内构建Web应用程序”最初于2018年9月26日在Okta开发人员博客上发布。

翻译自: https://www.javacodegeeks.com/2019/02/build-web-app-spring-boot-spring-security.html

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

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

相关文章

音频光端机的必备要素有哪些?

音频光端机就是发射端把传统的音频模拟信号转换成光信号&#xff0c;通过光纤传输到接收端&#xff0c;在接收端再转换成模拟信号的一种音频设备。那么&#xff0c;音频光端机有哪些必备要素呢&#xff1f;音频光端机的原理是什么呢&#xff1f;接下来我们就一起来详细了解下吧…

php vue联动查询,使用vue.js实现联动效果的示例代码

摘要&#xff1a;本篇文章主要介绍了使用vue.js实现联动效果的示例代码&#xff0c;小编觉得挺不错的&#xff0c;现在分享给大家&#xff0c;也给大家做个参考。一起跟随小编过来看看吧想用vue.js写一个联动效果&#xff0c;按照自己的思路实验了下&#xff0c;并没有成功。请…

【渝粤教育】电大中专学前儿童语言教育 (4)作业 题库

作业视频教务托管&#xff0c;壹叁路路贰陆陆壹〇肆〇 认为儿童天生就有学习语言能力且体现在一种语言获得装置&#xff08;LAD&#xff09;中的教育家是( )。 A.斯金纳 B.乔姆斯基 C.皮亚杰 D.伍顿 错误 正确答案&#xff1a;左边查询 学生答案&#xff1a;未作答 2.下面哪个选…

Spring Setter依赖注入示例

学习如何编写Spring Setter依赖注入示例 。 Setter注入是Spring依赖注入的一种 。 Spring支持字段注入&#xff0c;Setter注入以及构造函数注入&#xff0c;以将依赖项注入Spring托管的bean中。 本教程的范围仅限于Setter注入。 有关Spring依赖注入的更多信息&#xff1a; Sp…

【渝粤教育】电大中专幼儿园课程论 (8)作业 题库

作业视频教务托管&#xff0c;壹叁路路贰陆陆壹〇肆〇 显性课程是 ( )的课程 A.指定的 B.随机的 C.有计划的 D.无计划的 错误 正确答案&#xff1a;左边查询 学生答案&#xff1a;未作答 2.幼儿园课程目标要素不包括( ) A.特征 B.目标 C.评价 D.内容 错误 正确答案&#xff1a;…

http和php怎么交互,实现http与workerman的交互demo

这里主要用到wm的聊天室demo做了一个示例。/*** This file is part of workerman.** Licensed under The MIT License* For full copyright and license information, please see the MIT-LICENSE.txt* Redistributions of files must retain the above copyright notice.** au…

16路开关量光端机产品功能及接线图

飞畅科技生产的16路开关量光端机&#xff0c;可以使开关量信号通过光缆在光纤上传输双向控制。全数字光传输通道&#xff0c;确保高质量的信号传输。面板上有电源指示灯、光信号指示灯数据信号指示灯&#xff0c;可以直观的检测电源、光信号、数据信号状态。单向系列开关量光端…

【渝粤教育】电大中专新媒体营销实务 (2)_1作业 题库

1.新媒体在进行内容传播时&#xff0c;可以做到将文字、图片、视频等同时传播&#xff0c;呈现出&#xff08;&#xff09;的特点。 A.移动化 B.多元化 C.便捷性 错误 正确答案&#xff1a;左边查询 学生答案&#xff1a;A 2.第四媒体发展到宽带互联网阶段成为&#xff08;&…

matlab查找替换指令,使用matlab GUI在.txt文件中编辑特定数字使用搜索/替换

使用matlab GUI在.txt文件中编辑特定数字使用搜索/替换 我有一堆不同的模板.txt文件&#xff0c;我想由Matlab中的用户访问。这些模板看起来像这样&#xff0c;但是有一些主要的区别&#xff0c;我将解释&#xff1a;LOAD BOX 1 SUBJ M1_299633_D295158_JUN191910_Aut_ERROR2 E…

【渝粤教育】电大中专电商运营实操 (18)作业 题库

1.电子商务具有全球性特点&#xff0c;不受空间的限制&#xff0c;但受时间的限制。 &#xff08; &#xff09; A.正确 B.错误 错误 正确答案&#xff1a;左边查询 学生答案&#xff1a;未作答 2.电子商务最重要的是“商务”&#xff0c;而网站只不过是电子商务的后台支撑。 &…

【渝粤教育】电大中专电子商务网站建设与维护 (2)作业 题库

VBScript的运算符号包括&#xff08;&#xff09; A.算数运算符 B.逻辑运算符 C.字符串&#xff08;连接&#xff09;运算符 D.比较运算符 E.以上都正确 正确答案&#xff1a;E 查看答案 2.Buffer从英文直译过来的意思是“缓冲区”&#xff0c;缓冲区是指服务器内存中的一块区域…

电话光端机安装步骤详解

光端机是光信号传输的终端设备&#xff0c;其主要作用是把传统的电话信号转换成光信号并在光纤上传输的设备&#xff0c;是随着光线技术的发展而出现的光端机产品。那么&#xff0c;电话光端机是怎么安装的呢&#xff1f;今天就由飞畅科技的小编来为大家介绍下电话光端机的详细…

更深入地了解Java 8 Date and Time API

在这篇文章中&#xff0c;我们将更深入地了解通过Java 8获得的新的Date / Time API&#xff08; JSR 310 &#xff09;。 请注意&#xff0c;本文主要由显示新API功能的代码示例驱动。 我认为这些示例是不言自明的&#xff0c;因此我并没有花太多时间在它们周围写文本:-) 让我…

matlab怎么提取特征,matlab – 了解提取特征的编码

我关注的编码是fisher编码,因为我已经证明我的工作效果最好.所以我想在我提取的(SIFT)功能上测试Fisher编码,并测试系统的性能,无论是否编码.而不是重新开始我发现vl_feat有一个用于fisher编码的内置库,他们有一个教程,以及链接here现在我已经完成了所需的大部分工作,但实际上编…

【渝粤教育】电大中专药剂学基础知识 (3)作业 题库

1.胶囊剂不检查的项目是&#xff08;&#xff09;。 A.装量差异 B.崩解时限 C.硬度 D.水分 E.外观 正确 正确答案&#xff1a;左边查询 学生答案&#xff1a;C 2.成裂片和顶裂的原因正确的是&#xff08;&#xff09;。 A.压力分布的不均匀 B.颗粒中细粉太多 C.颗粒过干 D.弹性…

【渝粤教育】电大中专计算机应用基础_1作业 题库

1.反映计算机存储容量的基本单位是() A.字节 B.字 C.二进制位 D.双字 正确 正确答案&#xff1a;左边查询 学生答案&#xff1a;A 2.巨型计算机指的是() A.重量大 B.功能强 C.体积大 D.耗电量大 错误 正确答案&#xff1a;左边查询 学生答案&#xff1a;A 3.在微型计算机中,下列…

关于光端机的一些常见术语解释

光端机&#xff0c;就是光信号传输的终端设备。今天飞畅科技的小编就来为大家详细介绍下光端机的类型&#xff0c;接口种类及厂家的术语&#xff0c;感兴趣的朋友就一起来详细了解下吧&#xff01; 一、光端机类型&#xff1a; 光端机&#xff0c;就是将多个E1&#xff08;一种…

php 站内搜索引擎,淘特站内搜索引擎For PhoCmsV9.4

一、产品特点&#xff1a;该产品是淘特站内搜索引擎For PhpCmsV9特别定制版&#xff0c;系统安装后&#xff0c;就可以索引、模糊查询PhpCmsV9的文章数据了(无需连接数据库哦)二、产品下载&#xff1a;三、使用说明&#xff1a;提示&#xff1a;本系统已和tomcat7打包&#xff…

【渝粤教育】电大中专跨境电子商务理论与实务 (31)作业 题库

1.在按照服务类型中&#xff0c;&#xff08;&#xff09;服务平台主要是为境内外会员商户提供网络营销平台&#xff0c;传递供应商或采购商等商家的商品或服务信息&#xff0c;促成双方完成交易。 A.信息服务平台 B.在线交易平台 C.线上服务平台 D.线下交易平台 正确 正确答案…

交换机组网常见九大故障问题

交换机是一种用于电信号转发的网络设备。它可以为接入交换机的任意两个网络节点提供独享的电信号通路。最常见的交换机是以太网交换机。其他常见的还有电话语音交换机、光纤交换机等。那么&#xff0c;交换机组网常见九大故障问题有哪些呢&#xff1f;接下来我们就跟随飞畅科技…