`
y806839048
  • 浏览: 1108243 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

shiro动态修改权限,解决重启

阅读更多

 

shrio动态修改权限,解决重启

 

=====================解决重启===================

<bean id="myShiroFilterFactory" class="com.esteel.common.MyShiroFilterFactory">

<property name="filterChainDefinitions">  

       <value>  

           /admin/ = anon

/index/ = anon

/index = anon

/login = anon

/logout = logout

/getRandomValidateCode = anon

/verifyCode = anon

/admin/** = anon

 

                /main**=authc  

                /ui/info**=authc  

                /ui/listUser**=authc,perms[admin:manage]  

                /dwzIndex**=authc,perms[admin:manage]

       </value>  

   </property>  

</bean> 

 

package com.esteel.common;

 

import java.util.ArrayList;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Set;

 

import org.apache.shiro.config.Ini;

import org.apache.shiro.config.Ini.Section;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;

import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;

import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;

import org.apache.shiro.web.servlet.AbstractShiroFilter;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.BeansException;

import org.springframework.beans.factory.FactoryBean;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.context.ContextLoader;

import org.springframework.web.context.WebApplicationContext;

 

import com.esteel.system.bean.OpmMenuitem;

import com.esteel.system.bean.OpmMenuitemlimit;

import com.esteel.system.beanVo.OpmRolelimitVo;

import com.esteel.system.service.OpmMenuitemService;

import com.esteel.system.service.OpmMenuitemlimitService;

import com.esteel.system.service.OpmRolelimitService;

 

 

/**

 * 自定义shiro过滤器,初始化时从数据库读入url权限

 * 

 * @author 20005

 * @createDate 2014-7-23 上午09:38:26

 */

public class MyShiroFilterFactory  {

private static Logger logger = LoggerFactory

.getLogger(MyShiroFilterFactory.class);

    @Autowired

    private ShiroFilterFactoryBean shiroFilter;

 

 

    @Autowired

private OpmRolelimitService opmRolelimitService;

 

@Autowired

private OpmMenuitemlimitService opmMenuitemlimitService;

 

@Autowired

private OpmMenuitemService opmMenuitemService;

 

    private String filterChainDefinitions;

    

 

 

 

/**

* 初始化时加载filterChainDefinitions

*/

public MyShiroFilterFactory() {

//super();

//chainDefinitionSectionMetaSource.getObject();

// 从数据库中读入URL权限列表

//setFilterChainDefinitionMap(chainDefinitionSectionMetaSource.getObject());

//    shiroFilterFactoryBean=this;

}

 

/**

* 重新加载数据库权限

* @author 20005

* @createDate 2014-7-28 下午05:28:04

*/

public  void reloadChainDefinitions() {

WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();

//ServletContext context = getServletContext();  

//WebApplicationContext applicationContext  = WebApplicationContextUtils.getWebApplicationContext(context);

//System.out.println(myShiroFilte);

AbstractShiroFilter shiroFilter1 = null;

try {

shiroFilter1 = (AbstractShiroFilter) shiroFilter

.getObject();

} catch (Exception e) {

logger.error("getShiroFilter from shiroFilterFactoryBean error!", e);

}

 

PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter1

.getFilterChainResolver();

DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver

.getFilterChainManager();

 

// 清空老的权限控制

manager.getFilterChains().clear();

 

shiroFilter.getFilterChainDefinitionMap().clear();

try {

shiroFilter.setFilterChainDefinitionMap(getObject());

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

// 重新构建生成

Map<String, String> chains = shiroFilter

.getFilterChainDefinitionMap();

for (Map.Entry<String, String> entry : chains.entrySet()) {

String url = entry.getKey();

String chainDefinition = entry.getValue().trim().replace(" ", "");

manager.createChain(url, chainDefinition);

}

}

 

 

//    @Autowired

//    private ResourceDao resourceDao;

 

 

   /**

    * 默认premission字符串

    */

   public static final String PREMISSION_STRING="perms[\"{0}\"]";

 

   public  Section getObject() throws BeansException {

 

       //获取所有Resource

       List<OpmRolelimitVo> list =new ArrayList<OpmRolelimitVo>();

       List<OpmRolelimitVo> listAll =new ArrayList<OpmRolelimitVo>();

       list= opmRolelimitService.getRoleLimtContro();

       OpmMenuitem item = new OpmMenuitem();

       List<OpmMenuitem> items =opmMenuitemService.getMenuItems(item);

       OpmMenuitemlimit opmMenuitemlimit = new OpmMenuitemlimit();

       List<OpmMenuitemlimit> opmMenuitemlimits =opmMenuitemlimitService.getOpmMenuitemlimit(opmMenuitemlimit);

       List<OpmMenuitem> itemsb =new ArrayList<OpmMenuitem>();

       List<OpmMenuitemlimit> opmMenuitemlimitsb =new ArrayList<OpmMenuitemlimit>();

       Set<String> itms= new HashSet<String>();

       Set<String> itmls= new HashSet<String>();

       for (Iterator<OpmRolelimitVo> it1 = list.iterator(); it1.hasNext();) {

       OpmRolelimitVo resource = it1.next();

       if(resource.getMenuitemid()!=null){

           //如果不为空值添加到section中

           if(!"".equals(resource.getMenuitemid()) &&!"".equals(resource.getMenuitemid())) {

           itms.add(resource.getMenuitemid());

           }

            }

       if(resource.getMenuitemlimitid()!=null&&(resource.getMenuitemlimitid()!=null)&&!"".equals(resource.getMenuitemlimitid())){

       itmls.add(resource.getMenuitemlimitid());

       }

       }

       for(String im :itms){

       OpmMenuitem o = new OpmMenuitem();

       o.setId(im);

       itemsb.add(o);

       }

       for(String im :itmls){

       OpmMenuitemlimit o = new OpmMenuitemlimit();

       o.setId(im);

       opmMenuitemlimitsb.add(o);

       }

       items.removeAll(itemsb);

       opmMenuitemlimits.removeAll(opmMenuitemlimitsb);

       

       Ini ini = new Ini();

       //加载默认的url

       ini.load(filterChainDefinitions);

       Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);

       //循环Resource的url,逐个添加到section中。section就是filterChainDefinitionMap,

       //里面的键就是链接URL,值就是存在什么条件才能访问该链接

       Map<String,Set<String>> mapr = new HashMap<String,Set<String>>();

       Set<String> roleIds=null;

       Set<String> mlroleIds=null;

       if(list!=null&&list.size()>0){

       for(OpmRolelimitVo r :list){

       roleIds=new HashSet<String>();

           mlroleIds=new HashSet<String>();

            for (Iterator<OpmRolelimitVo> it = list.iterator(); it.hasNext();) {

       OpmRolelimitVo resource = it.next();

       if(r.getMenuitemid().equals(resource.getMenuitemid())){

           //如果不为空值添加到section中

           if(!"".equals(resource.getMenuitemid()) &&!"".equals(resource.getMenuitemid())) {

           roleIds.add(resource.getRoleid());

           }

            }

       if(r.getMenuitemlimitid()!=null&&resource.getMenuitemlimitid()!=null&&(r.getMenuitemlimitid().equals(resource.getMenuitemlimitid()))){

       mlroleIds.add(resource.getRoleid());

       }

       }

     //这里可以直接转set用section

   mapr.put(r.getMuri(), roleIds);

   mapr.put(r.getMluri(), mlroleIds);

       }

       }

       StringBuffer au=null;

       String st="";

       for(Map.Entry<String, Set<String>> en:mapr.entrySet()){

       au = new StringBuffer();

       au.append("authc,role[");

       for(String a :en.getValue()){

       au.append("\""+a+"\",");

       }

       String strau=au.substring(0,au.lastIndexOf(","));

       strau+="]";

       st+=en.getKey()+">>>>"+strau+"\n";

        section.put(en.getKey()+"**",strau);

       }

//        section.put("dwzIndex", MessageFormat.format(PREMISSION_STRING, "authc,perms[admin:manage]"));格式错了

       //

      // section.put(resource.getMenuitemid(), MessageFormat.format(PREMISSION_STRING, resource.getMenuitemid()));

//        section.put("/system/tbBasBed/list**","authc,perms[admin:manage]");

       System.out.println(st);

       for(OpmMenuitem i: items){

       section.put(i.getUri()+"**","authc,role[tempr]");

       }

       for(OpmMenuitemlimit i: opmMenuitemlimits){

       section.put(i.getUri()+"**","authc,role[tempr]");

       }

       return section;

   }

 

   /**

    * 通过filterChainDefinitions对默认的url过滤定义

    * 

    * @param filterChainDefinitions 默认的url过滤定义

    */

   public void setFilterChainDefinitions(String filterChainDefinitions) {

       this.filterChainDefinitions = filterChainDefinitions;

   }

 

   public Class<?> getObjectType() {

       return this.getClass();

   }

 

   public boolean isSingleton() {

       return false;

   }

 

}

 

@Controller

public class OpmRoleController extends BaseController {

 

 

 

@Autowired

private MyShiroFilterFactory myShiroFilterFactory;

 

@SuppressWarnings("unused")

@RequestMapping(value = "/system/opmRole/update", method = RequestMethod.POST)

public ModelAndView opmUpdate(OpmRole opmRole,HttpServletRequest request,Model modle) throws Exception {

int flag=0;

OpmMenufolder folder = new OpmMenufolder();

folder.setParentid("100000");

List<OpmMenufolder> opmMenufolders= opmMenufolderService.getOpmMenufolder(folder);

String[] a=new String[]{};

List<String> list = new ArrayList<String>();

try{

for(OpmMenufolder o: opmMenufolders){

a=request.getParameterValues(o.getId());

if(a==null||"".equals(a)){

continue;

}

list.addAll(Arrays.asList(a));

}

Map<String,Object> param = new HashMap<String,Object>();

OpmRolelimit opmLimt = new OpmRolelimit();

String org= opmRole.getOrganid();

flag = opmRoleService.updateRole(opmRole, list);

//

myShiroFilterFactory.reloadChainDefinitions();

return ajaxDoneOpm("/commonuntil/ajaxDone",200,"操作成功!","opmRoleNavUi","/system/opmRole/editUi","closeCurrent");

}catch (Exception e){

return ajaxDoneOpm("/commonuntil/ajaxDone",300,"添加失败!","opmRoleNavUi","/system/opmRole/editUi","closeCurrent");

//throw new Exception("操作失败!");

}

 

 

}

 

}

 

 

////////////////////////////////动态加载权限//////////////////////////

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

<property name="securityManager" ref="securityManager" />

<property name="loginUrl" value="/ui/login.jsp" />

<property name="successUrl" value="/ui/dwzIndex.jsp" />

<property name="unauthorizedUrl" value="/ui/accessDenied.jsp" />

<property name="filterChainDefinitionMap" ref="chainDefinitionSectionMetaSource" />   

<property name="filters">

<map>

<entry key="authc" value-ref="authenticationFilter" /> 

<entry key="role" value-ref="roleAuthorizationFilter" /> 

</map>

</property>

</bean>

    <bean id="chainDefinitionSectionMetaSource" class="com.esteel.common.ChainDefinitionSectionMetaSource">  

  

   <property name="filterChainDefinitions">  

       <value>  

           /admin/ = anon

/index/ = anon

/index = anon

/login = anon

/logout = logout

/getRandomValidateCode = anon

/verifyCode = anon

/admin/** = anon

 

                /main**=authc  

                /ui/info**=authc  

                /ui/listUser**=authc,perms[admin:manage]  

                /dwzIndex**=authc,perms[admin:manage]

       </value>  

   </property>  

   </bean>   

 

 

 

 

package com.esteel.common;

 

import java.util.ArrayList;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Set;

 

import org.apache.shiro.config.Ini;

import org.apache.shiro.config.Ini.Section;

import org.springframework.beans.BeansException;

import org.springframework.beans.factory.FactoryBean;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import org.springframework.stereotype.Controller;

 

import com.esteel.system.bean.OpmMenuitem;

import com.esteel.system.bean.OpmMenuitemlimit;

import com.esteel.system.beanVo.OpmRolelimitVo;

import com.esteel.system.service.OpmMenuitemService;

import com.esteel.system.service.OpmMenuitemlimitService;

import com.esteel.system.service.OpmRolelimitService;

 

public class ChainDefinitionSectionMetaSource implements FactoryBean<Ini.Section>{

 

//    @Autowired

//    private ResourceDao resourceDao;

@Autowired

private OpmRolelimitService opmRolelimitService;

 

@Autowired

private OpmMenuitemlimitService opmMenuitemlimitService;

 

@Autowired

private OpmMenuitemService opmMenuitemService;

 

    private String filterChainDefinitions;

    

 

    /**

     * 默认premission字符串

     */

    public static final String PREMISSION_STRING="perms[\"{0}\"]";

 

    public Section getObject() throws BeansException {

 

        //获取所有Resource

        List<OpmRolelimitVo> list =new ArrayList<OpmRolelimitVo>();

        List<OpmRolelimitVo> listAll =new ArrayList<OpmRolelimitVo>();

        list= opmRolelimitService.getRoleLimtContro();

        OpmMenuitem item = new OpmMenuitem();

        List<OpmMenuitem> items =opmMenuitemService.getMenuItems(item);

        OpmMenuitemlimit opmMenuitemlimit = new OpmMenuitemlimit();

        List<OpmMenuitemlimit> opmMenuitemlimits =opmMenuitemlimitService.getOpmMenuitemlimit(opmMenuitemlimit);

        List<OpmMenuitem> itemsb =new ArrayList<OpmMenuitem>();

        List<OpmMenuitemlimit> opmMenuitemlimitsb =new ArrayList<OpmMenuitemlimit>();

        Set<String> itms= new HashSet<String>();

        Set<String> itmls= new HashSet<String>();

        for (Iterator<OpmRolelimitVo> it1 = list.iterator(); it1.hasNext();) {

        OpmRolelimitVo resource = it1.next();

        if(resource.getMenuitemid()!=null){

            //如果不为空值添加到section中

            if(!"".equals(resource.getMenuitemid()) &&!"".equals(resource.getMenuitemid())) {

            itms.add(resource.getMenuitemid());

            }

             }

        if(resource.getMenuitemlimitid()!=null&&(resource.getMenuitemlimitid()!=null)&&!"".equals(resource.getMenuitemlimitid())){

        itmls.add(resource.getMenuitemlimitid());

        }

        }

        for(String im :itms){

        OpmMenuitem o = new OpmMenuitem();

        o.setId(im);

        itemsb.add(o);

        }

        for(String im :itmls){

        OpmMenuitemlimit o = new OpmMenuitemlimit();

        o.setId(im);

        opmMenuitemlimitsb.add(o);

        }

        items.removeAll(itemsb);

        opmMenuitemlimits.removeAll(opmMenuitemlimitsb);

        

        Ini ini = new Ini();

        //加载默认的url

        ini.load(filterChainDefinitions);

        Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);

        //循环Resource的url,逐个添加到section中。section就是filterChainDefinitionMap,

        //里面的键就是链接URL,值就是存在什么条件才能访问该链接

        Map<String,Set<String>> mapr = new HashMap<String,Set<String>>();

        Set<String> roleIds=null;

        Set<String> mlroleIds=null;

        if(list!=null&&list.size()>0){

        for(OpmRolelimitVo r :list){

        roleIds=new HashSet<String>();

            mlroleIds=new HashSet<String>();

             for (Iterator<OpmRolelimitVo> it = list.iterator(); it.hasNext();) {

        OpmRolelimitVo resource = it.next();

        if(r.getMenuitemid().equals(resource.getMenuitemid())){

            //如果不为空值添加到section中

            if(!"".equals(resource.getMenuitemid()) &&!"".equals(resource.getMenuitemid())) {

            roleIds.add(resource.getRoleid());

            }

             }

        if(r.getMenuitemlimitid()!=null&&resource.getMenuitemlimitid()!=null&&(r.getMenuitemlimitid().equals(resource.getMenuitemlimitid()))){

        mlroleIds.add(resource.getRoleid());

        }

        }

      //这里可以直接转set用section

    mapr.put(r.getMuri(), roleIds);

    mapr.put(r.getMluri(), mlroleIds);

        }

        }

        StringBuffer au=null;

        String st="";

        for(Map.Entry<String, Set<String>> en:mapr.entrySet()){

        au = new StringBuffer();

        au.append("authc,role[");

        for(String a :en.getValue()){

        au.append("\""+a+"\",");

        }

        String strau=au.substring(0,au.lastIndexOf(","));

        strau+="]";

        st+=en.getKey()+">>>>"+strau+"\n";

         section.put(en.getKey()+"**",strau);

        }

//        section.put("dwzIndex", MessageFormat.format(PREMISSION_STRING, "authc,perms[admin:manage]"));格式错了

        //

       // section.put(resource.getMenuitemid(), MessageFormat.format(PREMISSION_STRING, resource.getMenuitemid()));

//        section.put("/system/tbBasBed/list**","authc,perms[admin:manage]");

        System.out.println(st);

        for(OpmMenuitem i: items){

        section.put(i.getUri()+"**","authc,role[tempr]");

        }

        for(OpmMenuitemlimit i: opmMenuitemlimits){

        section.put(i.getUri()+"**","authc,role[tempr]");

        }

        return section;

    }

 

    /**

     * 通过filterChainDefinitions对默认的url过滤定义

     * 

     * @param filterChainDefinitions 默认的url过滤定义

     */

    public void setFilterChainDefinitions(String filterChainDefinitions) {

        this.filterChainDefinitions = filterChainDefinitions;

    }

 

    public Class<?> getObjectType() {

        return this.getClass();

    }

 

    public boolean isSingleton() {

        return false;

    }

 

}

 

 

分享到:
评论

相关推荐

    shiro管理端权限控制

    5. **动态权限控制**:Shiro 允许在运行时动态调整权限,例如在管理后台,管理员可以实时修改用户的权限,这些变更会立即生效,无需重启服务。 6. **会话管理**:Shiro 提供了强大的会话管理机制,可以跨服务器共享...

    SSM+Maven+Mysql+shiro无需重启动态权限

    "SSM+Maven+Mysql+Shiro无需重启动态权限"项目就是一个典型的示例,它整合了Spring、SpringMVC、Mybatis(SSM)这三大Java开发框架,并结合Maven进行项目管理和Mysql数据库存储数据,再利用Apache Shiro实现安全控制...

    动态添加权限管理

    动态添加权限管理则是一种灵活的解决方案,它允许管理员在系统运行时根据需要添加、修改或删除用户的权限,而无需重启服务。这里我们将深入探讨如何使用Spring、SpringMVC、MyBatis和EasyUI这四大组件来实现这一功能...

    基于Maven+SSM整合shiro+Redis实现后台管理项目

    这样做不仅可以解决分布式环境下的session共享问题,还能通过Redis的持久化机制,保证数据在服务器重启后不会丢失。 在项目结构上,通常会包含以下模块:用户模块(处理用户注册、登录、权限管理等)、系统设置模块...

    shiro+SpringMVC+Spring+mybatis+maven+mybatis 自动刷新xml

    **自动刷新XML** 是指在项目运行时,当MyBatis的XML配置文件被修改后,无需重启应用服务器,更改就能立即生效。这通常通过监听文件系统变化,如使用Spring的FileSystemWatcher或者第三方库实现。这种功能提高了开发...

    shiro文件 搭建攻防演练演示环境 解压后放入tomcat的webpass目录下即可

    6. **启动Tomcat**:启动或重启Tomcat服务,让更改生效。在命令行中,你可以运行`bin/startup.sh`(Unix/Linux)或`bin/startup.bat`(Windows)。 7. **模拟攻击**:现在环境已经准备就绪,你可以使用各种工具,如...

    xmwl-admin-bx.rar

    此外,通过Spring Cloud Config,系统实现了配置的集中管理和动态更新,使得开发者可以在不重启服务的情况下修改配置,增强了系统的灵活性。 项目中可能包含以下关键模块: 1. 用户模块:负责用户注册、登录以及...

    10_传智播客巴巴运动网_权限管理模块分析

    9. **权限动态调整**:系统应支持权限的动态调整,例如,管理员可以在运行时添加、删除或修改用户的权限,而不必重启服务。 10. **审计日志**:记录用户的操作行为和权限变更,有助于追踪异常活动和审计合规性。 ...

    RBAC.docx

    例如,一个系统管理员角色可能拥有添加、删除和修改用户的权限,而普通用户角色可能只有查看信息的权限。在实际应用中,如Ztree插件,可以利用jQuery实现多功能树结构,用于角色权限的管理。角色中包含一系列权限...

    jeecms v6修改后台地址

    同时,修改配置后记得重启Jeecms应用服务器,使改动生效。在测试阶段,要确保所有后台功能都能正常工作,没有因为路径改变而引发的问题。 总的来说,Jeecms后台路径的修改涉及多个层面的配置,需要对Web应用的运行...

    ssmdemo:后台权限管理Demo练习

    "ssmdemo"可能支持动态权限配置,允许管理员在运行时调整用户的权限,而无需重启服务。 7. **安全性考虑**:除了基本的认证和授权,"ssmdemo"可能还涉及防止SQL注入、XSS攻击等安全措施,以增强系统的整体安全性。 ...

    mysiteforme:mysiteforme权限管理系统是作者学习springBoot时基于springBoot开发的一套轻量级的系统的脚手架,可以逐步形成一套属于自己的系统后台,自动生成前后台基本代码;使用Spring Boot,Shiro,MyBatis,Layui等框架,包含:用户管理,角色管理,权限管理,资源管理,数据库管理,子系统生成,调度管理等

    然后获取密钥,更新到你的配置文件中()旧版配置文件util/QiniuFileUtil主要功能系统用户,角色,权限增删改查,权限分配,权限配色文件上传可自由选择本地存储,七牛云存储,阿里云存储系统字典配置网站基本信息,...

    jeecmsv6如何修改后台访问地址[参考].pdf

    - 修改完成后,请确保重启服务器,使更改生效。 - 在修改前最好备份相关文件,以防万一修改失败可以快速恢复。 - 测试修改后的功能是否正常运行,尤其是登录、注销等关键操作。 - 如果项目中还涉及到了其他与路径...

    Java EE常用框架.xmind

    而我们的Shiro实现系统的权限管理,有效提高开发效率,从而降低开发成本。 粗粒度和细粒度权限 粗粒度权限管理比如:超级管理员可以访问户添加页面、用户信息等全部页面。部门管理员可以访问用户信息页面...

    开发过程遇到的问题.doc

    - 更新或调整Tomcat的server.xml配置文件,可以更改端口设置、增加或修改服务器的行为。 4. **安卓BUG处理**: 安卓应用开发中,遇到BUG需要通过日志追踪、调试器或者使用Android Studio的调试工具进行定位和修复...

    基于vue-element-admin和springboot搭建的管理后台项目开发脚手架源码+数据库+项目说明.zip

    - 使用Gradle持续构建特性,开发时修改java代码无需重启 - 使用vue-element-admin做前端模板,摆脱写jQuery的痛苦 - 多种灵活形式的前后端分离方式,包括开发阶段的前后端分离和部署的前后端分离 请先安装好依赖的...

    基于SpringBoot的企业资产管理系统源码数据库.zip

    SpringBoot支持热部署,开发过程中修改代码后无需重启服务器。生产环境中,可以通过Docker容器化部署,提高资源利用率和部署效率。日志管理和监控则可借助SpringBoot Actuator进行。 总结,基于SpringBoot的企业...

    软件开发工程师简历模板

    - 功能:视频上墙、画面切换、分辨率修改、日志查看、重启和恢复出厂设置 以上项目经验展示了求职者在Java开发领域的深厚基础,以及在大数据处理和Web应用开发上的实践经验。对于寻求Java或大数据开发岗位的求职者...

    Smart Admin通用型中后台解决方案-其他

    哪些人在偷偷的跑你的Job11、自定义的quartz job添加和修改,方便测试人员测试12、smart-reload,为系统预留钩子,动态加载,在不重启程序前提下执行一些代码,你懂的13、其他功能:邮件、富文本、消息、系统配置...

Global site tag (gtag.js) - Google Analytics