Seasar2 框架学习笔记_selectbysqlfile-程序员宅基地

技术标签: Passbook デザイン  J2EE  

基本Seasar2 Web应用工程结构

Seasar2这个框架在日本十分的流行。Seasar2其实就是类似于Spring的一个提供DI功能的开源框架,但比Sping轻量级。并且同“其它轻量级容器”不同的是,“完全不需要书写设定文件”,“就算是应用程序发生改动也无需再次起动即可直接识别变更,因此具有脚本语言的灵活性。

 

  为了不用写设定文件也能够运行,Convention over Configuration的思想得以采用。Conventionover Configuration就是指,“只要遵守一个适当的规约,即使不用进行非常麻烦的设定,框架结构也可以自动替我们搞定的思想”,这一思想是Ruby on Rails中所倡导的。Seasar2的Convention over Configuration是从Ruby on Rails 那里得到的提示而产生的。Seasar2的核心特色,即SuperAgile Struts(超级敏捷开发框架,简称SAStruts),Seasar2实际上就是能够将传统基于Struts的系统开发过程大幅敏捷化的(Super Agile)的技术开发框架。

 

  本开发框架最大的特点是零配置文件支持,在使用传统的开发框架进行系统开发时,配置文件的管理十分的麻烦。同时,每修改一处配置,或者一个代码文件,还至少要重新启动一次服务器。而Seasar2实现零配置支持,可以不写一句配置文件就在框架基础上构建业务应用。开发人员只要遵从本框架约定的命名规范及代码规范根据设计编写业务代码,亦无需关注实现技术细节。

 

应用程序发生改动之时也无需启动便可立即识别变更的机能在Seasar2里被称为HOT deploy。

 

使用Seasar2基本功能(S2Container, S2AOP)的时候、CLASSPATH的下面必须包含以下文件。

lib/aopalliance-1.0.jar

lib/commons-logging-1.1.jar

lib/javassist-3.4.ga.jar

lib/ognl-2.6.9-patch-20070624.jar

lib/s2-framework-2.x.x.jar

lib/geronimo-j2ee_1.4_spec-1.0.jar (参考下面)

lib/portlet-api-1.0.jar (任选项)

lib/log4j-1.2.13.jar (任选项)

resources/log4j.properties (任选项)

resources/aop.dicon (任选项)

「lib」文件夹:包含S2Container以及相关库。

 

「doc」文件夹:S2Container的相关文档。

 

把下面jar包拷贝到lib目录下,并加入到Build Path里。

 

(1)使用S2Container必须的文件

 

s2-framework-2.4.42.jar

commons-logging-1.1.1.jar

javassist-3.4.ga.jar

ognl-2.6.9-patch-20090427.jar

 

(2)使用S2AOP必须的文件

 

aopalliance-1.0.jar

 

(3)使用Java EE服务器以外的Servlet容器(比如Tomcat)时必须的文件

 

geronimo-jta_1.1_spec-1.0.jar

 

 

使用Seasar2的扩张机能(S2JTA, S2DBCP, S2JDBC, S2Unit, S2Tx, S2DataSet)的时候必须要将以下文件追加到CLASSPATH里面。

lib/junit-3.8.2.jar

lib/poi-2.5-final-20040804.jar

lib/s2-extension-2.x.x.jar

lib/geronimo-jta_1.1_spec-1.0.jar (参考下面)

lib/geronimo-ejb_2.1_spec-1.0.jar (参考下面)

resources/jdbc.dicon

根据应用软件所需的执行环境、选择以下需要引用的文件[geronimo-j2ee_1.4_spec-1.0.jar、geronimo-jta_1.0.1B_spec-1.0.jar、geronimo-ejb_2.1_spec-1.0.jar]

环境 geronimo-j2ee_1.4_spec-1.0.jar geronimo-jta_1.1_spec-1.0.jargeronimo-ejb_2.1_spec-1.0.jar

不完全对应J2EE的Servlet container

(Tomcat等) 不要 要

(使用S2JTA,S2Tx的时候) 要

(使用S2Tiger的时候)

完全对应J2EE的应用服务器    



配置文件convention.dicon中配置src目录中的RootPackage包,名字自定义。

 

Passbook系统配置了两个RootPackageName

 

<components>

            <componentclass="org.seasar.framework.convention.impl.NamingConventionImpl">

                        <initMethodname="addRootPackageName">

                                    <arg>"jp.bric.passo.web"</arg>

                        </initMethod>

                        <initMethodname="addRootPackageName">

                                    <arg>"jp.bric.passo.db"</arg>

                        </initMethod>                     

            </component>

            <componentclass="org.seasar.framework.convention.impl.PersistenceConventionImpl"/>

</components>

1.Rootpackage下典型Java包

Action

系统中所有Action处理,都在RootPackage.Action下做定义,比如

与http://hostname/projectname/xxx/这样的URL相对应的Action类,就是XxxAction.java (注意大小写)

ActionForm

Action中对应的ActionForm,都在RootPackage.Form下做定义,比如,XxxAction中对应的ActionForm,其名称就对应为XxxForm。(注意大小写)

ActionForm的作用就是接受来自页面提交的输入/输出参数。(虽然这些参数都可以在action中定义,但从维护,可读的角度来要求,我们规定,对于Action处理中需要处理的页面输入输出参数,都要在ActionForm类中相应的变量定义)

Entity

系统中所有Entity类,都在RootPackage.Entity下做定义。Entity是用户储存数据库持久层的数据实体类。对于Entity的命名没有特别的规定。一般情况下可沿用数据库表的名称。

Passbook系统中为了更好的维护Entity放在了DB子项目中。

Service

对Entity操作的类,这里我们称为Service(业务逻辑层)。系统中所有Entity类,都在 RootPackage.Service下做定义。Serivce的类名称形如 XxxService, 因为一个Service通常与一个Entity对应, 所以Xxx部分原则上使用与之对应的Entity名称。(*关于数据持久层的说明,请参考S2JDBC)

Util

工程,项目中会经常调用到的自定义的工具类,可都存放在在RootPackage.Util下,没有特别的命名要求。

 

2.应用程序体系结构

Seasar2框架从根本上来说,也是基于MVC(ModelView Controller)体系结构衍生而成的, Model对应Entity、View对应JSP、Controller对应Action。 

一个Action中,可以包含多个执行方法(函数)。通常,一个UseCase映射一个Action。在B/S系统中也可以认为,业务由多个页面构成,也页面是构成UseCase的基本单位。而数据如何在页面中显示的逻辑,则在Action中做编码定义。

业务逻辑处理一般定义在Service中。也有一种设计观点认为。通过Dao(DataAccess Object),可以进一步把数据访问从业务逻辑中抽出,以应对开发过程中发生的数据访问层框架的变更。但这种情况基本上不会发生,故在Seasar2框 架中,数据访问处理可以直接写在业务逻辑中。

 

Action详解

服务器端用以响应处理浏览器请求(Request)的类,这里称之为Action。 在Struts和Struts2里,URL和Action的对应关系,需要在struts-config.xml中定义,在Seasar2框架中,这个对应关系通过下述约定的命名规则由框架自动确定,不需要再对struts-config.xml做任何编辑修改。“约定优于配置”原则的体现。

举例来说http://localhost:8080/seasar2-tutorial/login/ 

首先,seasar2-tutorial是应用名称。

再往后,Seasar2将根据下述规则,将URL转换定位到对应的Action。
    * Web应用名之后的是请求的路径,/login/ , 将路径最后的/去掉,并加上Action后缀, 变成 loginAction
    * 将首字母转换为大写字母 loginAction --〉LoginAction
    * 前置RootPackage.action.
    * 通过上面3步的转换,Seasar2最终将、/login/ 这个URL映射到tutorial.action.LoginAction 这个类。

如果请求URL中没有ActionPATH,框架会查找是否存在有RootPackage.action.IndexAction这个类,并加载执行。http://localhost:8080/seasra2-tutorial/ 对应的Action就是 tutorial.action.IndexAction。补充,如果想让系统缺省调用IndexAction,要注意Web的根目录下不要存放有 index.jsp。其执行的优先度高于IndexAction。

ActionPath可以进一步分割子集,如/aaa/bbb/这样的请求url的ActionPath,对应执行RootPackage.action.aaa.BbbAction类。

Seasar2中的Action类,是POJO(最普通的Java类)。 不需要继承Strtus的Action。

Struts2中一般extends ActionSupport .

在Action中通常会要使用到ActionForm,引用ActionForm时,请附加@ActionFormと@Resource注解,引用的ActionForm的实体变量名,固定定义为ActionForm类名的(首字母需转为小写)

Strtuts2中利用Value Stack来获取Action的参数和用户输入的参数。

ActionForm 引用示例

@ActionForm
@Resource
protected AddForm addForm;

向JSP页面输出的值以及而来自JSP页面提交的数据,既可以在Action类中作为属性定义,也可以将其定义在ActionForm中。但原则上请定义都在ActionForm中。

DTO

当有些信息(如Login用户名)需要在Session中管理保存时,将其放入RootPackage.dto.XxxDto。并通过注解@Component声明他将在Session中管理。

@Component(instance = InstanceType.SESSION)
public class UserDto implements Serializable {

    private static final long serialVersionUID = 1L;
    
    public String userName;
    ...
}

在Action中使用上述UserDto时、需要做如下变量定义,前置注解@Resource,变量名为类名称,首字母替换为小写。

@Resource
protected UserDto userDto;

相似的,我们编写的业务逻辑代码,都汇集到RootPackage.service包下,命名为XxxService。

public class XxxService {
    ...
}

在Action中,需要调用Service时, 按相同的命名规范定义实体,如下:

@Resource

protected XxxService xxxService;

同理,对于HttpServletRequest、HttpServletResponse等Servlet API相关的对象,也可通过前置@Resource注解的方式建立引用。

示例代码:

public class MyAction {


@Resource

protected HttpServletRequest request;


@Resource

protected HttpServletResponse response;

@Resource

protected HttpSession session;

@Resource

protected ServletContext application;

...

}

Method(函数)

Action类中的,对应于Request请求的处理函数,称为执行方法(函数),

方法名(函数名)任意,前置@Execute注解。方法的返回值是String,方法不带任何参数。

@Execute
public String xxx() {
    ...
    return ...;
}

执行方法的返回值,就是处理完成后页面跳转的地址,

如返回值不是以/开头的,系统将以Action所在Path作为相对路径的起始点。

例如,/add/的Action的返回值为index.jsp时,跳转的页面即为/add/index.jsp。在web.xml中有一个VIEW_PREFIX参数,用以确定该jsp文件在工程中的位置。

在seasar2-tutorial工程里,VIEW_PREFIX的值为/WEB-INF/view,所以跳转页面所在的位置就在/WEB-INF/view/add/index.jsp。

如返回值是以/开头的,系统则认为是Web应用的根地址为相对路径的起始点。

例如,返回值是/select/时,跳转的页面就是http://localhost:8080/seasar2-tutorial/select/ 。

页面的跳转方法,缺省为FORWARD,当需要使用重定向方式是,需要在返回路径的后面追加redirect=true的参数。形如,

    ...

    return"xxx.jsp?redirect=true";


    ...

    return"xxx.jsp?key=value&redirect=true";

跨域跳转

...
return "https://hostname/appname/path/?redirect=true";

也有些情况,如文件下载等请求处理,只通过Response直接输出而没有跳转时,执行方法的返回值设为null。

一个Action类中,可以定义多个执行方法。具体到哪一个方法被调用,则是由请求URL,JSP页面提交按钮的Name属性值来确定。

如下的例子、AddAction#index()将被调用执行。

http://localhost:8080/sa-struts-tutorial/add/index

http://localhost:8080/sa-struts-tutorial/add/  (url中没有执行方法名时,index()方法将被缺省调用)

故上述2个URL等效。

再看一个页面提交的例子

JSP页面的按钮定义为

<input type="submit"name="confirm" value="确认提交"/> 

此提交按钮标签的name属性值是comfirm。Action类中的conFirm()方法负责处理通过此按钮提交后的一系列工作。

如希望窗体提交前做必要的输入数据验证,Seaser2提供了比较简易的方法。 将@Execute注解的validator参数置为true。缺省为true。

当验证出错后,页面将跳转到input参数指定的页面。

@Execute(validator = true, input ="edit.jsp")

ActionForm

ActionForm,主要用于管理Request中的输入输出参数,是一个普通的POJO。

输入输出参数的名字对应ActionForm内定义各属性变量。

Seasar2中,Action的生存期缺省为Request周期,如要提升为Session生存周期,需要增加一行注解的描述。

@Component(instance = InstanceType.SESSION)

public class XxxForm implements Serializable {


    private static final long serialVersionUID = 1L;

    ...

}

需要注意的一点,需要归入Session生存周期管理的组件,必须implements Serializable。 

进一步,使用对输入对象做数据验证,也是在ActionForm中通过对属性变量前置注解来实现。

@Required

public String arg1;

* 对arg1做必须输入的验证

Ajax

Seasar2支持Ajax调用。最常见的是通过jquery调用。

Ajax调用时,Action的执行方法内,直接使用ResponseUtil.write("字符串"),输出字符文本。也没有页面迁移,所以方法的返回值是null。 

@Execute(validator = false) public String hello() {     ResponseUtil.write("Hello Ajax");     return null; }

在jsp文件中,使用到jquery,需要包含jquery库。

<scriptsrc="${f:url('/js/jquery.js')}"></script>
...
<span id="message"></span><br />
<input type="button" value="hello"
    οnclick="$('#message').load('hello');"/>

上例中,在jsp页面中,通过$('TAGid').load('执行方法名');的写法,可以将Ajax调用的输出结果赋回页面的指定元素(TAGID)。

3.DB访问配置

S2JDBC持久层框架,快速实现对数据库数据的增删查改和事务控制。

前面的章节提到过,对数据库操作的业务逻辑,可以放在Service层中实现。

Seasar2框架中缺省包含有S2JDBC持久层框架,实现对各类数据库的通用支持,与数据库连接有关的配置信息,都通过配置文件jdbc.dicon统一管理。
S2JDBC支持多种市面常见的数据库,这些信息定义在配置文件s2jdbc.dicon中,根据项目实际情况进行修改。

Passbook系统使用MySQL配置信息如下:

s2jdbc.dicon

<components>

                  <includepath="jdbc.dicon"/>

                  <includepath="s2jdbc-internal.dicon"/>

                  <componentname="jdbcManager"class="org.seasar.extension.jdbc.manager.JdbcManagerImpl">

                                    <propertyname="maxRows">0</property>

                                    <propertyname="fetchSize">0</property>

                                    <propertyname="queryTimeout">0</property>

                                    <propertyname="dialect">mysqlDialect</property>

                  </component>

</components>

jdbc.dicon

<componentsnamespace="jdbc">

    <include path="jta.dicon"/>

    <includepath="jdbc-extension.dicon"/>

                  <componentclass="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/>

                  <componentclass="org.seasar.extension.jdbc.impl.ConfigurableStatementFactory">

        <arg>

            <componentclass="org.seasar.extension.jdbc.impl.BasicStatementFactory"/>

        </arg>

        <propertyname="fetchSize">100</property>

        <!--

        <property name="maxRows">100</property>

        -->

    </component>

    <component name="xaDataSource"

           class="org.seasar.extension.dbcp.impl.XADataSourceImpl">

        <propertyname="driverClassName">"com.mysql.jdbc.Driver"</property>

        <property name="URL">

           "jdbc:mysql://localhost:3306/passo_web?characterEncoding=utf8"

        </property>

        <propertyname="user">"root"</property>

        <propertyname="password">""</property>

    </component>

    <component name="connectionPool"

           class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">

        <propertyname="timeout">600</property>

        <propertyname="maxPoolSize">10</property>

        <propertyname="allowLocalTx">true</property>

        <propertyname="validationQuery">null</property>

        <propertyname="validationInterval">0</property>

        <destroyMethodname="close"/>

    </component>

    <component name="dataSource"

      class="org.seasar.extension.dbcp.impl.DataSourceImpl"/>

</components>

在实际代码中,我们通过JdbcManager实例与持久层框架S2JDBC交互。

Service或者Action中,引用JdbcManager的方法如下:

@Resource

protected JdbcManager jdbcManager;

自动事务

在Action或Service中,如需要打开或关闭例外,异常发生后的事务自动回滚,请修改配置文件cutomizer.dicon

<componentname="actionCustomizer"
  class="org.seasar.framework.container.customizer.CustomizerChain">
  <initMethod name="addCustomizer">
    <arg>
      <component
       class="org.seasar.framework.container.customizer.TxAttributeCustomizer"/>
    </arg>
  </initMethod>
  ...
</component>
    
<component name="serviceCustomizer"
 class="org.seasar.framework.container.customizer.CustomizerChain">
  <initMethod name="addCustomizer">
    <arg>
      <component
       class="org.seasar.framework.container.customizer.TxAttributeCustomizer"/>
    </arg>
  </initMethod>
  ...

S2JDBC示例

下面的例子,演示了如何通过jdbcmanager,完成对数据库表的CRUD操作。

·       SELECT

/*多条结果*/

List<Employee> results =jdbcManager.from(Employee.class)
                            .join("department")
                            .where("id in (? , ?)", 11, 22)
                            .orderBy("name")
                            .getResultList();

/*单条结果*/

Employee result =
    jdbcManager
        .from(Employee.class)
        .where("id = ?", 1)
        .getSingleResult();
System.out.println(result.name);

* Employee是一个Entity,其属性一般都对应于数据库表的定义,其中没有业

@Entity

public classEmployee {

/** id字段属性 */

@Id

@Column

public Integer id;

/** name 字段 属性 */

@Column

public String name;

/** jobType 字段 属性 */

@Column

public IntegerjobType;

/** salary 字段 属性 */

@Column

public Integer salary;

/** departmentId 字段 属性 */

@Column(nullable =true, unique = false)

public IntegerdepartmentId;

/** addressId 字段 属性 */

@Column(nullable =true, unique = true)

public IntegeraddressId;

                                          
  • Select (结果分页)

List < Employee > results = 
    jdbcManager
        . from ( Employee . class ) 
        . orderBy ( "id" ) 
        . limit ( 5 ) 
        . offset ( 4 ) 
        . getResultList (); 
for ( Employee e : results ) { 
    System . out . println ( e . id ); 
}

  • Insert

public void testInsertTx () throws Exception { 
    Employee emp = new Employee (); 
    emp . name = "test" ; 
    emp . jobType = JobType . ANALYST ; 
    emp . salary = 300 ; 
    jdbcManager . insert ( emp ). execute (); 
}

  • Update

mployee emp = 
    jdbcManager
        . from ( Employee . class ) 
        . where ( "id = ?" , 1 ) 
        . getSingleResult (); 
emp . name = "hoge" ; 
jdbcManager . update ( emp ). execute (); 

  • Delete

Employee emp =
    jdbcManager
        .from(Employee.class)
        .where("id = ?", 1)
        .getSingleResult();
jdbcManager.delete(emp).execute();

emp =
    jdbcManager
        .from(Employee.class)
        .where("id = ?", 1)
        .getSingleResult();

对于单表的简单数据表操作,可以通过以上的方式完成。对于多表结合等复杂SQL的操作,JdbaManager提供另外一种直接执行SQL或SQL文件的方法。

代码内SQL定义

private static final String SELECT_SQL = 
    "select e.*, d.name as department_name" 
        + " from employee eleft outer join department d" 
        + " one.department_id = d.id" 
        + " where d.id =?" ; 
... 
List < EmployeeDto > results = 
    jdbcManager
        . selectBySql ( EmployeeDto . class , SELECT_SQL , 1 ) 
        . getResultList (); 
for ( EmployeeDto e : results ) { 
    System . out . println ( e . name + " " + e . departmentName ); 

执行外部SQL文件定义

SelectParam param = new SelectParam (); 
param . salaryMin = new BigDecimal ( 1200 ); 
param . salaryMax = new BigDecimal ( 1800 ); 
List < EmployeeDto > results = 
    jdbcManager
        . selectBySqlFile ( 
            EmployeeDto . class , 
            "examples/sql/employee/selectAll.sql" , 
            param ) 
        . getResultList ();

看一下sql文件是如何定义的examples/sql/employee/selectAll.sql:( SQL定义文件必须保存为UTF-8编码)。

select * from employeewhere
salary <= /*salaryMin*/ 1000
and salary >= /*salaryMax*/ 2000

SQL中的查询参数,可以是Map,也可以是一个POJO,只要KEY或者属性名和sql文件中定义的参数名称一致即可。

SelectParam .java: 

package examples . entity . Employee ;

public class SelectAllParam {

    public BigDecimal salaryMin ;

    public BigDecimal salaryMax ;

}

  • 复杂SQL的分页注意实现分页的SQL定义中一定要有order by

jdbcManager
    .selectBySql(
        EmployeeDto.class,
        "select id,name from employee order by name")
    .limit(100)
    .offset(10)
    .getResultList();

  • 通过SQL实现,insert/update/delete 

jdbcManager
        .updateBySql(
           "update employee set salary = ? where id = ?", 
           BigDecimal.class, 
           Integer.class)
        .params(null, 1)
        .execute();

4.Q&A?

Question 1:Web.xml中是否可以定义自己的Servlet?

 

Answer:可以。Seasar框架本身支持开发者自己编写的Servlet。但主要注意的是。当在Servlet中需要用到Seasar2提供的组件时,

请务必通过SingletonS2ContainerFactory(单例容器工厂)对象建立引用。

例:在servlet中使用jdbcmanager.

 

      final String PATH = "s2jdbc_cloud.dicon";

 

       SingletonS2ContainerFactory.setConfigPath(PATH);

       SingletonS2ContainerFactory.init();

       S2Container s2Container = SingletonS2ContainerFactory.getContainer();

       jdbcmanager = (JdbcManager)s2Container.getComponent("jdbcManager_cloud");

 

Question 2:s2jdbc是否支持oracle的BLOB字段类型?

Answer:支持。entity类中定义的字段项加注@Lob 注解即可

例:

@Lob

@Column(name = "IMAGEDATA")

public byte [] imagedata ;

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

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf

推荐文章

热门文章

相关标签