Springecurity2.0.4+OpenID完整配置攻略_spring框架固定openid-程序员宅基地

技术标签: Java  openjweb  spring security  openid  

Spring Security2.04+OpenID配置攻略

 

 

 

 

 

 

目 录

 

1.QQ互联中的OpenID 3

配置环境 3

3、 Spring Securityxml配置 3

4、 OpenID登录页 17

5、 申请OpenID 账号 17

6、 在本地登录OpenID 18

7、 其他注意事项 19

 


1.QQ互联中的OpenID

    QQ 互联接口中,在QQ登陆成功后,会返回一个OpenID,但是此OpenID是一个大写字母和数字的组合。与一般的OpenID的格式不同,正常的OpenID应该是http开头的URL格式,例如http://zhangsan.openid.org.cn/ ,本文介绍的是国际通用的OpenID认证协议+Spring Security配置过程。

2.配置环境

本文的介绍的配置过程是在OpenJWeb2.63环境下配置的,OpenJWeb2.63集成了S2SHSpring Security2.0.4,大家也可以自己搭建一个S2SH+Spring Security2.04的环境,在环境搭建好以后,我们需要从网上找到openid4java-0.9.8.jar,放到WEB-INF\lib目录下。有了这个驱动,我们就可以在spring security中进行openID的认证登陆。

另外,我们需要将spring-security-openid-2.0.4.jar放到lib目录中。

web.xml文件中,我们需要增加一段配置以支持openID认证过滤器:

<filter-mapping>

        <filter-name>springSecurityFilterChain</filter-name>

        <url-pattern>/j_spring_openid_security_check</url-pattern> 

    </filter-mapping>

    

3、Spring Securityxml配置

   特别注意Spring Security2.0.4的头部配置,因为网上版本众多,有的是以<bean>作为bean标签,有的是以<beans:bean> 作为bean标签,如果不设置正确的xml头部,则xml中无法使用像

<http>

    <intercept-url pattern="/test/**" access="ROLE_USER"/>

<openid-login/>

</http>

这种标签。可以参考下面的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:p="http://www.springframework.org/schema/p"     

   xmlns:security="http://www.springframework.org/schema/security"     

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"

        default-autowire="byType" default-lazy-init="true">

 

网上有很多pdf格式的spring security配置文档,里面介绍了

<http>

    <intercept-url pattern="/test/**" access="ROLE_USER"/>

<openid-login/>

</http>

使用 <openid-login/>就可以引入OpenID认证。

但是经过试验发现,使用 <openid-login/>以后,通过spring_openid_security_check进行OpenID认证,则无法使用j_spring_security_check做最常用的本地数据库认证。显然我们希望是两者同时支持。所以我们就不能使用缺省的方式,因此上面的<http>那段配置可以在xml中删除。

参考现有的authenticationProcessingFilter的配置方式,我们需要增加以下配置来满足openID认证授权:

<beans:bean id="springSecurityFilterChain"     

          class="org.springframework.security.util.FilterChainProxy">      

        <beans:property name="filterInvocationDefinitionSource">      

            <beans:value><![CDATA[      

                    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON      

                    PATTERN_TYPE_APACHE_ANT      

                    /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,openIDAuthenticationFilter,securityContextHolderAwareRequestFilter,exceptionTranslationFilter,filterSecurityInterceptor      

                ]]></beans:value>      

        </beans:property>      

    </beans:bean>      

上面蓝字部分是增加了一个openIDAuthenticationFilter ,下面是增加的这个bean的配置:

   <beans:bean id="openIDAuthenticationFilter"     

          class="org.springframework.security.ui.openid.OpenIDAuthenticationProcessingFilter"

   p:authenticationManager-ref="authenticationManager"     

          p:authenticationFailureUrl="/secure/openid.jsp"

    p:defaultTargetUrl="/apps/v22/ui/frame/main.jsp"

          p:filterProcessesUrl="/j_spring_openid_security_check"     

  />      

 p:authenticationFailureUrl指明认证失败跳转的页面。p:defaultTargetUrl指明认证成功跳转的页面。p:filterProcessesUrl指明openID的认证过滤器URL.

authenticationManager Bean中,原来有<beans:ref bean="daoAuthenticationProvider"/>      ,需要增加一个针对OpenID的Provider,见下文(蓝字是针对OpenID增加的Provider):

<beans:bean id="authenticationManager"     

          class="org.springframework.security.providers.ProviderManager"     

          p:sessionController-ref="concurrentSessionController">      

        <beans:property name="providers">      

            <beans:list>      

                <beans:ref bean="daoAuthenticationProvider"/>      

 <beans:ref bean="openidAuthenticationProvider"/>      

            </beans:list>      

        </beans:property>      

</beans:bean>      

下面我们要设置openidAuthenticationProvider Bean:

 

 <beans:bean id="openidAuthenticationProvider"

class="org.springframework.security.providers.openid.OpenIDAuthenticationProvider">

</beans:bean>

完整的配置(openjweb中此配置文件为D:\project\openjweb\src\java\applicationContext-security-new.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:p="http://www.springframework.org/schema/p"     

   xmlns:security="http://www.springframework.org/schema/security"     

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"

        default-autowire="byType" default-lazy-init="true">

 

  

  

    <!--去掉rememberme-->   

    <beans:bean id="springSecurityFilterChain"     

          class="org.springframework.security.util.FilterChainProxy">      

        <beans:property name="filterInvocationDefinitionSource">      

            <beans:value><![CDATA[      

                    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON      

                    PATTERN_TYPE_APACHE_ANT      

                    /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,openIDAuthenticationFilter,securityContextHolderAwareRequestFilter,exceptionTranslationFilter,filterSecurityInterceptor      

                ]]></beans:value>      

        </beans:property>      

    </beans:bean>      

     

   <beans:bean id="openIDAuthenticationFilter"     

          class="org.springframework.security.ui.openid.OpenIDAuthenticationProcessingFilter"

   p:authenticationManager-ref="authenticationManager"     

          p:authenticationFailureUrl="/secure/openid.jsp"

    p:defaultTargetUrl="/apps/v22/ui/frame/main.jsp"

          p:filterProcessesUrl="/j_spring_openid_security_check"     

  />      

    <beans:bean id="httpSessionContextIntegrationFilter"     

          class="org.springframework.security.context.HttpSessionContextIntegrationFilter"/>      

    <!--      

        退出(Logout)过滤器 退出登录操作      

    -->      

    <beans:bean id="logoutFilter"     

          class="org.springframework.security.ui.logout.LogoutFilter">      

        <!-- 退出系统后系统跳转到此URL -->      

        <beans:constructor-arg value="/common/chooseLogin.jsp"/>      

        <!-- 退出系统后的操作(调用logout方法) -->      

        <beans:constructor-arg>      

            <beans:list>      

                <!-- 实现了LogoutHandler接口(logout方法) -->      

                <beans:ref bean="rememberMeServices"/>      

                <beans:bean class="org.springframework.security.ui.logout.SecurityContextLogoutHandler"/>      

            </beans:list>      

        </beans:constructor-arg>      

    </beans:bean>      

    

  <beans:bean id="authenticationProcessingFilter"     

          class="org.openjweb.core.springsecurity.UserAuthenticationProcessingFilter"     

          p:authenticationManager-ref="authenticationManager"     

          p:authenticationFailureUrl="/common/chooseLogin.jsp?login_error=1"

  p:defaultTargetUrl="/apps/v22/redirect.jsp"

          p:filterProcessesUrl="/j_spring_security_check"     

          p:rememberMeServices-ref="rememberMeServices"/> 

           

    

    <beans:bean id="authenticationManager"     

          class="org.springframework.security.providers.ProviderManager"     

          p:sessionController-ref="concurrentSessionController">      

        <beans:property name="providers">      

            <beans:list>      

                <beans:ref bean="daoAuthenticationProvider"/>      

 <beans:ref bean="openidAuthenticationProvider"/>      

                 <!-- 去掉rememberme 查看是否还有超时问题

                <bean      class="org.springframework.security.providers.anonymous.AnonymousAuthenticationProvider"     

                        p:key="springsecurity"/>      

              

                <bean    class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider"     

                  p:key="springsecurity"/>       -->     

            </beans:list>      

        </beans:property>      

    </beans:bean>      

    <!-- 阻止用户在成功登录之后再进行一次成功登录 -->      

    <beans:bean  id="concurrentSessionController"     

          class="org.springframework.security.concurrent.ConcurrentSessionControllerImpl"     

          p:maximumSessions="1000"     

          p:exceptionIfMaximumExceeded="true"     

          p:sessionRegistry-ref="sessionRegistry"     

          p:messageSource-ref="messageSource"/>      

    <beans:bean  id="sessionRegistry"     

          class="org.springframework.security.concurrent.SessionRegistryImpl"/>      

   <beans:bean id="messageSource"     

          class="org.springframework.context.support.ReloadableResourceBundleMessageSource"     

          p:basename="/WEB-INF/classes/messageResource_zh_CN"/>      

   <beans:bean  id="securityContextHolderAwareRequestFilter"     

          class="org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter"/>      

     

    <beans:bean  id="rememberMeProcessingFilter"     

          class="org.springframework.security.ui.rememberme.RememberMeProcessingFilter"     

          p:authenticationManager-ref="authenticationManager"     

          p:rememberMeServices-ref="rememberMeServices"/>   

<!--<http>

<intercept-url pattern="/secure/**" access="ROLE_USER" requires-channel="https"/>

</http>-->

 

    

    <beans:bean  id="anonymousProcessingFilter"     

          class="org.springframework.security.providers.anonymous.AnonymousProcessingFilter"     

          p:key="springsecurity"     

          p:userAttribute="anonymousUser,ROLE_ANONYMOUS"/>      

     

   <beans:bean  id="exceptionTranslationFilter"     

          class="org.springframework.security.ui.ExceptionTranslationFilter"     

          p:accessDeniedHandler-ref="accessDeniedHandler"     

          p:authenticationEntryPoint-ref="authenticationEntryPoint"/>      

     <beans:bean id="accessDeniedHandler"     

          class="org.springframework.security.ui.AccessDeniedHandlerImpl"     

          p:errorPage="/accessDenied.jsp"/>      

     <beans:bean id="authenticationEntryPoint"     

          class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint"     

          p:loginFormUrl="/common/chooseLogin.jsp"     

          p:forceHttps="false"/>      

    

 

 

 

<beans:bean id="userCache"

class="org.springframework.security.providers.dao.cache.EhCacheBasedUserCache">

<beans:property name="cache" ref="userCacheBacked" />

</beans:bean>

 

<beans:bean  id="userCacheBacked"

class="org.springframework.cache.ehcache.EhCacheFactoryBean">

<beans:property name="cacheManager" ref="cacheManager" />

<beans:property name="cacheName" value="userCache" />

</beans:bean>

 

<beans:bean  id="cacheManager"

class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">

<beans:property name="configLocation"

value="classpath:ehcache-security.xml" />

</beans:bean>

 

 

<beans:bean id="filterSecurityInterceptor"

class="org.springframework.security.intercept.web.FilterSecurityInterceptor">

<security:custom-filter before="FILTER_SECURITY_INTERCEPTOR" />

<beans:property name="authenticationManager"

ref="authenticationManager" />

<beans:property name="accessDecisionManager"

ref="accessDecisionManager" />

 

<beans:property name="alwaysReauthenticate" value="true" />

 

<beans:property name="objectDefinitionSource"

ref="databaseFilterInvocationDefinitionSource" />

</beans:bean>

 

      <beans:bean  id="accessDecisionManager"

class="org.springframework.security.vote.AffirmativeBased">

<beans:property name="decisionVoters">

<beans:list>

<beans:bean

class="org.springframework.security.vote.RoleVoter">

<beans:property name="rolePrefix" value="" />

</beans:bean>

<!-- <bean class="org.springframework.security.vote.AuthenticatedVoter"/>  -->  <!--解决权限不足出现异常信息-->

</beans:list>

</beans:property>

</beans:bean>

 

     

    <beans:bean id="rememberMeServices"     

          class="org.springframework.security.ui.rememberme.TokenBasedRememberMeServices"     

          p:key="springsecurity"     

          p:userDetailsService-ref="userDetailsService"/>      

     <!-- <property name="tokenValiditySeconds" value="86400" />  -->

   

 

    <beans:bean id="daoAuthenticationProvider"

class="org.springframework.security.providers.dao.DaoAuthenticationProvider">

<beans:property name="userDetailsService" ref="userDetailsService" />

<beans:property name="userCache" ref="userCache" />

<beans:property name="passwordEncoder" ref="passwordEncoder" />

</beans:bean>

 

 <beans:bean id="openidAuthenticationProvider"

class="org.springframework.security.providers.openid.OpenIDAuthenticationProvider">

<!--<beans:property name="userDetailsService" ref="userDetailsService" />

<beans:property name="userCache" ref="userCache" />

<beans:property name="passwordEncoder" ref="passwordEncoder" />-->

</beans:bean>

    <beans:bean id="passwordEncoder"     

          class="org.springframework.security.providers.encoding.Md5PasswordEncoder"/>      

     

    

     

    <beans:bean  id="userDetailsService"

class="org.openjweb.core.springsecurity.UserDetailsServiceImpl">

<beans:constructor-arg>

<beans:ref bean="IBaseDao3" />

</beans:constructor-arg>

</beans:bean>

     

   <beans:bean  id="databaseFilterInvocationDefinitionSource"

class="org.springframework.security.intercept.web.DefaultFilterInvocationDefinitionSource">

<!-- 匹配urlmatcher -->

<beans:constructor-arg

type="org.springframework.security.util.UrlMatcher"

ref="antUrlPathMatcher" />

<!-- url对应authoritymap -->

<beans:constructor-arg type="java.util.LinkedHashMap" ref="requestMap" />

</beans:bean>

 

<beans:bean  id="antUrlPathMatcher"

class="org.springframework.security.util.AntUrlPathMatcher" />

 

<beans:bean id="requestMap"

class="org.openjweb.core.springsecurity.RequestMapFactoryBean"

init-method="init">

 

</beans:bean>

 

    <beans:bean id="loggerListener"     

          class="org.springframework.security.event.authentication.LoggerListener"/>      

     

</beans:beans>    

 

注意配置文件中的这段代码:

    <beans:bean  id="userDetailsService"

class="org.openjweb.core.springsecurity.UserDetailsServiceImpl">

<beans:constructor-arg>

<beans:ref bean="IBaseDao3" />

</beans:constructor-arg>

</beans:bean>

org.openjweb.core.springsecurity.UserDetailsServiceImplOpenJWeb中实现Spring Security UserDetailsService接口的实现类。我们 此实现类中增加一段代码,此段代码获取openID认证以后的OpenID账号,检查数据库表comm_user中是否存在此账号,如果不存在,则认证成功后自动向数据库表添加一条账号记录,并且为此账号分配一个网站会员角色。下面是org.openjweb.core.springsecurity.UserDetailsServiceImpl的代码:

package org.openjweb.core.springsecurity;

 

 

 

import org.apache.log4j.Logger;

import org.openjweb.core.dao.IBaseDao;

import org.openjweb.core.entity.CommUser;

import org.openjweb.core.entity.CommUserRole;

import org.openjweb.core.service.IDBSupportService;

import org.openjweb.core.service.ServiceLocator;

import org.openjweb.core.util.StringUtil;

 

import org.springframework.dao.DataAccessException;

import org.springframework.security.userdetails.UserDetails;

import org.springframework.security.userdetails.UsernameNotFoundException;

 

public class UserDetailsServiceImpl   implements IUserService 

{

private static final Logger logger = Logger.getLogger(UserDetailsServiceImpl.class);

private IBaseDao defaultDao;

public UserDetailsServiceImpl (IBaseDao dao)

{

this.defaultDao = dao;

}

 

public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException 

{

CommUser user = null;

try

{

user = (CommUser)this.defaultDao.findById(CommUser.class.getName(), "loginId", userName);

    if(user.getIsInUse()!=null&&user.getIsInUse().equals("Y"))

    {

    }

    else

    {

    logger.info("用户被锁定......");

    throw new UsernameNotFoundException(userName); //被锁定

    }

}

catch(Exception ex)

{

//检查如果是openid格式的,则生成一个对应的openid用户--必填项先默认生成,用户再自己修改

if(userName.startsWith("http://")||userName.startsWith("https://"))

{

IDBSupportService service = (IDBSupportService)ServiceLocator.getBean("IDBSupportService3");

user = new CommUser();

Long serial = null;

try

{

serial = service.getSerial();

}

catch(Exception ex1)

{

//

}

user.setUserId(serial);

user.setRowId(StringUtil.getUUID());

user.setLoginId(userName);

user.setComId("C0001");

user.setIsPortalMember("Y");//设置为网站会员,这种情况一般是网站会员

user.setUsername(userName);//暂时以用户id作为用户名

user.setUserEmail(serial.toString()+"openjweb.com");//生成一个默认的

user.setPassword("unused");

user.setUserMobile(serial.toString());//生成一个默认的由用户自己修改

user.setIsInUse("Y");

user.setEmpNo(serial.toString());//工号

user.setUpdateUid("system");

user.setCreateUid("system");

user.setCreateDt(StringUtil.getCurrentDateTime());

user.setUpdateDt(user.getCreateDt());

user.setCurrFrameCode("06");

user.setCurrSkinCode("sky");

try

{

service.saveOrUpdate(user);

//然后分配门户网站会员角色

CommUserRole roleEnt = new CommUserRole();

roleEnt.setCreateDt(StringUtil.getCurrentDateTime());

roleEnt.setSerialNo(service.getSerial());

roleEnt.setRoleId(new Long(505715));

roleEnt.setUserId(user.getUserId());

service.saveOrUpdate(roleEnt);

}

catch(Exception ex2)

{

}

}

else

{

throw new UsernameNotFoundException(userName);

}

}

return user;

}

 

}

4、OpenID登录页

编写一个jsp,例如openid.jsp,下面是此jsp中的一段form内容:

<form action="/portal/j_spring_openid_security_check" method="post">    

  <label for="openid_identifier">Login</label>:    

   

    <input id="openid_identifier1" name="j_username" size="20" maxlength="100" type="text"/>  

 

  <input type="submit" value="Login"/>    

 </form>    

 

说明:/portal/指的是openjweb的应用路径,如果在webapps根目录可使用/j_spring_openid_security_check ,OpenID输入框的name必须为j_username

 

5、申请OpenID 账号

我们可以到谷歌、微软等openID提供商注册一个openID账号,或者在http://www.openid.org.cn上注册一个账号,例如注册一个baozhengw的账号,则完整的OpenID账号则为:  http://baozhengw.openid.org.cn/

 

6、在本地登录OpenID

运行第四步创建的JSP,见下图:

输入:http://baozhengw.openid.org.cn/

然后点登录,系统会跳转到OpenID服务器(系统会根据openid的域名跳转到对应的服务器),见下图(跳转到http://www.openid.org.cn/): 

输入baozhengw,和注册时的口令,然后点登录,自动跳转到http://localhost:8088/portal/apps/v22/ui/frame/main.jsp(在配置文件中通过redirect.jsp跳转到后台,因为新增用户自动添加了关联角色,所以能进入后台)

 

 

7、其他注意事项

SecurityContextImpl securityContext =(SecurityContextImpl)obj;

Object tmpObj = null;

tmpObj  = securityContext.getAuthentication().getPrincipal();

 

以传统的方式登录,即/j_spring_security_check本地数据库认证的模式,通过getPrincipal()实际返回的是UserDetailsService接口的实现类,在OpenJWeb中是CommUser类,而使用OpenID,则getPrincipal()返回的是OpenID账号,如http://baozhengw.openid.org.cn/ ,所以产品支持OpenID以后,getPrincipal()的返回值类型处理要考虑多种类型。

 

OpenJWeb 开源组织

QQ 29803446

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/baozhengw/article/details/20740447

智能推荐

机器学习算法学习02:决策树的学习以及应用决策树解决Cora数据集论文分类问题_传统机器学习解决cora数据集论文分类问题-程序员宅基地

文章浏览阅读1.1k次,点赞3次,收藏7次。机器学习03:决策树的学习以及应用决策树解决Cora数据集论文分类问题文章目录机器学习03:决策树的学习以及应用决策树解决Cora数据集论文分类问题1.前言2.算法分析2.1算法概述2.2 算法优化3.算法代码3.1 决策属性优先级选择3.1.1 信息熵3.2.2 信息增益率3.3.3 基尼系数3.2 数据集的预处理3.3 决策树的生成3.4 决策树的分类4.算法运行与评估4.1 使用信息增益来划分数据集4.2 使用信息增益率划分数据4.3 使用基尼指数划分数据5.结语1.前言决策树方法作为非常经典的_传统机器学习解决cora数据集论文分类问题

NVIDIA控制面板不见了解决方法-程序员宅基地

文章浏览阅读4.4k次,点赞2次,收藏2次。NVIDIA控制面板调不出来欢迎使用Markdown编辑器你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。新的改变我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:全新的界面设计 ,将会带来全新的写作体验;在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮

x4412开发板&ibox卡片电脑项目实战16-将hello x4412驱动编译成模块-程序员宅基地

文章浏览阅读1.3k次。在内核根目录执行make menuconfig,进入Device Drivers-> Character devices菜单界面,找到hello X4412 driver配置选项,按空格键将它配置成模块[M],保存退出。执行如下指令,保存配置好的内核配置文件:cp .config arch/arm/configs/x4412_android_defconfig 再在整个源码

新一代大数据引擎操作系统:DataWorks V2.0重磅来袭-程序员宅基地

文章浏览阅读723次。摘要: 众所周知,MaxComput与Blink分别是阿里巴巴自主研发的离线计算、实时计算大数据计算引擎,不仅拥有多项国家专利技术,而且多项关键指标已远超业内开源引擎平均能力,名副其实地成为了阿里巴巴大数据之路上的领航者。认识DataWorks:新一代大数据引擎操作系统众所周知,MaxComput与Blink分别是阿里巴巴自主研发的离线计算、实时计算大数据计算引擎,不仅拥有多项国家专利技术...

不好好作图的NCS系列(五):从这篇Cell学习GSEA的R语言分析及作图-程序员宅基地

文章浏览阅读3.6k次,点赞10次,收藏30次。之前我们在讲转录组系列的时候,说过差异基因的功能富集,用的是GO和KEGG分析。但是这远远不够,很多研究者更喜欢使用GSEA,全名是Gene Set Enrichment Analysis (基因集富集分析)。GSEA在一定程度上与GO一样,但是两者具有巨大的差别。GO使用的是差异基因,因为阈值的设定是人为的,所以很有可能遗漏一些重要基因,仅仅是因为这些基因的变化较小。而GSEA则不同,它需要的是对所有的基因进行分析,因此能够保留更多的信息。通俗的说,GSEA的适用场景是:在两种不同的生物学状态下,

Odoo2021最新实用教程之——Odoo Studio 在线开发工具实战入门指导-程序员宅基地

文章浏览阅读4.7k次。Odoo Studio 作为Odoo企业版中的核心模块,能让odoo使用者通过此设计器快速、高效地构建新模块以及方便地进行已有功能地调整。但目前缺乏与Odoo Studio有关的中文指导资料,本文通过文字与视频结合的方式讲解Odoo Studio的实战操作,希望帮助有需要的朋友快速掌握这个工具。即使你最终可能不用企业版,但通过odoo企业版在线试用提供的这个在线开发工具也能帮助你对odoo的原理更快的了解。 Odoo的在线开发工具是Odoo企业版提供的强力设计工具,本实战..._odoo studio

随便推点

【问题】解决docker 容器中文乱码_主机内的vi支持中文,但是docker内vi不支持中文-程序员宅基地

文章浏览阅读3.5k次。进入容器 查看字符集# docker exec -it <container_id> /bin/bash# locale 查看当前容器字符集# locale -a 查看容器支持的字符集从输出可以看到,系统使用的是POSIX字符集,POSIX字符集是不支持中文的,而UTF-8是支持中文的 只要把系统中的环境 LANG 改为”UTF-8”格式即可解决问题。临时设置#vi /etc/profile 进入文件加入变量# export LANG="en_US..._主机内的vi支持中文,但是docker内vi不支持中文

已知数据信息为 16位,最少应附加( )位校验位,以实现海明码纠错。_已知数据信息为16位,最少应附加-程序员宅基地

文章浏览阅读582次。已知数据信息为 16位,最少应附加( )位校验位,以实现海明码纠错。 A、3B、4C、5D、6答案:C答案解析:根据公式 2的k次方 ≥ n+k+1 , n=16 则 K=5_已知数据信息为16位,最少应附加

VUE项目报错webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --host 192.168.1.10-程序员宅基地

文章浏览阅读1.1k次。首先粘上logF:\BackStage>npm run dev> [email protected] dev F:\BackStage> webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --host 192.168.1.105报这个错我也是很无奈,正常情况下VU...

【ElasticSearch】RestClient和ElasticsearchTemplate实现高亮查询-程序员宅基地

文章浏览阅读1.9k次。在查询的时候希望,查询结果中的包含查询关键字高亮。(Es版本,6.5.4)前提准备,首先建立mappingPOST http://47.101.167.46:9200/hello_es/doc/_mapping{ "properties": { "name": { "type": "text", "analyzer":"ik_max_word", ...

PDF转word_pdf转word的方式csdn-程序员宅基地

文章浏览阅读2.4k次,点赞3次,收藏3次。https://www.addpdf.cn/pdf-to-word_pdf转word的方式csdn

背包问题 ——第K优解 或 次优解_次优解符号-程序员宅基地

文章浏览阅读1.9k次。附上水题一枚:http://acm.hdu.edu.cn/showproblem.php?pid=2639_次优解符号

推荐文章

热门文章

相关标签