本篇文章参考大神的文章,总结而来。附赠大神帖子地址。https://jinnianshilongnian.iteye.com/blog/2018398

什么是Shiro?

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。

Shiro的作用

Shiro可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境。Shiro可以帮助我们完成:认证、授权、加密、会话管理、与Web集成、缓存等。这不就是我们想要的嘛,而且Shiro的API也是非常简单;其基本功能点如下图所示:

Authentication:身份认证/登录,验证用户是不是拥有相应的身份;

Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;

Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;

Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;

Web Support:Web支持,可以非常容易的集成到Web环境;

Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;

Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;

Testing:提供测试支持;

Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;

Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

从外部来看Shiro

可以看到:应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心就是Subject;

Subject:主体,代表了当前“用户”,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等;即一个抽象概念;所有Subject都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager;可以把Subject认为是一个门面;SecurityManager才是实际的执行者;

SecurityManager:安全管理器;即所有与安全有关的操作都会与SecurityManager交互;且它管理着所有Subject;可以看出它是Shiro的核心,它负责与后边介绍的其他组件进行交互,如果学习过SpringMVC,你可以把它看成DispatcherServlet前端控制器;

Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。

就是说对于我们而言,最简单的一个Shiro应用流程:

1、应用代码通过Subject来进行认证和授权,而Subject又委托给SecurityManager;

2、我们需要给Shiro的SecurityManager注入Realm,从而让SecurityManager能得到合法的用户及其权限进行判断。

从内部来看Shiro

Subject:主体,可以看到主体可以是任何可以与应用交互的“用户”;

SecurityManager:相当于SpringMVC中的DispatcherServlet或者Struts2中的FilterDispatcher;是Shiro的心脏;所有具体的交互都通过SecurityManager进行控制;它管理着所有Subject、且负责进行认证和授权、及会话、缓存的管理。

Authenticator:认证器,负责主体认证的,这是一个扩展点,如果用户觉得Shiro默认的不好,可以自定义实现;其需要认证策略(Authentication Strategy),即什么情况下算用户认证通过了;

Authrizer:授权器,或者访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的哪些功能;

Realm:可以有1个或多个Realm,可以认为是安全实体数据源,即用于获取安全实体的;可以是JDBC实现,也可以是LDAP实现,或者内存实现等等;由用户提供;注意:Shiro不知道你的用户/权限存储在哪及以何种格式存储;所以我们一般在应用中都需要实现自己的Realm;

SessionManage:如果写过Servlet就应该知道Session的概念,Session呢需要有人去管理它的生命周期,这个组件就是SessionManager;而Shiro并不仅仅可以用在Web环境,也可以用在如普通的JavaSE环境、EJB等环境;所有呢,Shiro就抽象了一个自己的Session来管理主体与应用之间交互的数据;这样的话,比如我们在Web环境用,刚开始是一台Web服务器;接着又上了台EJB服务器;这时想把两台服务器的会话数据放到一个地方,这个时候就可以实现自己的分布式会话(如把数据放到Memcached服务器);

SessionDAO:DAO大家都用过,数据访问对象,用于会话的CRUD,比如我们想把Session保存到数据库,那么可以实现自己的SessionDAO,通过如JDBC写到数据库;比如想把Session放到Memcached中,可以实现自己的Memcached SessionDAO;另外SessionDAO中可以使用Cache进行缓存,以提高性能;

CacheManager:缓存控制器,来管理如用户、角色、权限等的缓存的;因为这些数据基本上很少去改变,放到缓存中后可以提高访问的性能

Cryptography:密码模块,Shiro提高了一些常见的加密组件用于如密码加密/解密的。

第一个Shiro的HelloWord

导入jar包

  • shiro-all-1.3.2.jar
  • log4j-1.2.15.jar
  • slf4j-api-1.6.1.jar
  • slf4j-log4j12-1.6.1.jar

配置文件

# =============================================================================
# Quickstart INI Realm configuration
#
# For those that might not understand the references in this file, the
# definitions are all based on the classic Mel Brooks' film "Spaceballs". ;)
# =============================================================================# -----------------------------------------------------------------------------
# Users and their assigned roles
#
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setUserDefinitions JavaDoc
# -----------------------------------------------------------------------------
[users]
# user 'root' with password 'secret' and the 'admin' role
root = secret, admin
# user 'guest' with the password 'guest' and the 'guest' role
guest = guest, guest
# user 'presidentskroob' with password '12345' ("That's the same combination on
# my luggage!!!" ;)), and role 'president'
presidentskroob = 12345, president
# user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz'
darkhelmet = ludicrousspeed, darklord, schwartz
# user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz'
lonestarr = vespa, goodguy, schwartz# -----------------------------------------------------------------------------
# Roles with assigned permissions
#
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc
# -----------------------------------------------------------------------------
[roles]
# 'admin' role has all permissions, indicated by the wildcard '*'
admin = *
# The 'schwartz' role can do anything (*) with any lightsaber:
schwartz = lightsaber:*
# The 'goodguy' role is allowed to 'delete' (action) the user (type) with
# license plate 'zhangsan' (instance specific id)
#user可以删除zhangsan
goodguy = user:delete:zhangsan

配置文件中配置了简单的几个用户和角色,当然实际开发中不可能将用户信息放入配置文件,都是从数据库动态获取用户信息。这里只是简单的测试。

测试代码:

package cn.xyl.shiro;import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class HelloWord {private static final transient Logger log = LoggerFactory.getLogger(HelloWord.class);public static void main(String[] args) {// The easiest way to create a Shiro SecurityManager with configured// realms, users, roles and permissions is to use the simple INI config.// We'll do that by using a factory that can ingest a .ini file and// return a SecurityManager instance:// Use the shiro.ini file at the root of the classpath// (file: and url: prefixes load from files and urls respectively):Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");SecurityManager securityManager = factory.getInstance();// for this simple example quickstart, make the SecurityManager// accessible as a JVM singleton. Most applications wouldn't do this// and instead rely on their container configuration or web.xml for// webapps. That is outside the scope of this simple quickstart, so// we'll just do the bare minimum so you can continue to get a feel// for things.//绑定给SecurityUtils    这是一个全局设置,设置一次即可;SecurityUtils.setSecurityManager(securityManager);// Now that a simple Shiro environment is set up, let's see what you can do:// get the currently executing user:// 获取当前的 Subject. 调用 SecurityUtils.getSubject();   //通过SecurityUtils得到Subject,其会自动绑定到当前线程Subject subject = SecurityUtils.getSubject();// Do some stuff with a Session (no need for a web or EJB container!!!)// 测试使用 Session// 获取 Session: Subject#getSession()Session session = subject.getSession();session.setAttribute("someKey", "aValue");String value = (String) session.getAttribute("someKey");if (value.equals("aValue")) {log.info("---> Retrieved the correct value! [" + value + "]");}// let's login the current user so we can check against roles and permissions:// 测试当前的用户是否已经被认证. 即是否已经登录.// 调动 Subject 的 isAuthenticated()if (!subject.isAuthenticated()) {// 把用户名和密码封装为 UsernamePasswordToken 对象UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");// remembermetoken.setRememberMe(true);try {// 执行登录.subject.login(token);}// 若没有指定的账户, 则 shiro 将会抛出 UnknownAccountException 异常.catch (UnknownAccountException uae) {log.info("----> There is no user with username of " + token.getPrincipal());return;}// 若账户存在, 但密码不匹配, 则 shiro 会抛出 IncorrectCredentialsException 异常。catch (IncorrectCredentialsException ice) {log.info("----> Password for account " + token.getPrincipal() + " was incorrect!");return;}// 用户被锁定的异常 LockedAccountExceptioncatch (LockedAccountException lae) {log.info("The account for username " + token.getPrincipal() + " is locked.  "+ "Please contact your administrator to unlock it.");}// ... catch more exceptions here (maybe custom ones specific to your// application?// 所有认证时异常的父类.catch (AuthenticationException ae) {// unexpected condition? error?}}// say who they are:// print their identifying principal (in this case, a username):log.info("----> User [" + subject.getPrincipal() + "] logged in successfully.");// test a role:// 测试是否有某一个角色. 调用 Subject 的 hasRole 方法.if (subject.hasRole("schwartz")) {log.info("----> May the Schwartz be with you!");} else {log.info("----> Hello, mere mortal.");return;}// test a typed permission (not instance-level)// 测试用户是否具备某一个行为. 调用 Subject 的 isPermitted() 方法。if (subject.isPermitted("lightsaber:weild")) {log.info("----> You may use a lightsaber ring.  Use it wisely.");} else {log.info("Sorry, lightsaber rings are for schwartz masters only.");}// a (very powerful) Instance Level permission:// 测试用户是否具备某一个行为.if (subject.isPermitted("user:delete:zhangsan")) {log.info("----> You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  "+ "Here are the keys - have fun!");} else {log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");}// all done - log out!0// 执行登出. 调用 Subject 的 Logout() 方法.System.out.println("---->" + subject.isAuthenticated());subject.logout();System.out.println("---->" + subject.isAuthenticated());System.exit(0);}}

测试代码中演示了使用Shiro的基本流程

  1. 首先通过new IniSecurityManagerFactory并指定一个ini配置文件来创建一个SecurityManager工厂;
  2. 接着获取SecurityManager并绑定到SecurityUtils,这是一个全局设置,设置一次即可;
  3. 通过SecurityUtils得到Subject,其会自动绑定到当前线程;如果在web环境在请求结束时需要解除绑定;然后获取身份验证的Token,如用户名/密码;
  4. 调用subject.login方法进行登录,其会自动委托给SecurityManager.login方法进行登录;
  5. 如果身份验证失败请捕获AuthenticationException或其子类,常见的如: DisabledAccountException(禁用的帐号)、LockedAccountException(锁定的帐号)、UnknownAccountException(错误的帐号)、ExcessiveAttemptsException(登录失败次数过多)、IncorrectCredentialsException (错误的凭证)、ExpiredCredentialsException(过期的凭证)等,具体请查看其继承关系;对于页面的错误消息展示,最好使用如“用户名/密码错误”而不是“用户名错误”/“密码错误”,防止一些恶意用户非法扫描帐号库;
  6. 调用subject.hasRole方法判断是否是某一角色,调用subject.isPermitted方法判断是否具备某一行为。
  7. 最后可以调用subject.logout退出,其会自动委托给SecurityManager.logout方法退出。

基础原理和概念

Subject介绍

Subject是Shiro的核心对象,基本所有身份验证、授权都是通过Subject完成。

相应的方法

1、身份信息获取

Object getPrincipal(); //Primary Principal  PrincipalCollection getPrincipals(); // PrincipalCollection

2、身份验证

void login(AuthenticationToken token) throws AuthenticationException; boolean isAuthenticated(); boolean isRemembere();

通过login登录,如果登录失败将抛出相应的AuthenticationException,如果登录成功调用isAuthenticated就会返回true,即已经通过身份验证;如果isRemembered返回true,表示是通过记住我功能登录的而不是调用login方法登录的。isAuthenticated/isRemembered是互斥的,即如果其中一个返回true,另一个返回false。

3、角色授权验证

boolean hasRole(String roleIdentifier);  boolean[] hasRoles(List<String> roleIdentifiers);  boolean hasAllRoles(Collection<String> roleIdentifiers);  void checkRole(String roleIdentifier) throws AuthorizationException;  void checkRoles(Collection<String> roleIdentifiers) throws AuthorizationException;  void checkRoles(String... roleIdentifiers) throws AuthorizationException;

hasRole进行角色验证,验证后返回true/false;而checkRole验证失败时抛出AuthorizationException异常。

4、权限授权验证

itted(String permission);  boolean isPermitted(Permission permission);  boolean[] isPermitted(String... permissions);  boolean[] isPermitted(List<Permission> permissions);  boolean isPermittedAll(String... permissions);  boolean isPermittedAll(Collection<Permission> permissions);  void checkPermission(String permission) throws AuthorizationException;  void checkPermission(Permission permission) throws AuthorizationException;  void checkPermissions(String... permissions) throws AuthorizationException;  void checkPermissions(Collection<Permission> permissions) throws AuthoriationException;

isPermitted进行权限验证,验证后返回true/false;而checkPermission验证失败时抛出AuthorizationException。

5、会话

Session getSession(); //相当于getSession(true)
Session getSession(boolean create);

类似于Web中的会话。如果登录成功就相当于建立了会话,接着可以使用getSession获取;如果create=false如果没有会话将返回null,而create=true如果没有会话会强制创建一个。

6、退出*

void logout();

ShiroFilter拦截器的工作原理

filterChainDefinition的配置

•[urls] 部分的配置,其格式是:“url=拦截器[参数],拦截器[参数]”; •如果当前请求的url匹配[urls] 部分的某个url模式,将会执行其配置的拦截器。 •anon(anonymous)拦截器表示匿名访问(即不需要登录即可访问) •authc(authentication)拦截器表示需要身份认证通过后才能访问

其他的默认拦截器:

URL 匹配模式

•url模式使用Ant 风格模式 •Ant 路径通配符支持?、*,注意通配符匹配不包括目录分隔符“/”:

  • ?:匹配一个字符,如/admin? 将匹配/admin1,但不匹配/admin 或/admin/;
  • *:匹配零个或多个字符串,如/admin 将匹配/admin、/admin123,但不匹配/admin/1;
  • *:匹配路径中的零个或多个路径,如/admin/* 将匹配/admin/a 或/admin/a/b

URL 匹配顺序

•URL 权限采取第一次匹配优先的方式,即从头开始使用第一个匹配的url模式对应的拦截器链。 •如:

  • /bb/**=filter1
  • /bb/aa=filter2
  • /**=filter3

如果请求的url是“/bb/aa”,因为按照声明顺序进行匹配,那么将使用filter1 进行拦截。

认证流程

1、首先调用 Subject.login(token) 进行登录,其会自动委托给SecurityManager

2、SecurityManager 负责真正的身份验证逻辑;它会委托给Authenticator 进行身份验证;

3、Authenticator 才是真正的身份验证者,Shiro API 中核心的身份认证入口点,此处可以自定义插入自己的实现;

4、Authenticator 可能会委托给相应的 AuthenticationStrategy 进行多 Realm 身份验证,默认 ModularRealmAuthenticator 会调用AuthenticationStrategy 进行多 Realm 身份验证;

5、Authenticator 会把相应的 token 传入 Realm,从 Realm 获取身份验证信息,如果没有返回/抛出异常表示身份验证失败了。此处可以配置多个Realm,将按照相应的顺序及策略进行访问。

注意:Shiro本身不维护用户账户信息,需要程序员自己从数据库或别的地方获取数据提供给Shiro进行登录认证和权限认证。如何将数据提供给shiro呢?Shiro提供了抽象类供我们继承,通过实现抽象方法实现验证。我们称之为Realm。

什么是Realm

Realm:Shiro 从 Realm 获取安全数据(如用户、角色、权限),即 SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作。

如何自定义Realm

认证:

​ 继承AuthenticatingRealm 类。

​ 实现抽象方法doGetAuthenticationInfo方法

​ 在Spring容器中创建bean,在securityManager 安全管理器配置自定义的realm

授权:

​ 和认证的步骤差不多,只是继承的类不同,授权需要继承AuthorizingRealm 类,在AuthorizingRealm 类是AuthenticatingRealm的子类,而AuthorizingRealm 类没有实现doGetAuthenticationInfo方法,所以可以将认证和授权放在一个realm类中。

AuthorizingRealm(授权) 类和AuthenticatingRealm(认证)类的介绍

  1. AuthorizingRealm 类是AuthenticatingRealm的子类
  2. 两个抽象方法
  3. doGetAuthenticationInfo获取身份验证相关信息:首先根据传入的用户名获取User信息;然后如果user为空,那么抛出没找到帐号异常UnknownAccountException;如果user找到但锁定了抛出锁定异常LockedAccountException;最后生成AuthenticationInfo信息,交给间接父类AuthenticatingRealm使用CredentialsMatcher进行判断密码是否匹配,如果不匹配将抛出密码错误异常IncorrectCredentialsException;另外如果密码重试此处太多将抛出超出重试次数异常ExcessiveAttemptsException;在组装SimpleAuthenticationInfo信息时,需要传入:身份信息(用户名)、凭据(密文密码)、盐(username+salt),CredentialsMatcher使用盐加密传入的明文密码和此处的密文密码进行匹配。
  4. doGetAuthorizationInfo获取授权信息:PrincipalCollection是一个身份集合,因为我们现在就一个Realm,所以直接调用getPrimaryPrincipal得到之前传入的用户名即可;然后根据用户名调用UserService接口获取角色及权限信息。

认证方法的介绍

Shiro本身不维护用户账户信息,需要程序员自己从数据库或别的地方获取数据提供给Shiro进行登录认证和权限认证。

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException

参数为AuthenticationToken

AuthenticationToken用于收集用户提交的身份(如用户名)及凭据(如密码)

public interface AuthenticationToken extends Serializable {  Object getPrincipal(); //身份  Object getCredentials(); //凭据  }

返回值类型为AuthenticationInfo

AuthenticationInfo有两个作用:

1、如果Realm是AuthenticatingRealm子类,则提供给AuthenticatingRealm内部使用的CredentialsMatcher进行凭据验证;(如果没有继承它需要在自己的Realm中自己实现验证);

2、提供给SecurityManager来创建Subject(提供身份信息)一般;

一般情况下返回其子类SimpleAuthenticationInfo。

授权流程

名词说明:

• 授权,也叫访问控制,即在应用中控制谁访问哪些资源(如访问页面/编辑数据/页面操作等)。在授权中需了解的几个关键对象:主体(Subject)、资源(Resource)、权限(Permission)、角色(Role)。

• 主体(Subject):访问应用的用户,在 Shiro 中使用 Subject 代表该用户。用户只有授权后才允许访问相应的资源。

• 资源(Resource):在应用中用户可以访问的 URL,比如访问 JSP 页面、查看/编辑某些数据、访问某个业务方法、打印文本等等都是资源。用户只要授权后才能访问。

• 权限(Permission):安全策略中的原子授权单位,通过权限我们可以表示在应用中用户有没有操作某个资源的权力。即权限表示在应用中用户能不能访问某个资源,如:访问用户列表页面查看/新增/修改/删除用户数据(即很多时候都是CRUD(增查改删)式权限控制)等。权限代表了用户有没有操作某个资源的权利,即反映在某个资源上的操作允不允许。

• Shiro 支持粗粒度权限(如用户模块的所有权限)和细粒度权限(操作某个用户的权限,即实例级别的)

• 角色(Role):权限的集合,一般情况下会赋予用户角色而不是权限,即这样用户可以拥有一组权限,赋予权限时比较方便。典型的如:项目经理、技术总监、CTO、开发工程师等都是角色,不同的角色拥有一组不同的权限。

流程如下:

1、首先调用Subject.isPermitted/hasRole接口,其会委托给SecurityManager,而SecurityManager接着会委托给Authorizer;

2、Authorizer是真正的授权者,如果我们调用如isPermitted(“user:view”),其首先会通过PermissionResolver把字符串转换成相应的Permission实例;

3、在进行授权之前,其会调用相应的Realm获取Subject相应的角色/权限用于匹配传入的角色/权限;

4、Authorizer会判断Realm的角色/权限是否和传入的匹配,如果有多个Realm,会委托给ModularRealmAuthorizer进行循环判断,如果匹配如isPermitted/hasRole会返回true,否则返回false表示授权失败。

上面有说到授权需要自定义的Realm继承AuthorizingRealm类,并实现doGetAuthorizationInfo方法。

doGetAuthorizationInfo方法介绍

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)

参数:PrincipalCollection

PrincipalCollection用于聚合这些身份信息

public interface PrincipalCollection extends Iterable, Serializable {  Object getPrimaryPrincipal(); //得到主要的身份  <T> T oneByType(Class<T> type); //根据身份类型获取第一个  <T> Collection<T> byType(Class<T> type); //根据身份类型获取一组  List asList(); //转换为List  Set asSet(); //转换为Set  Collection fromRealm(String realmName); //根据Realm名字获取  Set<String> getRealmNames(); //获取所有身份验证通过的Realm名字  boolean isEmpty(); //判断是否为空  }

返回值AuthorizationInfo

AuthorizationInfo用于聚合授权信息的:

public interface AuthorizationInfo extends Serializable {  Collection<String> setRoles(); //获取角色字符串信息  Collection<String> getStringPermissions(); //获取权限字符串信息  Collection<Permission> getObjectPermissions(); //获取Permission对象信息
}

一般情况下使用其子类SimpleAuthorizationInfo,设置Role和Permission并返回。

例如:

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRole(u.getRoles().getRolename());
for (Funs fun : u.getFuns()) {info.addStringPermission(fun.getFunurl());
}
return info;

apache shiro jar包_Shiro(一)相关推荐

  1. apache shiro jar包_只需要6个步骤,springboot集成shiro,并完成登录

    小Hub领读: 导入jar包,配置yml参数,编写ShiroConfig定义DefaultWebSecurityManager,重写Realm,编写controller,编写页面,一气呵成.搞定,是个 ...

  2. shiro jar包下载

    shiro是一款java安全框架,使用shiro jar包可以执行身份验证,授权,密码学和会话管理功能,如果想使用shiro这款安全框架就马上下载shiro jar包进行使用吧. 基本简介 shiro ...

  3. java org.apache.http_org.apache.http jar包下载-org.apache.http.jar包下载 --pc6下载站

    org.apache.http.jar包是一款十分常用的jar包如果没有org.apache.http.jar包Apache与http的链接将会出现错误等现象马上下载org.apache.http.j ...

  4. 使用maven引入Apache poi jar包

    maven构建的项目-->pom.xml文件 eclipse提供Dependencies直接添加依赖jar包的工具:直接搜索poi以及poi-ooxml即可,maven会自动依赖需要的jar包: ...

  5. 初识 Apache Commons jar 包

    长篇预警 ,要有耐心才能看下去 1.1. 开篇 在Java的世界,有很多(成千上万)开源的框架,有成功的,也有不那么成功的,有声名显赫的,也有默默无闻的.在我看来,成功而默默无闻的那些框架值得我们格外 ...

  6. java Apache Commons jar包简介

    一.Commons BeanUtils 说明:针对Bean的一个工具集.由于Bean往往是有一堆get和set组成,所以BeanUtils也是在此基础上进行一些包装. 二.Commons CLI 说明 ...

  7. apache shiro 如何升级_Shiro登录认证

    我们使用一个springboot+Shiro集成项目来了解一下Shiro在登录认证方面是如何运作的. 1.pom依赖添加 <dependency> <groupId>org.a ...

  8. java poi jar maven_使用maven引入Apache poi jar包

    mysql 用户管理和权限设置 用户管理 mysql>use mysql; 查看 mysql> select host,user,password from user ; 创建 mysql ...

  9. Apache Shiro第3部分–密码学

    除了保护网页和管理访问权限外, Apache Shiro还执行基本的加密任务. 该框架能够: 加密和解密数据, 哈希数据, 生成随机数. Shiro没有实现任何加密算法. 所有计算都委托给Java密码 ...

  10. Eclipse生成jar包和导入jar包

    现在常用的开发软件就是Eclipse了,因为Eclipse 是一个开放源代码的.基于Java的可扩展开发平台.它给我们封装了很多类,这些类我们可以直接拿来,使用类中的方法.尽管这些类已经很多了,但是在 ...

最新文章

  1. 最经典的计算机网络新书推荐--计算机网络(第5版)Tanenbaum著中文版上市
  2. 活学活用流行的JavaScript库——《JavaScript实战》
  3. linux写命令时方便的快捷键以及Vim必备命令
  4. Java设计模式--使用内部类实现线程安全且懒加载的单例模式
  5. 【百科】走近飞天:伏羲——资源调度服务
  6. linux Centos下磁盘分区及文件系统创建与挂载
  7. Bandicam录屏
  8. python中polyfit 之poly1d与polyval的含义
  9. RESTfull API简单项目的快速搭建
  10. 计算机应用专业招聘试讲内容,广东文艺职业学院2018年第二批合同制人员招聘专业技能考核和试讲题目...
  11. alk In Web Security(安全世界观): Devleping a Secure Wesite
  12. html动画人物走路,CSS3动画中的steps(),制作人物行走动画
  13. 操作系统OS-Lab2-FAT12文件读取
  14. 《辩证行为疗法》精华部分 + 我的理解
  15. LaTeX之双栏模板表格布局(单双栏满宽+不满宽)
  16. 带有serpstack的实时Google搜索结果API
  17. 免费学习机器学习和深度学习的源码、学习笔记和框架分享
  18. 使用PS快速抠图:(磁锁套抠图,快速工具,)
  19. 08简单推导:手机尾号评分
  20. 下一清分日期是几年前_驾驶证清分日期是什么意思?清分日期包含当天吗

热门文章

  1. 《腾讯Android自动化测试实战》— Android 书籍
  2. Linux使用CLASS_ATTR创建节点
  3. DRF之认证组件源码解析
  4. bzoj 1046: [HAOI2007]上升序列【dp+二分】
  5. TCP服务端开发为例--web开发不同url请求为何会走不同方法
  6. java hibernate状态_Hibernate对象的三种状态
  7. Windows服务器nginx多个二级域名配置多端口无效问题的解决方案
  8. Linux磁盘管理详解
  9. Linux常用命令介绍(二)——压缩与解压缩命令
  10. 跟随腾讯WeTest一起来2019Unreal Open Day!