Spring Security示例UserDetailsS​​服务

欢迎使用UserDetailsS​​ ervice的Spring安全性示例。在上一篇文章中,我们学习了如何在Web应用程序中使用Spring Security。今天我们将研究如何在Spring MVC项目中集成Spring Security以进行身份验证。

目录[  隐藏  ]

  • 1 Spring安全示例

    • 1.1 Spring Security Maven依赖项
    • 1.2 Spring安全示例部署描述符
  • 2 UserDetailsS​​服务
    • 2.1 Spring安全示例控制器类
    • 2.2 Spring安全示例Bean配置文件
    • 2.3 Spring MVC安全配置
    • 2.4 Spring安全示例查看页面
    • 2.5 Spring Security MVC示例测试

春季安全示例

将Spring Security与Spring MVC Framework集成非常简单,因为我们已经有了Spring Beans配置文件。我们所需要的只是创建与弹簧安全认证相关的更改以使其正常工作。今天我们将研究如何使用内存,UserDetailsServiceDAO实现和基于JDBC的身份验证在Spring MVC应用程序中实现身份验证。

首先在Spring Tool Suite中创建一个简单的Spring MVC项目,它将为我们提供基础Spring MVC应用程序来构建我们的Spring安全性示例应用程序。一旦我们完成所有更改,我们的应用程序将如下图所示。

让我们看一下Spring安全性示例项目的每个组件。

Spring Security Maven依赖项

我们的最终pom.xml文件如下所示。


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.journaldev.spring</groupId><artifactId>SpringMVCSecurity</artifactId><name>SpringMVCSecurity</name><packaging>war</packaging><version>1.0.0-BUILD-SNAPSHOT</version><properties><java-version>1.6</java-version><org.springframework-version>4.0.2.RELEASE</org.springframework-version><org.aspectj-version>1.7.4</org.aspectj-version><org.slf4j-version>1.7.5</org.slf4j-version></properties><dependencies><!-- Spring --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${org.springframework-version}</version><exclusions><!-- Exclude Commons Logging in favor of SLF4j --><exclusion><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${org.springframework-version}</version></dependency><!-- Spring Security --><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId><version>3.2.3.RELEASE</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId><version>3.2.3.RELEASE</version></dependency><!-- AspectJ --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>${org.aspectj-version}</version></dependency>    <!-- Logging --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${org.slf4j-version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>jcl-over-slf4j</artifactId><version>${org.slf4j-version}</version><scope>runtime</scope></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>${org.slf4j-version}</version><scope>runtime</scope></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.15</version><exclusions><exclusion><groupId>javax.mail</groupId><artifactId>mail</artifactId></exclusion><exclusion><groupId>javax.jms</groupId><artifactId>jms</artifactId></exclusion><exclusion><groupId>com.sun.jdmk</groupId><artifactId>jmxtools</artifactId></exclusion><exclusion><groupId>com.sun.jmx</groupId><artifactId>jmxri</artifactId></exclusion></exclusions><scope>runtime</scope></dependency><!-- @Inject --><dependency><groupId>javax.inject</groupId><artifactId>javax.inject</artifactId><version>1</version></dependency><!-- Servlet --><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.1</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><!-- Test --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.7</version><scope>test</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>4.0.2.RELEASE</version></dependency></dependencies><build><plugins><plugin><artifactId>maven-eclipse-plugin</artifactId><version>2.9</version><configuration><additionalProjectnatures><projectnature>org.springframework.ide.eclipse.core.springnature</projectnature></additionalProjectnatures><additionalBuildcommands><buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand></additionalBuildcommands><downloadSources>true</downloadSources><downloadJavadocs>true</downloadJavadocs></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.5.1</version><configuration><source>1.6</source><target>1.6</target><compilerArgument>-Xlint:all</compilerArgument><showWarnings>true</showWarnings><showDeprecation>true</showDeprecation></configuration></plugin><plugin><groupId>org.codehaus.mojo</groupId><artifactId>exec-maven-plugin</artifactId><version>1.2.1</version><configuration><mainClass>org.test.int1.Main</mainClass></configuration></plugin></plugins></build>
</project>

这里已包括spring-security-configspring-security-web为Spring Security依赖。除此之外我们还有spring-jdbc依赖,因为我们也将使用Spring JDBC身份验证。

其余依赖项与Spring MVC,日志记录,AOP等相关。

Spring安全性示例部署描述符

我们的web.xml文件如下所示。


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><!-- Spring Security Configuration File --><context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring/appServlet/spring-security.xml</param-value></context-param><!-- Creates the Spring Container shared by all Servlet and Filters --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><listener><listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class></listener><session-config><session-timeout>15</session-timeout></session-config><!-- Spring Security Filter --><filter><filter-name>springSecurityFilterChain</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping><filter-name>springSecurityFilterChain</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- Spring MVC - START --><servlet><servlet-name>appServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>appServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!-- Spring MVC - END --></web-app>

contextConfigLocation是我们提供spring安全bean配置文件名的context参数。它用于ContextLoaderListener在我们的应用程序中配置身份验证。

我们还添加了HttpSessionEventPublisher侦听器,以将会话创建/销毁事件发布到Spring Root WebApplicationContext。

我也设置session-timeout为15分钟,当用户处于非活动状态15分钟时,用于自动超时。

DelegatingFilterProxy 是定义的应用程序过滤器,它用于拦截HTTP请求和执行与身份验证相关的任务。

DispatcherServlet servlet是Spring MVC应用程序的前端控制器。

的UserDetailsS​​ervice

如果我们想使用任何DAO类进行身份验证,我们需要实现UserDetailsService接口。配置DAO后,它将loadUserByUsername()用于验证用户。


package com.journaldev.spring.security.dao;import java.util.Collection;
import java.util.List;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;public class AppUserDetailsServiceDAO implements UserDetailsService {protected final Log logger = LogFactory.getLog(getClass());@Overridepublic UserDetails loadUserByUsername(final String username)throws UsernameNotFoundException {logger.info("loadUserByUsername username="+username);if(!username.equals("pankaj")){throw new UsernameNotFoundException(username + " not found");}//creating dummy user details, should do JDBC operationsreturn new UserDetails() {private static final long serialVersionUID = 2059202961588104658L;@Overridepublic boolean isEnabled() {return true;}@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isAccountNonLocked() {return true;}@Overridepublic boolean isAccountNonExpired() {return true;}@Overridepublic String getUsername() {return username;}@Overridepublic String getPassword() {return "pankaj123";}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {List<SimpleGrantedAuthority> auths = new java.util.ArrayList<SimpleGrantedAuthority>();auths.add(new SimpleGrantedAuthority("Admin"));return auths;}};}}

请注意,我UserDetails通过使用匿名内部类实现返回实例。理想情况下,我们应该有一个实现类,UserDetails也可以有其他用户数据,如emailID,用户名,地址等。

请注意,唯一可行的组合是用户名为“pankaj”且密码为“pankaj123”。

Spring安全性示例控制器类

这是我们的控制器类,它定义了我们可以访问的两个URI。


package com.journaldev.spring.controller;import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;import javax.servlet.http.HttpServletRequest;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;@Controller
public class HomeController {private static final Logger logger = LoggerFactory.getLogger(HomeController.class);@RequestMapping(value = "/home", method = RequestMethod.GET)public String home(Locale locale, Model model) {logger.info("Welcome home! The client locale is {}.", locale);Date date = new Date();DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);String formattedDate = dateFormat.format(date);model.addAttribute("serverTime", formattedDate );return "home";}@RequestMapping(value = "/emp/get/{id}", method = RequestMethod.GET)public String getEmployee(Locale locale, Model model,@PathVariable("id") int id) {logger.info("Welcome user! Requested Emp ID is: "+id);Date date = new Date();DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);String formattedDate = dateFormat.format(date);model.addAttribute("serverTime", formattedDate );model.addAttribute("id", id);model.addAttribute("name", "Pankaj");return "employee";}@RequestMapping(value="/login")public String login(HttpServletRequest request, Model model){return "login";}@RequestMapping(value="/logout")public String logout(){return "logout";}@RequestMapping(value="/denied")public String denied(){return "denied";}
}

在我们的示例中,我们仅将身份验证应用于URI“/ emp / get / {id}”。无需任何身份验证即可访问所有其他URI。登录,注销和拒绝URI用于在请求安全URL时发送相应的响应页面。

Spring安全示例Bean配置文件


<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:beans="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --><!-- Enables the Spring MVC @Controller programming model --><annotation-driven /><!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --><resources mapping="/resources/**" location="/resources/" /><!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --><beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><beans:property name="prefix" value="/WEB-INF/views/" /><beans:property name="suffix" value=".jsp" /></beans:bean><context:component-scan base-package="com.journaldev.spring.controller" /></beans:beans>

我们的spring bean配置文件很简单,它只有与Spring MVC应用程序相关的配置。

Spring MVC安全配置

这是我们教程中最重要的部分,让我们来看看我们的文件。我们将逐一了解每个部分。

spring-security.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- Configuring RoleVoter bean to use custom access roles, by default roles should be in the form ROLE_{XXX} --><beans:bean id="roleVoter"class="org.springframework.security.access.vote.RoleVoter"><beans:property name="rolePrefix" value=""></beans:property></beans:bean><beans:bean id="accessDecisionManager"class="org.springframework.security.access.vote.AffirmativeBased"><beans:constructor-arg name="decisionVoters"ref="roleVoter" /></beans:bean><http authentication-manager-ref="jdbc-auth"access-decision-manager-ref="accessDecisionManager">   <intercept-url pattern="/emp/**" access="Admin" /><form-login login-page="/login" authentication-failure-url="/denied"username-parameter="username" password-parameter="password"default-target-url="/home" /><logout invalidate-session="true" logout-success-url="/login"logout-url="/j_spring_security_logout" /><access-denied-handler error-page="/denied"/><session-management invalid-session-url="/login"><concurrency-control max-sessions="1"expired-url="/login" /></session-management></http><authentication-manager id="in-memory-auth"><authentication-provider><user-service><user name="pankaj" password="pankaj123" authorities="Admin" /></user-service></authentication-provider></authentication-manager><authentication-manager id="dao-auth"><authentication-provider user-service-ref="userDetailsService"></authentication-provider></authentication-manager><beans:bean id="userDetailsService"class="com.journaldev.spring.security.dao.AppUserDetailsServiceDAO" /><authentication-manager id="jdbc-auth"><authentication-provider><jdbc-user-service data-source-ref="dataSource"users-by-username-query="select username,password,enabled from Employees where username = ?"authorities-by-username-query="select username,role from Roles where username = ?" /></authentication-provider></authentication-manager><!-- MySQL DB DataSource --><beans:bean id="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource"><beans:property name="driverClassName" value="com.mysql.jdbc.Driver" /><beans:property name="url"value="jdbc:mysql://localhost:3306/TestDB" /><beans:property name="username" value="pankaj" /><beans:property name="password" value="pankaj123" /></beans:bean><!-- If DataSource is configured in Tomcat Servlet Container --><beans:bean id="dbDataSource"class="org.springframework.jndi.JndiObjectFactoryBean"><beans:property name="jndiName" value="java:comp/env/jdbc/MyLocalDB" /></beans:bean>
</beans:beans>

accessDecisionManagerbean被定义为我们可以拥有自定义角色,默认情况下所有角色都应该以ROLE_开头,并且我们在roleVoterbean属性中覆盖了这个设置rolePrefix

我们可以在spring安全配置中定义多个身份验证管理器。我已经in-memory-auth为内存中的身份验证,dao-authUserDetailsS​​ervice DAO实现和jdbc-authJDBC身份验证定义了。对于JDBC身份验证,我已经为应用程序中定义的DataSource提供了配置,以及我们是否要使用servlet容器中定义的JNDI资源。

http authentication-manager-ref用于定义将用于验证用户的身份验证管理器。目前,它已配置为使用基于JDBC的身份验证。

http access-decision-manager-ref用于指定应该用于授权HTTP请求的AccessDecisionManager实现的ID。

intercept-url用于定义可以访问此页面的用户的URL模式和权限。例如,我们已经定义了URI“/ emp / **”只能由具有“Admin”访问权限的用户访问。

form-login定义登录表单配置,我们可以提供用户名和密码参数名称。authentication-failure-url用于定义身份验证失败页面的URL。如果未指定登录失败URL,Spring Security将自动在/ spring_security_login?login_error创建失败登录URL,并在请求时自动创建登录失败URL。

default-target-url用于定义在成功验证后将重定向到的默认URL,如果用户的先前操作无法恢复。如果用户在没有首先请求触发认证的安全操作的情况下访问登录页面,则通常会发生这种情况。如果未指定,则默认为应用程序的根目录。

logout用于定义注销处理过滤器。这里我们使会话无效并在成功注销后将用户发送到登录页面。logout-url用于定义用于注销操作的URL。

access-denied-handler 如果拒绝用户访问,则定义全局错误页面,因为他无权执行指定的操作。

session-management 将SessionManagementFilter过滤器添加到会话管理的过滤器堆栈。

还有一些其他配置,但我已经包含了我们使用的大多数重要配置。

Spring安全示例查看页面

在部署和测试我们的应用程序之前,让我们快速浏览一下我们的视图页面。

home.jsp


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page session="false"%>
<html>
<head>
<title>Home</title>
</head>
<body><h1>Hello world!</h1><P>The time on the server is ${serverTime}.</P>
</body>
</html>

home.jsp返回“/ home”URI,不应该要求任何身份验证。

employee.jsp


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page session="false"%>
<html>
<head>
<title>Get Employee Page</title>
</head>
<body><h1>Employee Information</h1><p>Employee ID:${id}<br> Employee Name:${name}<br></p><c:if test="${pageContext.request.userPrincipal.name != null}">Hi ${pageContext.request.userPrincipal.name}<br><c:url var="logoutAction" value="/j_spring_security_logout"></c:url><form action="${logoutAction}" method="post"><input type="submit" value="Logout" /></form></c:if>
</body>
</html>

当我们访问需要身份验证的URI时,将返回此页面。这里我提供了注销选项,以便用户可以注销并终止会话。注销成功后,应按照配置将用户发送回登录页面。

login.jsp


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><html><head>
<title>Login Page</title>
</head>
<body><h3>Login with Username and Password</h3><c:url var="loginUrl" value="/j_spring_security_check"></c:url><form action="${loginUrl}" method="POST"><table><tr><td>User ID:</td><td><input type='text' name='username' /></td></tr><tr><td>Password:</td><td><input type='password' name='password' /></td></tr><tr><td colspan='2'><input name="submit" type="submit"value="Login" /></td></tr></table></form>
</body>
</html>

这里有几点需要注意。第一个是登录URL是“ / j_spring_security_check ”。这是默认的登录处理URL,就像logout-url一样。

另一个重点是用户名和密码的表单参数名称。它们应与弹簧安全配置中配置的相同。

logout.jsp


<html>
<head><title>Logout Page</title>
</head>
<body>
<h2>Logout Successful!
</h2></body>
</html>

denied.jsp


<html>
<head><title>Access Denied</title>
</head>
<body>
<h1>Access Denied!
</h1></body>
</html>

logout.jsp和denied.jsp页面很简单,但我们可以根据用户的详细信息在这里包含一些信息。

我们的春季安全性示例应用程序已准备好进行测试,请注意,对于JDBC身份验证,我使用的是与之前的春季安全性示例相同的设置。所以如果你直接降落在这里,你应该检查出来。

Spring Security MVC示例测试

只需将应用程序部署在您最喜欢的servlet容器中,我的是Apache Tomcat 7.下图显示了不同URL的不同输出。

Spring安全示例 - 没有身份验证的主页

Spring安全示例 - 请求启用身份验证页面时的登录页面(/ emp / get / {20})

Spring安全示例 - 身份验证成功时的响应页面

Spring安全示例 - 身份验证失败时访问被拒绝的页面

这就是使用UserDetailsS​​ ervice的春季安全示例,请从下面的链接下载示例项目并浏览它以了解更多信息。

下载Spring MVC安全项目

Spring Security 示例UserDetailsS​​ervice相关推荐

  1. Spring安全示例UserDetailsS​​ervice

    Welcome to Spring Security Example using UserDetailsService. In the last post we learned how to use ...

  2. 带有Spring Boot 2.0的Spring Security:UserDetailsS​​ervice

    正如我们在上一篇文章中所看到的,我们的spring应用程序的用户名和密码是通过环境变量配置的. 这对于原型目的是可以的,但是在现实生活中,我们必须提供另一种方式来使用户有资格登录到该应用程序. 为此, ...

  3. Spring Security示例教程

    Spring Security provides ways to perform authentication and authorization in a web application. We c ...

  4. Spring Security 示例教程

    Spring Security 示例教程 Spring Security提供了在Web应用程序中执行身份验证和授权的方法.我们可以在任何基于servlet的Web应用程序中使用spring secur ...

  5. java ldap操作实例_Java Spring Security示例教程中的2种设置LDAP Active Directory身份验证的方法...

    java ldap操作实例 LDAP身份验证是世界上最流行的企业应用程序身份验证机制之一,而Active Directory (Microsoft为Windows提供的LDAP实现)是另一种广泛使用的 ...

  6. Java Spring Security示例教程中的2种设置LDAP Active Directory身份验证的方法

    LDAP身份验证是全球范围内最流行的企业应用程序身份验证机制之一,而Active Directory (Microsoft针对Windows的LDAP实现)是另一种广泛使用的LDAP服务器. 在许多项 ...

  7. service获取selinux权限_Spring Boot 整合 Spring Security 示例实现前后分离权限注解 + JWT 登录认证...

    点击上方蓝色字体,选择"标星公众号" 优质文章,第一时间送达 99套Java企业级实战项目 4000G架构师资料 作者:Sans_ juejin.im/post/5da82f066 ...

  8. Spring Boot 整合 Spring Security 示例

    点击关注公众号,Java干货及时送达 一.说明 SpringSecurity是一个用于Java 企业级应用程序的安全框架,主要包含用户认证和用户授权两个方面.相比较Shiro而言,Security功能 ...

  9. Spring安全示例教程

    Spring安全示例教程 Spring Security提供了在Web应用程序中执行身份验证和授权的方法.我们可以在任何基于servlet的Web应用程序中使用spring security. 目录[ ...

最新文章

  1. 解决win10安装MySQL数据库出现服务无法启动的问题
  2. Access库的小问题
  3. 算法题:水洼有多少(C++)
  4. 基于互联网生态积累,百度Apollo智舱产品斩获智能网联创新奖
  5. Hadoop源码分类概要整理
  6. python中math库_Python的math库、random库实际应用
  7. 使用Istio进行多集群部署管理(2):单控制平面Gateway连接拓扑
  8. c语言程序设计实践教程编程题8.3,C语言程序设计教程(21世纪计算机科学与技术实践型教程)...
  9. 用OpenSSL写一个简单的Server/Client程序:证书与私钥
  10. 服务器文件地址怎么写,服务器里的文件链接地址怎么写
  11. MR案例:输出/输入SequenceFile
  12. 三,linux系统的由来
  13. Weka算法Classifier-tree-J48源代码分析(一个)基本数据结构和算法
  14. 在线图片水平/垂直均等切割工具
  15. 刚注册博客了,发发随笔
  16. dw怎么保存HTML手机可以看,【dw网页制作】如何使用Dreamweaver制作网页?如何用Dreamweaver制作个人虚拟网站?dreamweaver如何制作手机网站?...
  17. 第二人生的源码分析(2)第二人生的基本功能
  18. spark开发及调优
  19. spotify电脑下载歌曲_26步,把Spotify音乐集成进SAP
  20. ------已搬运-------BUUCTF:[BJDCTF 2nd]假猪套天下第一-----------Header请求头学习!!!

热门文章

  1. SVG 教程 (四)多边形,曲线,路径
  2. scrapy splash 爬取图片学习心得
  3. 【三维深度学习】Sparse Convolutional Network 基于稀疏采样不变性的深度稠密重建
  4. SpringBoot—jasypt加解密库的使用方法
  5. linux 下按内容查找文件
  6. 9206 课堂笔记 综合演练 添加数据与非空验证
  7. 线程加入 java 1615477815
  8. 案例 以继承的方式实现解析频道节目单 c# 1614262275
  9. 前端开发 css样式的简写
  10. jquery-nodejs-安装与测试