LDAP 验证、添加、修改、删除(转)

1. 域服务器(dc=dctest,dc=com),安装证书服务,创建企业根证书,名称为dctest.com

   则:cn=dctest.com,dc=dctest,dc=com

2. 申请证书类型域控制器的证书

3. 将企业根证书和域控制器证书导入到应用服务器cacerts

4. 在应用程序中,编写代码引用cacerts认证。

keytool

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. package  bof.usermanager.auth.impl;  
  2. import  java.io.IOException;  
  3. import  java.util.ArrayList;  
  4. import  java.util.List;  
  5. import  java.util.Properties;  
  6. import  javax.naming.AuthenticationException;  
  7. import  javax.naming.Context;  
  8. import  javax.naming.NamingEnumeration;  
  9. import  javax.naming.NamingException;  
  10. import  javax.naming.directory.Attribute;  
  11. import  javax.naming.directory.Attributes;  
  12. import  javax.naming.directory.BasicAttribute;  
  13. import  javax.naming.directory.BasicAttributes;  
  14. import  javax.naming.directory.DirContext;  
  15. import  javax.naming.directory.ModificationItem;  
  16. import  javax.naming.directory.SearchControls;  
  17. import  javax.naming.directory.SearchResult;  
  18. import  javax.naming.ldap.Control;  
  19. import  javax.naming.ldap.InitialLdapContext;  
  20. import  javax.naming.ldap.LdapContext;  
  21. import  com.report.service.PropertyItem;  
  22. import  com.report.vo.OrganizationalUnitDomain;  
  23. import  com.report.vo.UserDomain;  
  24. /**  
  25.  * 功能:本操作类提供AD域用户的增、删、查、改功能  
  26.  * 作者:陈艺武  
  27.  * 日期:2010-4-13  
  28.  */   
  29. public   class  LdapADManager {  
  30.       
  31.     protected  DataSourceConnectLDAPVO transientInstance =  null ;  
  32.       
  33.     /** 用户的objectClass*/   
  34.     private  String default_objectclass =  "user" ;  
  35.     /**用户的默认根DN*/   
  36.     private  String default_base =  "CN=Users,DC=all,DC=com" ;  
  37.     /** 用户默认主键*/   
  38.     private  String key_index =  "CN" ;  
  39.     /** 用户默认密码属性.*/   
  40.     private  String pwd_index =  "unicodePwd" ;  
  41.     private  Control[] connCtls =  null ;  
  42.       
  43.     private   static  LdapADManager LdapADManager =  null ;  
  44.       
  45.     private  LdapADManager(){}  
  46.     public   static  LdapADManager getInstance(){  
  47.         if (LdapADManager== null )  
  48.             LdapADManager = new  LdapADManager();  
  49.         return  LdapADManager;         
  50.     }  
  51.       
  52.       
  53.       
  54.       
  55.     /**    
  56.      * 从连接池中获取一个连接.    
  57.      *     
  58.      * @return LdapContext    
  59.      * @throws NamingException    
  60.      */     
  61.     public  LdapContext getConnectionFromFool()  throws  NamingException {     
  62.         PropertyItem ldapProperty  = (PropertyItem)AdProperties.getInstance().getPropertyItem().get(0 );  
  63.         String keystore = "c:/Java/jdk1.6.0_10/jre/lib/security/cacerts" ;     
  64.         System.setProperty("javax.net.ssl.trustStore" , keystore);     
  65.           
  66.         Properties env = new  Properties();     
  67.         env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory" );    
  68.         env.put("com.sun.jndi.ldap.connect.pool""true" );    
  69.         env.put(Context.SECURITY_AUTHENTICATION, "simple" );  
  70.         env.put(Context.SECURITY_PROTOCOL, "ssl" );  
  71.         //env.put("java.naming.referral", "follow");   
  72.           
  73.         env.put(Context.PROVIDER_URL, ldapProperty.getLdapURL());         
  74.         connCtls = new  Control[] {  new  LdapADManagerControl() };  
  75.         return   new  InitialLdapContext(env, connCtls);     
  76.     }    
  77.       
  78.       
  79.        
  80.     /**  
  81.      * 功能:校验用户登录.  
  82.      * @param userName  
  83.      * @param password  
  84.      * @return  
  85.      *  
  86.      * 作者:陈艺武  
  87.      * 日期:Apr 13, 2010  
  88.      */   
  89.     public   boolean  authenticate(String userName, String password) {    
  90.         PropertyItem ldapProperty  = (PropertyItem)AdProperties.getInstance().getPropertyItem().get(0 );  
  91.         String userDn = userName + "@"  + ldapProperty.getDomain();  
  92.         LdapContext ctx = null ;     
  93.         try  {     
  94.             ctx = getConnectionFromFool();     
  95.             ctx.getRequestControls();      
  96.             ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDn);  
  97.             ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);     
  98.             ctx.reconnect(connCtls);     
  99.             return   true ;     
  100.         } catch  (AuthenticationException e) {     
  101.             e.printStackTrace();  
  102.             return   false ;     
  103.         } catch  (NamingException e) {  
  104.             e.printStackTrace();  
  105.             return   false ;     
  106.         } finally  {     
  107.                 try  {  
  108.                     ctx.close();     
  109.                 } catch  (Exception e){  
  110.                     e.printStackTrace();     
  111.                 }      
  112.          }     
  113.      }     
  114.       
  115.       
  116.       
  117.     /**  
  118.      * 功能:获取AD用户列表  
  119.      * @return  
  120.      *  
  121.      * 作者:陈艺武  
  122.      * 日期:Apr 12, 2010  
  123.      */   
  124.     public  List listUser(){  
  125.         PropertyItem ldapProperty  = (PropertyItem)AdProperties.getInstance().getPropertyItem().get(0 );  
  126.         List list = new  ArrayList();  
  127.         LdapContext ctx = null ;  
  128.         UserDomain user=null ;  
  129.           
  130.         String base = "OU="  + ldapProperty.getBase() +  ","  + ldapProperty.getDomainDC();  
  131.         try {  
  132.             ctx = this .getConnectionFromFool();  
  133.             ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, ldapProperty.getUserName() + "@"  + ldapProperty.getDomain());  
  134.             ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, ldapProperty.getPassWord());  
  135.               
  136.             //base = "OU=北京华融综合投资公司,DC=bjhr,DC=com,DC=cn";   
  137.             String filter = "(&(objectCategory=person)(objectClass=USER)(name=*))" ;  
  138.             SearchControls controls = new  SearchControls();  
  139.             controls.setSearchScope(SearchControls.SUBTREE_SCOPE);  
  140.             //controls.setReturningAttributes(new String[] {"sAMAccountName", "displayName", "department"});   
  141.             controls.setReturningAttributes(new  String[] { "sAMAccountName""cn" });  
  142.                
  143.             NamingEnumeration<SearchResult> answer = ctx.search(base, filter, controls);  
  144.             while  (answer.hasMore()) {  
  145.                 user=new  UserDomain();  
  146.                 SearchResult result = answer.next();  
  147.                 NamingEnumeration<? extends  Attribute> attrs = result.getAttributes().getAll();  
  148.                 int  count= 0 ;  
  149.           
  150.                 while  (attrs.hasMore()) {  
  151.                     Attribute attr = attrs.next();  
  152.                     if (count== 0 ){  
  153.                         user.setUserName(attr.get().toString());  
  154.                     }else {  
  155.                         user.setUserAliasName(attr.get().toString());  
  156.                     }  
  157.                     count++;  
  158.                 }  
  159.                   
  160.                 user.setNameSpace(ldapProperty.getDomain());  
  161.                 list.add(user);  
  162.             }  
  163.         }catch (Exception e){  
  164.             e.printStackTrace();  
  165.         } finally  {     
  166.             try  {  
  167.                 ctx.close();     
  168.             } catch  (Exception e){  
  169.                 e.printStackTrace();     
  170.             }      
  171.         }   
  172.         return  list;  
  173.     }  
  174.       
  175.       
  176.       
  177.     /**  
  178.      * 功能:查询组织单位列表  
  179.      * @param ouName  
  180.      * @return  
  181.      *  
  182.      * 作者:陈艺武  
  183.      * 日期:Apr 13, 2010  
  184.      * 说明:base格式如:"OU=北京华融综合投资公司,DC=bjhr,DC=com,DC=cn";  
  185.      */   
  186.     public  List listOrganizztionalUnit(String ouName){  
  187.         PropertyItem ldapProperty  = (PropertyItem)AdProperties.getInstance().getPropertyItem().get(0 );  
  188.         List list = new  ArrayList();  
  189.         LdapContext ctx = null ;  
  190.         OrganizationalUnitDomain ouDomain = null ;  
  191.           
  192.         String base = "OU="  + ldapProperty.getBase() +  ","  + ldapProperty.getDomainDC();  
  193.         try {  
  194.             ctx = this .getConnectionFromFool();  
  195.             ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, ldapProperty.getUserName() + "@"  + ldapProperty.getDomain());  
  196.             ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, ldapProperty.getPassWord());  
  197.               
  198.             String filter = "(&(objectClass=organizationalUnit)" ;  
  199.             if (ouName!= null &&!ouName.equals( "" ))  
  200.                 filter = filter + "(name=*"  + ouName +  "*)" ;  
  201.             filter = filter + ")" ;  
  202.               
  203.             SearchControls controls = new  SearchControls();  
  204.             controls.setSearchScope(SearchControls.SUBTREE_SCOPE);  
  205.             controls.setReturningAttributes(new  String[] { "name" });  
  206.                
  207.             NamingEnumeration<SearchResult> answer = ctx.search(base, filter, controls);  
  208.             while  (answer.hasMore()) {  
  209.                 ouDomain = new  OrganizationalUnitDomain();  
  210.                 SearchResult result = answer.next();  
  211.                 NamingEnumeration<? extends  Attribute> attrs = result.getAttributes().getAll();  
  212.                 int  count= 0 ;  
  213.           
  214.                 while  (attrs.hasMore()) {  
  215.                     Attribute attr = attrs.next();  
  216.                     if (count== 0 ){  
  217.                         ouDomain.setOuName(attr.get().toString());  
  218.                     }  
  219.                     count++;  
  220.                 }  
  221.                   
  222.                 list.add(ouDomain);  
  223.             }  
  224.         }catch (Exception e){  
  225.             e.printStackTrace();  
  226.         } finally  {     
  227.             try  {  
  228.                 ctx.close();     
  229.             } catch  (Exception e){  
  230.                 e.printStackTrace();     
  231.             }      
  232.         }   
  233.         return  list;  
  234.     }  
  235.       
  236.       
  237.     /**  
  238.      * 功能:添加用户  
  239.      * @param ou    组织单位:中投证券,销售部门  
  240.      * @param department  
  241.      * @param realName  真实姓名,如:李伟  
  242.      * @param userName  用户名,如:administrator  
  243.      * @param userPwd  
  244.      * @param adminUser  
  245.      * @param adminPwd  
  246.      * @return  
  247.      *  
  248.      * 作者:陈艺武  
  249.      * 日期:Apr 12, 2010  
  250.      */   
  251.     public   boolean  addUser(String ou,String department,String realName, String userName, String adminUser,String adminPwd) {     
  252.         PropertyItem ldapProperty  = (PropertyItem)AdProperties.getInstance().getPropertyItem().get(0 );  
  253.         LdapContext ctx = null ;     
  254.         try  {     
  255.             ctx = getConnectionFromFool();  
  256.              
  257.             Attributes attrs = new  BasicAttributes( true );     
  258.             Attribute objclass = new  BasicAttribute( "objectclass" );   
  259.             setObjectclassToAttribute(objclass);  
  260.             attrs.put(objclass);  
  261.             attrs.put("sAMAccountName" , userName);     
  262.             attrs.put("cn" , realName);     
  263.               
  264.             int  UF_ACCOUNTDISABLE =  0x0002 ;     
  265.             int  UF_PASSWD_NOTREQD =  0x0020 ;     
  266.             int  UF_NORMAL_ACCOUNT =  0x0200 ;     
  267.             int  UF_PASSWORD_EXPIRED =  0x800000 ;  
  268.             attrs.put("userAccountControl" , Integer.toString(UF_NORMAL_ACCOUNT + UF_PASSWD_NOTREQD + UF_PASSWORD_EXPIRED + UF_ACCOUNTDISABLE));      
  269.               
  270.               
  271.             ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, adminUser + "@"  + ldapProperty.getDomain());  
  272.             ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, adminPwd);  
  273.             //String newUser = "CN="+realName+"," + cvtOuString(ou) + "," + ldapProperty.getDomainDC();   
  274.             String newUser = "CN=" +realName+ ","  +  this .getFullOu(ctx, ou) +  ","  + ldapProperty.getDomainDC();  
  275.             ctx.createSubcontext(newUser, attrs);    
  276.               
  277.             ModificationItem[] mods = new  ModificationItem[ 2 ];      
  278.             String newQuotedPassword = "\""  + userName +  "\"" ;     
  279.             byte [] newUnicodePassword = newQuotedPassword.getBytes( "UTF-16LE" );     
  280.             mods[0 ] =  new  ModificationItem(DirContext.REPLACE_ATTRIBUTE, new  BasicAttribute( "unicodePwd" , newUnicodePassword));     
  281.             mods[1 ] =  new  ModificationItem(DirContext.REPLACE_ATTRIBUTE, new  BasicAttribute( "userAccountControl" , Integer.toString(UF_NORMAL_ACCOUNT + UF_PASSWORD_EXPIRED)));     
  282.             ctx.modifyAttributes(newUser, mods);     
  283.             mods = null ;     
  284.             return   true ;     
  285.         } catch  (NamingException e) {     
  286.             e.printStackTrace();     
  287.         } catch  (IOException e) {     
  288.             e.printStackTrace();     
  289.         }finally {     
  290.             if (ctx !=  null ){     
  291.                 try {     
  292.                     ctx.close();     
  293.                 }catch (NamingException e){     
  294.                     e.printStackTrace();     
  295.                 }     
  296.                 ctx = null ;     
  297.             }     
  298.         }     
  299.         return   false ;     
  300.     }    
  301.       
  302.       
  303.       
  304.      /**  
  305.      * 功能:管理员用户初始化用户密码  
  306.      * @param sUserName  
  307.      * @param sNewPassword  
  308.      * @return  
  309.      *  
  310.      * 作者:陈艺武  
  311.      * 日期:Apr 13, 2010  
  312.      */   
  313.     public   boolean  adminChangePassword(String adminUser,String adminPwd,String sUserName){       
  314.          PropertyItem ldapProperty  = (PropertyItem)AdProperties.getInstance().getPropertyItem().get(0 );  
  315.          LdapContext ctx = null ;    
  316.            
  317.         //不能从应用中修改超级管理员密码   
  318.          if (sUserName!= null &&sUserName.equalsIgnoreCase( "administrator" ))  
  319.              return   false ;  
  320.          try  {         
  321.              ctx = getConnectionFromFool();  
  322.              ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, adminUser + "@"  + ldapProperty.getDomain());  
  323.              ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, adminPwd);  
  324.                
  325.              ModificationItem[] mods = new  ModificationItem[ 1 ];            
  326.              String newQuotedPassword = "\""  + sUserName +  "\"" ;              
  327.              byte [] newUnicodePassword = newQuotedPassword.getBytes( "UTF-16LE" );               
  328.              mods[0 ] =  new  ModificationItem(DirContext.REPLACE_ATTRIBUTE, new  BasicAttribute( "unicodePwd" , newUnicodePassword));               
  329.              String cnUser = getUser(ctx,sUserName) + ","  + ldapProperty.getDomainDC();  
  330.              ctx.modifyAttributes(cnUser, mods);                          
  331.              return   true ;          
  332.          }catch (Exception e){              
  333.              e.printStackTrace();    
  334.         } finally  {     
  335.             try  {  
  336.                 ctx.close();     
  337.             } catch  (Exception e){  
  338.                 e.printStackTrace();     
  339.             }      
  340.         }           
  341.          return   false ;      
  342.      }          
  343.        
  344.        
  345.        
  346.      /**  
  347.      * 功能:用户修改密码  
  348.      * @param sUserName  
  349.      * @param sOldPassword  
  350.      * @param sNewPassword  
  351.      * @return  
  352.      *  
  353.      * 作者:陈艺武  
  354.      * 日期:Apr 9, 2010  
  355.      */   
  356.     public   boolean  userChangePassword(String sUserName, String sOldPassword, String sNewPassword){      
  357.          PropertyItem ldapProperty  = (PropertyItem)AdProperties.getInstance().getPropertyItem().get(0 );  
  358.          LdapContext ctx = null ;    
  359.          String userNameAndDomain = sUserName + "@"  + ldapProperty.getDomain();  
  360.            
  361.          //不能从应用中修改超级管理员密码   
  362.          if (sUserName!= null &&sUserName.equalsIgnoreCase( "administrator" ))  
  363.              return   false ;  
  364.          try  {  
  365.              ctx = getConnectionFromFool();  
  366.              ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userNameAndDomain);  
  367.              ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, sOldPassword);     
  368.                
  369.              ModificationItem[] mods = new  ModificationItem[ 2 ];                          
  370.              String oldQuotedPassword = "\""  + sOldPassword +  "\"" ;              
  371.              byte [] oldUnicodePassword = oldQuotedPassword.getBytes( "UTF-16LE" );              
  372.              String newQuotedPassword = "\""  + sNewPassword +  "\"" ;              
  373.              byte [] newUnicodePassword = newQuotedPassword.getBytes( "UTF-16LE" );                      
  374.              mods[0 ] =  new  ModificationItem(DirContext.REMOVE_ATTRIBUTE, new  BasicAttribute( "unicodePwd" , oldUnicodePassword));              
  375.              mods[1 ] =  new  ModificationItem(DirContext.ADD_ATTRIBUTE, new  BasicAttribute( "unicodePwd" , newUnicodePassword));               
  376.                
  377.              String cnUser = getUser(ctx,sUserName) + ","  + ldapProperty.getDomainDC();  
  378.              ctx.modifyAttributes(cnUser, mods);                               
  379.              return   true ;           
  380.          }catch ( Exception e){              
  381.              e.printStackTrace();                    
  382.          }finally {  
  383.              try {  
  384.                  ctx.close();  
  385.              }catch (Exception e){  
  386.                  e.printStackTrace();  
  387.              }  
  388.          }  
  389.          return   false ;      
  390.    }  
  391.           
  392.       
  393.       
  394.       
  395.     /**  
  396.      * 功能:修改用户信息  
  397.      * @param attrs  
  398.      * @param userDN  
  399.      * @return  
  400.      *  
  401.      * 作者:陈艺武  
  402.      * 日期:Apr 12, 2010  
  403.      */   
  404.     public   boolean  modify(Attributes attrs, String userDN) {  
  405.         LdapContext ctx = null ;     
  406.         try  {     
  407.             ctx = getConnectionFromFool();     
  408.             attrs.remove(key_index);     
  409.             ctx.modifyAttributes(userDN, DirContext.REPLACE_ATTRIBUTE, attrs);     
  410.             return   true ;     
  411.         } catch  (NamingException e) {     
  412.             System.err.println("Problem changing password: "  + e);     
  413.         } catch  (Exception e) {     
  414.             System.err.println("Problem: "  + e);     
  415.         } finally  {       
  416.                 try  {     
  417.                     ctx.close();     
  418.                 } catch  (Exception e) {     
  419.                     e.printStackTrace();     
  420.                 }     
  421.                 
  422.         }     
  423.         return   false ;     
  424.     }    
  425.       
  426.       
  427.     /**  
  428.      * 功能:删除用户  
  429.      * @param adminUser  
  430.      * @param adminPwd  
  431.      * @param userDN        用户登陆名  
  432.      * @return  
  433.      *  
  434.      * 作者:陈艺武  
  435.      * 日期:Apr 12, 2010  
  436.      */   
  437.     public   boolean  del(String adminUser,String adminPwd,String userName) {     
  438.         PropertyItem ldapProperty  = (PropertyItem)AdProperties.getInstance().getPropertyItem().get(0 );  
  439.         LdapContext ctx = null ;     
  440.           
  441.         try  {     
  442.             ctx = getConnectionFromFool();     
  443.             ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, adminUser + "@"  + ldapProperty.getDomain());  
  444.             ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, adminPwd);  
  445.             String adUser = getUser(ctx,userName) + ","  + ldapProperty.getDomainDC();  
  446.               
  447.             ctx.destroySubcontext(adUser);     
  448.             return   true ;     
  449.         } catch  (NamingException e) {     
  450.             System.err.println("Problem changing password: "  + e);     
  451.         } catch  (Exception e) {     
  452.             System.err.println("Problem: "  + e);     
  453.         } finally  {       
  454.                 try  {     
  455.                     ctx.close();     
  456.                 } catch  (Exception e) {     
  457.                     e.printStackTrace();     
  458.                 }     
  459.                   
  460.         }     
  461.         return   false ;     
  462.     }    
  463.       
  464.       
  465.       
  466.       
  467.       
  468.     private   void  setObjectclassToAttribute(Attribute objclass){  
  469.         objclass.add("top" );   
  470.         objclass.add("person" );   
  471.         objclass.add("organizationalPerson" );   
  472.         objclass.add("inetorgperson" );   
  473.     }  
  474.       
  475.       
  476.     private  String getUser(LdapContext ctx,String usr){  
  477.         String userName = "" ;  
  478.         String filter = "sAMAccountName=" +usr;  
  479.         SearchResult si = getSearchResult(ctx,filter);  
  480.         if (si!= null )   
  481.             userName = si.getName();  
  482.         return  userName;  
  483.     }  
  484.       
  485.       
  486.     private  String getFullOu(LdapContext ctx,String ou){  
  487.         String userName = "" ;  
  488.         String filter = "(&(objectClass=organizationalUnit)(name="  + ou +  "))" ;  
  489.         SearchResult si = getSearchResult(ctx,filter);  
  490.         if (si!= null )   
  491.             userName = si.getName();  
  492.         return  userName;  
  493.     }  
  494.       
  495.       
  496.     private  SearchResult getSearchResult(LdapContext ctx,String filter){  
  497.         SearchResult si = null ;  
  498.         PropertyItem ldapProperty  = (PropertyItem)AdProperties.getInstance().getPropertyItem().get(0 );  
  499.         try  {  
  500.             SearchControls constraints = new  SearchControls();  
  501.             co<mce:script type="text/javascript"  src= "http://hi.images.csdn.net/js/blog/tiny_mce/themes/advanced/langs/zh.js"  mce_src= "http://hi.images.csdn.net/js/blog/tiny_mce/themes/advanced/langs/zh.js" ></mce:script><mce:script type= "text/javascript"  src= "http://hi.images.csdn.net/js/blog/tiny_mce/plugins/syntaxhl/langs/zh.js"  mce_src= "http://hi.images.csdn.net/js/blog/tiny_mce/plugins/syntaxhl/langs/zh.js" ></mce:script>nstraints.setSearchScope(SearchControls.SUBTREE_SCOPE);  
  502.             NamingEnumeration en = ctx.search(ldapProperty.getDomainDC(), filter , constraints); // 查询所有用户   
  503.              
  504.             while (en!=  null &&en.hasMoreElements()){  
  505.                 Object obj = en.nextElement();  
  506.                 if  (obj  instanceof  SearchResult) {  
  507.                     si = (SearchResult)obj;  
  508.                     break ;  
  509.                 }  
  510.             }  
  511.         }catch  (NamingException ex) {  
  512.             ex.printStackTrace();  
  513.         }  
  514.         return  si;  
  515.     }  
  516. }  
  517. class  LdapADManagerControl  implements  Control {      
  518.     public   byte [] getEncodedValue() {  
  519.         return   null ;      
  520.     }      
  521.     public  String getID() {          
  522.         return   "1.2.840.113556.1.4.1781" ;      
  523.     }      
  524.     public   boolean  isCritical() {          
  525.         return   true
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值