首页
友链
关于
免责声明
Search
1
王者营地战绩数据王者荣耀查询网页源码
6,210 阅读
2
群晖Active Backup for Business套件备份Linux服务器教程
4,384 阅读
3
影视分享
4,313 阅读
4
(亲测)Jrebel激活破解方式2019-08-21
4,290 阅读
5
centos7 安装及卸载 jekenis
3,573 阅读
日常
文章
后端
前端
Linux
异常
Flutter
分享
群辉
登录
Search
标签搜索
docker
springboot
Spring Boot
java
linux
Shiro
Graphics2D
图片
游戏账号交易
Mybatis
Spring Cloud
centos
脚本
Web Station
群辉
王者营地
战绩查询
平台对接
Spring Cloud Alibaba
nacos
绿林寻猫
累计撰写
249
篇文章
累计收到
26
条评论
首页
栏目
日常
文章
后端
前端
Linux
异常
Flutter
分享
群辉
页面
友链
关于
免责声明
搜索到
195
篇与
后端
的结果
2021-12-08
Hibernate(三):多对多(many-to-many)
以下是多对多的基础配置 -- 多对多-- 用户CREATE TABLE users(uid int PRIMARY KEY auto_increment, -- 用户iduname VARCHAR(50) not null -- 用户名);-- 角色CREATE TABLE roles(rid int PRIMARY KEY auto_increment, -- 角色idrname VARCHAR(50) not null -- 角色名);-- 用户角色关系表CREATE TABLE relation(uid int not null, -- 用户idrid int not null -- 角色id); Roles.hbm.xml<hibernate-mapping> <class name="club.lygangdai.pojo.Roles" table="roles"> <id name="rid" type="int"> <column name="rid" /> <generator class="native" /> </id> <property name="rname" type="java.lang.String"> <column name="rname" /> </property> <set name="users" table="relation" > <key column="rid"></key> <many-to-many class="club.lygangdai.pojo.Users" column="uid" /> </set> </class> </hibernate-mapping> Roles.javapackage club.lygangdai.pojo; import java.util.HashSet; import java.util.Set; /** * @ClassName: Roles * @Description: TODO(角色表) * @author Uncle * @date 2018年8月9日 下午7:11:39 * */ public class Roles { private int rid; private String rname; private Set<Users> users = new HashSet<Users>(); /** * @Description: TODO(这里用一句话描述这个类的作用) * @param rid * @param rname */ public Roles(int rid, String rname) { super(); this.rid = rid; this.rname = rname; } /** * @Description: TODO(这里用一句话描述这个类的作用) */ public Roles() { super(); } /** * @return rid */ public int getRid() { return rid; } /** * @param rid 要设置的 rid */ public void setRid(int rid) { this.rid = rid; } /** * @return rname */ public String getRname() { return rname; } /** * @param rname 要设置的 rname */ public void setRname(String rname) { this.rname = rname; } /** * @return users */ public Set<Users> getUsers() { return users; } /** * @param users 要设置的 users */ public void setUsers(Set<Users> users) { this.users = users; } /* (非 Javadoc) * @Title: toString * @Description: TODO(这里用一句话描述这个方法的作用) * @return * @see java.lang.Object#toString() */ @Override public String toString() { return "Roles [rid=" + rid + ", rname=" + rname + "]"; } } Users.hbm.xml<hibernate-mapping> <class name="club.lygangdai.pojo.Users" table="users"> <id name="uid" type="int"> <column name="uid" /> <generator class="native" /> </id> <property name="uname" type="java.lang.String"> <column name="uname" /> </property> <set name="roles" table="relation" cascade="all-delete-orphan" inverse="true" > <key> <column name="uid" /> </key> <many-to-many class="club.lygangdai.pojo.Roles" column="rid"/> </set> </class> </hibernate-mapping> Users.javapackage club.lygangdai.pojo; import java.util.HashSet; import java.util.Set; /** * @ClassName: Users * @Description: TODO(用户表) * @author Uncle * @date 2018年8月9日 下午7:10:23 * */ public class Users { private int uid; private String uname; private Set<Roles> roles = new HashSet<Roles>(); /** * @Description: TODO(这里用一句话描述这个类的作用) * @param uid * @param uname */ public Users(int uid, String uname) { super(); this.uid = uid; this.uname = uname; } /** * @Description: TODO(这里用一句话描述这个类的作用) */ public Users() { super(); } /** * @return uid */ public int getUid() { return uid; } /** * @param uid 要设置的 uid */ public void setUid(int uid) { this.uid = uid; } /** * @return uname */ public String getUname() { return uname; } /** * @param uname 要设置的 uname */ public void setUname(String uname) { this.uname = uname; } /** * @return roles */ public Set<Roles> getRoles() { return roles; } /** * @param roles 要设置的 roles */ public void setRoles(Set<Roles> roles) { this.roles = roles; } /* (非 Javadoc) * @Title: toString * @Description: TODO(这里用一句话描述这个方法的作用) * @return * @see java.lang.Object#toString() */ @Override public String toString() { return "Users [uid=" + uid + ", uname=" + uname + "]"; } } hibernate.cfg.xml<hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.password">root</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property> <property name="hibernate.connection.username">root</property> <property name="show_sql">true</property> <property name="format_sql">true</property> <mapping resource="club/lygangdai/pojo/Roles.hbm.xml"/> <mapping resource="club/lygangdai/pojo/Users.hbm.xml"/> </session-factory> </hibernate-configuration>
2021年12月08日
141 阅读
0 评论
0 点赞
2021-12-08
面向对象的特征有哪些方面?
面向对象的编程语言有封装、继承 、抽象、多态等4个主要的特征。封装封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、低耦合”,防止程序相互依赖性而带来的变动影响。在面向对象的编程语言中,对象是封装的最基本单位,面向对象的封装比传统语言的封装更为清晰、更为有力。面向对象的封装就是把描述一个对象的属性和行为的代码封装在一个“模块”中,也就是一个类中,属性用变量定义,行为用方法进行定义,方法可以直接访问同一个对象中的属性。通常情况下,只要记住让变量和访问这个变量的方法放在一起,将一个类中的成员变量全部定义成私有的,只有这个类自己的方法才可以访问到这些成员变量,这就基本上实现对象的封装,就很容易找出要分配到这个类上的方法了,就基本上算是会面向对象的编程了。例如,人要在黑板上画圆,这一共涉及三个对象:人、黑板、圆,画圆的方法要分配给哪个对象呢?由于画圆需要使用到圆心和半径,圆心和半径显然是圆的属性,如果将它们在类中定义成了私有的成员变量,那么,画圆的方法必须分配给圆,它才能访问到圆心和半径这两个属性,人以后只是调用圆的画圆方法、表示给圆发给消息而已,画圆这个方法不应该分配在人这个对象上,这就是面向对象的封装性,即将对象封装成一个高度自治和相对封闭的个体,对象状态(属性)由这个对象自己的行为(方法)来读取和改变。一个更便于理解的例子就是,司机将火车刹住了,刹车的动作是分配给司机,还是分配给火车,显然,应该分配给火车,因为司机自身是不可能有那么大的力气将一个火车给停下来的,只有火车自己才能完成这一动作,火车需要调用内部的离合器和刹车片等多个器件协作才能完成刹车这个动作,司机刹车的过程只是给火车发了一个消息,通知火车要执行刹车动作而已。抽象抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。抽象包括行为抽象和状态抽象两个方面。例如,定义一个Person类,如下: class Person{ String name; int age;} 人本来是很复杂的事物,有很多方面,但因为当前系统只需要了解人的姓名和年龄,所以上面定义的类中只包含姓名和年龄这两个属性,这就是一种抽像,使用抽象可以避免考虑一些与目标无关的细节。我对抽象的理解就是不要用显微镜去看一个事物的所有方面,这样涉及的内容就太多了,而是要善于划分问题的边界,当前系统需要什么,就只考虑什么。继承在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。多态多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。多态性增强了软件的灵活性和扩展性。例如,下面代码中的UserDao是一个接口,它定义引用变量userDao指向的实例对象由daofactory.getDao()在执行的时候返回,有时候指向的是UserJdbcDao这个实现,有时候指向的是UserHibernateDao这个实现,这样,不用修改源代码,就可以改变userDao指向的具体类实现,从而导致userDao.insertUser()方法调用的具体代码也随之改变,即有时候调用的是UserJdbcDao的insertUser方法,有时候调用的是UserHibernateDao的insertUser方法: UserDao userDao = daofactory.getDao(); userDao.insertUser(user); 比喻:人吃饭,你看到的是左手,还是右手?
2021年12月08日
47 阅读
0 评论
0 点赞
2021-12-08
论web开发中一些标签属性命名规则的重要性
在平时做项目时给页面标签赋值或者拿值等操作时,都会根据对应的id或者name、class或者通过jquery 的其他方式来操作。不过在一些很平常的一些操作来说,命名可能只是给标签赋予一个身份,指定一个名称,并没有考虑太多。 不过在一些特殊的情况下时,一个适应当下操作的命名规则很重要。 例如曾经我碰到一个进度报表: 这个报表需要统计每个不同类型(新户、分户.....)的工单对应流程(用户申请....)的数量,可能有些会调用很多的查询去统计每个的数量。其实在一些业务需求下,根据一些已存在的特殊性可以很方便的进行操作。就比如这个工单的类型最开始的时候已经定义了用什么指代它,假设1~7对应每一个工单,而流程步骤也是对应-1~8。当我想到这一步的时候,我只需要从数据库拿出三个列的数据:统计数、工单类型、流程,一个统计加分组的视图完全可以做到。 既然能拿到所有的对应数据了,那么在标签命名这一块其实根据这三个列就很好来命名了 如:id='s1o1',id='s1o2' 这两个分别对应的是新户工单的新户申请和分户申请的工单申请, <thead> <tr> <th>进度</th> <th width="100">新户</th> <th width="100">分户</th> <th width="100">过户</th> <th width="100">代扣</th> <th width="100">换表</th> <th width="100">重签</th> <th width="100">销户</th> <th width="100">总数</th> </tr> </thead> <tbody> <tr> <td class="center item">01 用户申请</td> <td class="center num" id="s1o1">0</td> <td class="center num" id="s1o2">0</td> <td class="center num" id="s1o3">0</td> <td class="center num" id="s1o4">0</td> <td class="center num" id="s1o5">0</td> <td class="center num" id="s1o6">0</td> <td class="center num" id="s1o7">0</td> <td class="center cnt num" id="s1oo">0</td> </tr> <tr> <td class="center item">02 初步审核</td> <td class="center num" id="s2o1">0</td> <td class="center num" id="s2o2">0</td> <td class="center num" id="s2o3">0</td> <td class="center num" id="s2o4">0</td> <td class="center num" id="s2o5">0</td> <td class="center num" id="s2o6">0</td> <td class="center num" id="s2o7">0</td> <td class="center cnt num" id="s2oo">0</td> </tr> <tr> <td class="center item">03 交施工费</td> <td class="center num" id="s3o1">0</td> <td class="center num" id="s3o2">0</td> <td class="center num" id="s3o3"></td> <td class="center num" id="s3o4"></td> <td class="center num" id="s3o5">0</td> <td class="center num" id="s3o6"></td> <td class="center num" id="s3o7"></td> <td class="center cnt num" id="s3oo">0</td> </tr> <tr> <td class="center item">04 水费清算</td> <td class="center num" id="s4o1"></td> <td class="center num" id="s4o2">0</td> <td class="center num" id="s4o3"></td> <td class="center num" id="s4o4"></td> <td class="center num" id="s4o5"></td> <td class="center num" id="s4o6"></td> <td class="center num" id="s4o7">0</td> <td class="center cnt num" id="s4oo">0</td> </tr> <tr> <td class="center item">05 供水协议</td> <td class="center num" id="s5o1">0</td> <td class="center num" id="s5o2">0</td> <td class="center num" id="s5o3"></td> <td class="center num" id="s5o4"></td> <td class="center num" id="s5o5"></td> <td class="center num" id="s5o6">0</td> <td class="center num" id="s5o7"></td> <td class="center cnt num" id="s5oo">0</td> </tr> <tr> <td class="center item">06 施工竣工</td> <td class="center num" id="s6o1">0</td> <td class="center num" id="s6o2">0</td> <td class="center num" id="s6o3"></td> <td class="center num" id="s6o4"></td> <td class="center num" id="s6o5">0</td> <td class="center num" id="s6o6"></td> <td class="center num" id="s6o7"></td> <td class="center cnt num" id="s6oo">0</td> </tr> <tr> <td class="center item">07 通水停水</td> <td class="center num" id="s7o1">0</td> <td class="center num" id="s7o2">0</td> <td class="center num" id="s7o3"></td> <td class="center num" id="s7o4"></td> <td class="center num" id="s7o5">0</td> <td class="center num" id="s7o6"></td> <td class="center num" id="s7o7">0</td> <td class="center cnt num" id="s7oo">0</td> </tr> <tr> <td class="center item">08 档案存档</td> <td class="center num" id="s8o1">0</td> <td class="center num" id="s8o2">0</td> <td class="center num" id="s8o3">0</td> <td class="center num" id="s8o4">0</td> <td class="center num" id="s8o5">0</td> <td class="center num" id="s8o6">0</td> <td class="center num" id="s8o7">0</td> <td class="center cnt num" id="s8oo">0</td> </tr> <tr class="todo"> <td class="center item"> 待办总数</td> <td class="center num" id="o1">0</td> <td class="center num" id="o2">0</td> <td class="center num" id="o3">0</td> <td class="center num" id="o4">0</td> <td class="center num" id="o5">0</td> <td class="center num" id="o6">0</td> <td class="center num" id="o7">0</td> <td class="center cnt num" id="oo">0</td> </tr> <tr> <td class="center item"> 工单完成</td> <td class="center num" id="s0o1">0</td> <td class="center num" id="s0o2">0</td> <td class="center num" id="s0o3">0</td> <td class="center num" id="s0o4">0</td> <td class="center num" id="s0o5">0</td> <td class="center num" id="s0o6">0</td> <td class="center num" id="s0o7">0</td> <td class="center cnt num" id="s0oo">0</td> </tr> <tr> <td class="center item"> 工单终止</td> <td class="center num" id="s-1o1">0</td> <td class="center num" id="s-1o2">0</td> <td class="center num" id="s-1o3">0</td> <td class="center num" id="s-1o4">0</td> <td class="center num" id="s-1o5">0</td> <td class="center num" id="s-1o6">0</td> <td class="center num" id="s-1o7">0</td> <td class="center cnt num" id="s-1oo">0</td> </tr> </tbody> 那么利用Ajax拿取返回值,使用jquery的each 用 $("#s"+this.stepId+"o"+this.orderType).text(this.count);绑值,完全一句代码可以完成。在Ajax的success里执行$.each(data,function(){ //给对应工单的对应流程绑值 $("#s"+this.stepId+"o"+this.orderType).text(this.count); }); //流程统计 for (var i = -1; i < 9; i++) { //流程 var counts = 0; for (var j = 1; j < 8; j++) {//工单类型 var z= $("#s"+i+"o"+j).text(); if(z!=''){ counts=counts+parseInt(z); } } //设置流程统计 $("#s"+i+"oo").text(counts); } //待完成总和 var cou = 0; //统计待完成 for (var j = 1; j < 8; j++) {//工单类型 var counts = 0; for (var i = 1; i < 9; i++) { //流程 var z= $("#s"+i+"o"+j).text(); if(z!=''){ counts=counts+parseInt(z); } } cou=cou+counts; //设置统计待完成 $("#o"+j).text(counts); } //设置待完成总和 $("#oo").text(cou); }至此完全可以给所有标签赋值。其实每一个统计数来的 td都能点击去详细页面。而我们只需要把id传过去,进行处理就可以得到对应的统计数信息。 当然可能这种比不是适用于所有的报表什么的,只能说在某种情况下面,看清此时的需求及数据与页面的关系,定义一个正确的命名规则可以省去很多事情。如果我还有不足的地方请大佬提示
2021年12月08日
157 阅读
0 评论
0 点赞
2021-12-08
SSH框架的架设
Maven 创建项目POM.XML<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>club.lygangdai</groupId> <artifactId>WaterWorks_1</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>WaterWorks_1 Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <!-- junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- jstl --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.0</version> <scope>provided</scope> </dependency> <!--自定义标签 jsp-api --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> <scope>provided</scope> </dependency> <!-- fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> <!-- mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <!-- hibernate --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.3.3.Final</version> </dependency> <!-- spring依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.8.RELEASE</version> </dependency> <!-- c3p0依赖 --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <!-- 引入spring-orm依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>5.0.8.RELEASE</version> </dependency> <!-- struts2 --> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.5.13</version> </dependency> <!-- 日志 --> <!-- log配置:Log4j2 + Slf4j start --> <!-- 引入slf4j核心接口包 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.7</version> </dependency> <!--把jcl实现的日志输出重定向到 SLF4J --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.7</version> <scope>runtime</scope> </dependency> <!--用于与slf4j保持桥接 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.9.1</version> </dependency> <!--引入log4j2jar核心包:日志接入接口 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.9.1</version> </dependency> <!--引入log4j2jar核心包 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.9.1</version> </dependency> <!--web工程需要包含log4j-web,非web工程不需要 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-web</artifactId> <version>2.9.1</version> <scope>runtime</scope> </dependency> <!--需要使用log4j2的AsyncLogger需要包含disruptor --> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.2.0</version> </dependency> <!-- log配置:Log4j2 + Slf4j end --> <!-- 引入logging依赖:日志框架,与log4j时使用,struts使用Time拦截器时 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <!-- 引入struts2对Spring的支持插件 --> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.5.13</version> </dependency> <!-- spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.0.8.RELEASE</version> </dependency> <!-- 引入Spring 的AspectJ依赖,解析事务切点 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.0.8.RELEASE</version> </dependency> </dependencies> <build> <finalName>WaterWorks_1</finalName> </build> </project> db.propertiesdriver_Class=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/db_tap_water?useUnicode=true&characterEncoding=UTF-8 uname=root upass=root initPoolSize=10 maxPoolSizea=50 applicationContext-core.xml(可创建其他的applicationContext-*.xml配置其他bean)<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 载入db.properties --> <context:property-placeholder location="classpath:db.properties" /> <!-- 2. 配置数据源(需引入C3P0,同时删除hibernate.hbm.xml中的数据源配置) --> <!-- 要引用C3PO中的ComboPooledDataSource类 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 读取db.properties中参数值 --> <property name="user" value="${uname}"></property> <property name="password" value="${upass}"></property> <property name="jdbcUrl" value="${url}"></property> <property name="driverClass" value="${driver_Class}"></property> <property name="initialPoolSize" value="${initPoolSize}"></property> <property name="maxPoolSize" value="${maxPoolSizea}"></property> <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 --> <property name="maxIdleTime" value="300" /> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 --> <property name="acquireIncrement" value="5" /> <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements 属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。 如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0 --> <property name="maxStatements" value="0" /> <!--每60秒检查所有连接池中的空闲连接。Default: 0 --> <property name="idleConnectionTestPeriod" value="300" /> <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 --> <property name="acquireRetryAttempts" value="30" /> <!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试 获取连接失败后该数据源将申明已断开并永久关闭。Default: false --> <property name="breakAfterAcquireFailure" value="true" /> <!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable 等方法来提升连接测试的性能。Default: false --> <property name="testConnectionOnCheckout" value="false" /> <!-- 提示:db.properties中的key尽量不要与这里name的值一致,会引起冲突 --> </bean> <!-- 3. 配置SessionFactory --> <!-- 实例化LocalSessionFactoryBean类,需要在pom.xml中引入spring-orm依赖 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <!-- 3.1 引入数据源 --> <property name="dataSource" ref="dataSource"></property> <!-- 3.2 加载hibernate核心配置文件 (hibernate核心文件交给spring来加载) --> <!-- <property name="configLocation" value="classpath:hibernate.cfg.xml"></property> --> <property name="hibernateProperties"> <props> <prop key="hibernate.connection.release_mode">after_statement</prop> <!-- <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> --> </props> </property> <!-- 3.3 加载hibernate映射文件 --> <property name="mappingLocations" value="classpath:com/waterworks/pojo/*.hbm.xml"></property> <!-- *.hbm.xml代表加载entity下面所有的.hbm.xml文件 删除掉hibernate.cfg.xml中<mapping>对应的映射文件 提示:hibernate.cfg.xml中的show_sql和format_sql其实也可以写到db.properties中,那么hibernate.cfg.xml文件就可以删除掉了。 --> </bean> <!-- 4. 配置事务 --> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 5. 配置事务的属性 --> <!-- 在<beans>标签中复制xmlns:aop="http://www.springframework.org/schema/aop" 修改成:xmlns:tx="http://www.springframework.org/schema/tx" 复制最后一行:http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd 改成:http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd 这样<tx:>就可以使用。 <tx:advice>表示通知/增强,AOP在项目中是通过事务来体现,而事务的底层是通知。 --> <tx:advice id="myAdvice" transaction-manager="transactionManager"> <!-- 事务的属性 --> <tx:attributes> <!--当方法以add开头,如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中 --> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="*" /> </tx:attributes> </tx:advice> <!-- 6. 配置事务的切点 --> <!-- 指明哪些包里的哪些类,哪些类中的哪些方法要事务 --> <aop:config> <!-- * com.spring.dao.*.*(..)表示com.spring.dao包下所有的类,所有的方法 --> <aop:pointcut expression="execution(* com.waterworks.dao.*.*())" id="myCut" /> <!--注意:需要再次引入一个依赖:spring-aspects,用于解析上面这个表达式 --> <!-- 关联事务的属性 --> <aop:advisor advice-ref="myAdvice" pointcut-ref="myCut" /> </aop:config> </beans> struts.xml(当中class="{2}" 通配符指定的是action Bean的id)<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <struts> <package name="default" extends="struts-default"> <global-allowed-methods>regex:.*</global-allowed-methods> <action name="*_*" class="{2}" method="{1}"> <result name="success">success.jsp</result> </action> </package> </struts> log4j2-test.xml<?xml version="1.0" encoding="UTF-8"?> <configuration status="error"> <!-- 先定义所有的appender --> <appenders> <!-- 这个输出控制台的配置 --> <Console name="Console" target="SYSTEM_OUT"> <!-- 控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) --> <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/> <!-- 这个都知道是输出日志的格式 --> <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> </Console> <!-- 文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用 --> <!-- append为TRUE表示消息增加到指定文件中,false表示消息覆盖指定的文件内容,默认值是true --> <File name="log" fileName="log/test.log" append="false"> <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> </File> <!-- 添加过滤器ThresholdFilter,可以有选择的输出某个级别以上的类别 onMatch="ACCEPT" onMismatch="DENY"意思是匹配就接受,否则直接拒绝 --> <File name="ERROR" fileName="logs/error.log"> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/> </File> <!-- 这个会打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 --> <RollingFile name="RollingFile" fileName="logs/web.log" filePattern="logs/$${date:yyyy-MM}/web-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/> <SizeBasedTriggeringPolicy size="2MB"/> </RollingFile> </appenders> <!-- 然后定义logger,只有定义了logger并引入的appender,appender才会生效 --> <loggers> <!-- 建立一个默认的root的logger --> <root level="trace"> <appender-ref ref="RollingFile"/> <appender-ref ref="Console"/> <appender-ref ref="ERROR" /> <appender-ref ref="log"/> </root> </loggers> </configuration>web.xml<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>Archetype Created Web Application</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-*.xml</param-value> </context-param> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>*.action</url-pattern> </filter-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
2021年12月08日
188 阅读
0 评论
0 点赞
2021-12-08
初识Spring(一)
Spring概述Spring是一款开源的轻量级框架Spring是一个设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此他将面向接口的编程思想贯穿整个系统应用。Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的Java SE/EE full-stack(一站式)轻量级开源框架。Spring在Java EE三层结构中,每一层都提供不同的解决技术,形成一种Spring生态,如: WEB层 SpringMVC SERVICE层 Spring的IOC DAO层 jdbcTemplate 特点 使层与层之间依赖于接口 Spring的bean工厂为我们创建对象,不需要程序自己new对象了(IOC:Inverse of control控制反转;DI:depandency injection依赖注入) 可以管理事务 可以对其他框架进行管理(Struts2, Hibernate, mybatis等) 可以使用 spring自带的springMVC框架 可以使用spring的JDBC模板jdbcTemplate Spring核心部分Spring是一个轻量级的IOC和AOP的容器。其两大核心部分是:IOC(DI) 控制反转(依赖注入)控制反转(依赖注入),不是一种技术,而是一种设计思想,即通过XML配置或注解的方式实例化对象(Bean),然后交给Spring容器控制,如项目中想使用对象,从容器中取用(依赖注入)。而非通过Java硬代码中的new来实例化对象。AOP:面向切面(方面)编程即应用程序在扩展功能时不修改源代码实现功能的扩展。Spring 框架的一个关键组件是面向方面的程序设计(AOP)框架。一个程序中跨越多个点的功能被称为横切关注点,这些横切关注点在概念上独立于应用程序的业务逻辑。有各种各样常见的很好的关于方面的例子,比如日志记录、声明性事务、安全性,和缓存等等。
2021年12月08日
134 阅读
0 评论
0 点赞
2021-12-08
初识Python(一)
Python也是一个类似于Java面向对象的编程语言优点 简单、易学免费、开源:Python是FLOSS(自由/开放源码软件)之一。使用者可以自由地发布这个软件的拷贝、阅读它的源代码、对它做改动、把它的一部分用于新的自由软件中。FLOSS是基于一个团体分享知识的概念。可移植性、解释性:一个用编译性语言比如C或C++写的程序可以从源文件(即C或C++语言)转换到一个你的计算机使用的语言(二进制代码,即0和1)。这个过程通过编译器和不同的标记、选项完成。运行程序的时候,连接/转载器软件把你的程序从硬盘复制到内存中并且运行。而Python语言写的程序不需要编译成二进制代码。你可以直接从源代码运行 程序。在计算机内部,Python解释器把源代码转换成称为字节码的中间形式,然后再把它翻译成计算机使用的机器语言并运行。这使得使用Python更加简单。也使得Python程序更加易于移植。面向对象:Python既支持面向过程的编程也支持面向对象的编程。在“面向过程”的语言中,程序是由过程或仅仅是可重用代码的函数构建起来的。在“面向对象”的语言中,程序是由数据和功能组合而成的对象构建起来的。可扩展性:如果需要一段关键代码运行得更快或者希望某些算法不公开,可以部分程序用C或C++编写,然后在Python程序中使用它们。可嵌入性:可以把Python嵌入C/C++程序,从而向程序用户提供脚本功能。丰富的库:Python标准库确实很庞大。它可以帮助处理各种工作,包括正则表达式、文档生成、单元测试、线程、数据库、网页浏览器、CGI、FTP、电子邮件、XML、XML-RPC、HTML、WAV文件、密码系统、GUI(图形用户界面)、Tk和其他与系统有关的操作。这被称作Python的“功能齐全”理念。除了标准库以外,还有许多其他高质量的库,如wxPython、Twisted和Python图像库等等。规范的代码:Python采用强制缩进的方式使得代码具有较好可读性。而Python语言写的程序不需要编译成二进制代码。缺点单行语句和命令行输出问题:很多时候不能将程序连写成一行,如import sys;for i in sys.path:print i。而perl和awk就无此限制,可以较为方便的在shell下完成简单程序,不需要如Python一样,必须将程序写入一个.py文件。独特的语法这也许不应该被称为局限,但是它用缩进来区分语句关系的方式还是给很多初学者带来了困惑。即便是很有经验的Python程序员,也可能陷入陷阱当中。运行速度慢:这里是指与C和C++相比。#默认情况下 Python3的源码文件以UTF-8编码,所有字符串都是unicode字符串 #以下是定义源文件使用UTF-8编码 # -*- coding: UTF-8 -*- #标识符 #1.第一个字符必须是字母或者下划线 #2.标识符的其他部分由字母、数字和下划线组成 #3.标识符区分大小写 #python的注释分为 #号、'''和""" ''' 多行注释 ''' """ 多行注释 """ #行与缩进 #Python使用缩进来表示代码块,不需要{} if True: print("True") else: print("False") # 结果为 True # if True: # print("True") # else: # print("False") # print(9) #此行代码缩进不一致,运行会报错 #单独一句代码必须顶格书写 不然会报错 #多行语句 total="123"+\ "456" print(total) # 输出:123456 #多行语句用\实现连接 #数字类型(Number) #Python中数字有四种类型:整数、布尔型、浮点型和复数 #int 整数 没有长度限制 #bool 布尔型 True or False #float 浮点型 如1.23、3E-2 #complex 复数 如1+2j、1.1+2.2j #字符串(Stirng) #Python中单引号和双引号使用一样 #可用三引号"""或'''可指定一个多行字符串,其输出格式和输入格式一样 #转义符\,在字符串前面加r可以使\不发生转义 如r"\"999" 输出为 \"999 #按字面意义的级联字符串 如"123""999" 会自动转成123999,也可用+连接在一起 #字符串的两种索引方式,从左往右以0开始,从右往左以-1开始 #截取语法:变量[起始下标:尾下标] #声明变量 #格式 变量名=变量值 a="湖南" print(a) #结果 湖南 print(type(a)) # type()查看类型 <class 'str'> b='长沙' print(b) #结果 长沙 print(type(b)) # type()查看类型 <class 'str'> # \转义 c="\"999" print(c) #结果 "999 # \n 换行 d="000\n123" print(d) # \t 制表 e="abcd\tefg" print(e) #结果 abcd efg # r 不需要转义 f=r"\"你好" print(f) #结果 \"你好 #整数 num=1123123123123333333333131212113 print(num) #结果1123123123123333333333131212113 print(type(num)) # type()查看类型 <class 'int'> n=1_2_3 print(n) #结果123 print(type(n)) # type()查看类型 <class 'int'> #进制 #十进制不能以0开头 #二进制以0b开头 #八进制以0o开头 #十六进制以0x开头 #以其他进制定义的整数输出结果均为十进制 j=0o1331 print(j) #结果为729 #类型转换 aa="123" print(type(aa)) # type()查看类型 <class 'str'> print("aa ="+aa) # 结果 aa =123 aa=123 print(type(aa)) # type()查看类型 <class 'int'> print("aa ="+str(aa)) # 结果 aa =123 如果不转字符串则会报错 #aa最开始是字符串类型 后面赋值是int类型 aa可以赋任何类型的值 print("aa =",aa) # 结果 aa = 123 不需要转类型
2021年12月08日
101 阅读
0 评论
0 点赞
2021-12-08
Python(二)运算符与条件控制及while循环打印菱形
#运算符 #算数运算符 # + 加 1+1结果为2 # - 减 1-1结果为0 # * 乘 2*2结果为4 # / 除 2/2结果为1 # % 取模 2%2结果为0 # ** 幂 2**2结果为4 # // 整除 2//2结果为1 #赋值运算符 a=2 a+=1 #a=a+1 a-=1 #a=a-1 a*=1 #a=a*1 a**=3 #a=a*a*a a/=2 #a=a/2 a//=3 #a=a//3 除不尽时 取整 a%=2 #取模 a=a%2 print(True-1) #结果为0,1-1=0 (True==1,False==0) print(25**0.5) #开平方 #比较运算符 print(True==1) # 等于号 结果为True (True==1,False==0) print("1">"0") # 大于号 结果为True 可比较字符串 根据哈希值比较 print(1!=2) # 不等于 结果为True 1不等于2 print(1<2) # 小于号 结果为True 1小于2 print(2>=2) # 大于等于 结果为True 2大于或等于2 print(2<=2) # 小于等于 结果为True 2小于或等于2 #位运算符 #位运算符是把数字转为二进制来进行计算 # 运算符 描述 实例 #a 为 60,b 为 13 #二进制格式为 # a = 0011 1100 # b = 0000 1101 # & 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 (a & b) 输出结果 12 ,二进制解释: 0000 1100 # a&b = 0000 1100 # | 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 (a | b) 输出结果 61 ,二进制解释: 0011 1101 # a|b = 0011 1101 # ^ 按位异或运算符:当两对应的二进位相异时,结果为1 (a ^ b) 输出结果 49 ,二进制解释: 0011 0001 # a^b = 0011 0001 # ~ 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1。~x 类似于 -x-1 (~a ) 输出结果 -61 ,二进制解释: 1100 0011, 在一个有符号二进制数的补码形式。 # ~a = 1100 0011 # << 左移动运算符:运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。 a << 2 输出结果 240 ,二进制解释: 1111 0000 # >> 右移动运算符:把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数 a >> 2 输出结果 15 ,二进制解释: 0000 1111 #逻辑运算符 and、 or、 not # 以下假设变量 a 为 10, b为 20 # and x and y 布尔"与" - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。 (a and b) 返回 20。 # or x or y 布尔"或" - 如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值。 (a or b) 返回 10。 # not not x 布尔"非" - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 not(a and b) 返回 False a = 10 b = 20 print(a and b) #结果为20 print(a<b and a==10) #结果为True,两边同时为True则为True print(1==1 or 1>2) #结果为True 一边为True在,则为True print(not(1==1)) #1==1为True ,加上not则取非 True则变False,False变True #三元运算 # 结果1 if 条件 else 结果2 print("1大于0") if 1>0 else print("1小于0") #成员运算符 # Python还支持成员运算符,测试实例中包含了一系列的成员,包括字符串,列表或元组。 # in 如果在指定的序列中找到值返回 True,否则返回 False。 x 在 y 序列中 , 如果 x 在 y 序列中返回 True。 # not in 如果在指定的序列中没有找到值返回 True,否则返回 False。 x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。 a = 1 b = 20 arr = [1, 2, 3, 4, 5 ]; if a in arr: print("arr中存在a变量") #在arr中找到变量a的值则输出 else: print("arr中不存在a变量") #在arr没有中找到变量a的值则输出 if b not in arr: print("arr中不存在b变量") #在arr中没有找到变量b的值则输出 else: print("arr中存在b变量")#在arr中找到变量b的值则输出 #身份运算符 身份运算符用于比较两个对象的存储单元 # is is 是判断两个标识符是不是引用自一个对象 x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False # is not is not 是判断两个标识符是不是引用自不同对象 x is not y , 类似 id(a) != id(b)。如果引用的不是同一个对象则返回结果 True,否则返回 False。 n = 20 m = 10 if ( n is m ): # 也可 if ( 20 is 20 ): print ("n 和 m 有相同的标识") #如果n和m里的值相同 else: print ("n 和 m 没有相同的标识") #如果n和m里的值不相同 if ( id(n) == id(m) ): print ("n 和 m 有相同的标识") #如果n和m里的值相同 else: print ("n 和 m 没有相同的标识") #如果n和m里的值不相同 m=20 if ( n is not m ): print ("n 和 m 没有相同的标识") #如果n和m里的值不相同 else: print ("n 和 m 有相同的标识") #如果n和m里的值相同 #条件控制 #行与缩进 #Python使用缩进来表示代码块,不需要{} if True: print("True") else: print("False") # 结果为 True # if True: # print("True") # else: # print("False") # print(9) #此行代码缩进不一致,运行会报错 #单独一句代码必须顶格编写 不然会报错 #也可编写为: # if 条件: # 结果 # elif 条件: # 结果 # else: # 结果 #控制台输入 #name= input("请输入你的姓名:")#控制台输入回车,会将输入的值赋给name #注意:因为控制台输入的值都是string类型,如果要做int类型使用要转类型 #print(name) #循环之while循环 i=1 while i<=9: j=1 while j<=i: print(j,"*",i,"=",(j*i)," ",end="") # j,"*",i,"=",(j*i)," " 为j*i=(j*i)【," "为在最后添加空格】 end=""为print不换行 j+=1 print() i+=1 #菱形 #-----------------上半部分 y=1 while y<10: #打印9行 k=1 p=1 while k<10-y: #第一次八个空格 print(" ",end="") k+=1 while p<y*2: #第一次一个* print("*",end="") p+=1 print("") #换行 y+=1 #-----------------下半部分 y = 9 while y<10 and y>0: k=1 p=1 while k<=10-y: #第一次一个空格 print(" ",end="") k+=1 y-=1 while p<=y*2-1:#1=8*2-1 第一次十五个* print("*",end="") p+=1 print("")
2021年12月08日
165 阅读
0 评论
0 点赞
2021-12-08
XML中声明DTD、XML解析、什么是反射?
什么是格式良好XML 1 有且只有一个根元素 2 XML标签大小写正确区分 3 正确使用结束标签 4 正确嵌套标签 5 使用了合法的标签名 6 定义有效的属性 XML中声明DTD<!Doctype root[]> 定义元素的语法<!ELEMENT element-name (type)>元素的分类element-name:元素名称<!ELEMENT element-name EMPTY> //空元素<!ELEMENT element-name (#PCDATA)> //文本元素<!ELEMENT element-name (e1,e2)> //混合元素,标签里包含了其他的元素 元素的限制, :顺序| :或次数: +(1~n) *(0~n) ?(0或1) 没有(1) 属性定义的语法att_name:属性名<!ATTLIST element-nameatt_name type> 类型:ID :唯一(男|女) :列表“值” :默认值CDATA :文本IDREF :外键#REQUIRED :不为空#IMPLIED :允许为空 XML中的特殊符号& (逻辑与) &> (大于) << (小于) >“ (双引号) "‘ (单引号) ' DTD列子:config.xml文件 <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE config[<!ELEMENT config (action*)><!ELEMENT action (forward*)><!ELEMENT forward EMPTY><!ATTLIST action path CDATA #REQUIRED type CDATA #REQUIRED><!ATTLIST forward name CDATA #REQUIRED path CDATA #REQUIRED redirect (true|false) "false">]><!--config标签:可以包含0~N个action标签 --><config><!-- action标签:可以饱含0~N个forward标签 path:以/开头的字符串,并且值必须唯一 非空 type:字符串,非空 --><action path="/regAction" type="test.RegAction"><!-- forward标签:没有子标签; name:字符串,同一action标签下的forward标签name值不能相同 ; path:以/开头的字符串redirect:只能是false|true,允许空,默认值为false --><forward name="failed" path="/reg.jsp" redirect="false" /><forward name="success" path="/login.jsp" redirect="true" /></action> <action path="/loginAction" type="test.LoginAction"><forward name="failed" path="/login.jsp" redirect="false" /><forward name="success" path="/main.jsp" redirect="true" /></action></config> XML的作用:配置:*.properties*.XML 数据交换XMLWebserviceJson JAVA配置文件的三种配置位置及读取方式 XML和*.properties(属性文件) 存储位置src根目录下 Xxx.class.getResourceAsStream("/config.properties");与读取配置文件的类在同一包 Xxx.class.getResourceAsStream("config2.properties");WEB-INF(或其子目录下) ServletContext application = this.getServletContext(); InputStream is = application.getResourceAsStream("/WEB-INF/config3.properties"); XML解析1.properties//输入流 类名.class.getResourceAsStream 填写配置文件的地址// /db.properties为src目录下InputStream is = Test.class.getResourceAsStream("/db.properties");//解析Properties properties = new Properties();properties.load(is); //键值对的存储方式,根据键的名称获得值 Stringuname = properties.getProperty("uname");String user = properties.getProperty("user");String password = properties.getProperty("password");System.out.println(uname+" "+user+" "+password); 2.xmlInputStream is = Test.class.getResourceAsStream("/students.xml"); SAXReader saxReader = new SAXReader();Document read = saxReader.read(is); Stringxpath="/students/student"; //得到xml文件里students下所有student元素节点List<Node>li = read.selectNodes(xpath);for (Node node :li) { //student元素节点Element studentElement = (Element) node; // 1.得到student中的sid属性节点Attribute sidAttribute = studentElement.attribute("sid");//得到sid中的文本节点Stringsid = sidAttribute.getText(); // 2.得到student中sid属性节点里的文本节点Stringsid = studentElement.attributeValue("sid"); //student下的name元素节点Element nameElement = (Element)studentElement.selectSingleNode("name");//得到name元素节点中的文本节点String name = nameElement.getText();System.out.println(sid+","+name);} //得到某个元素节点InputStream is =Test.class.getResourceAsStream("/students.xml"); SAXReader saxReader =new SAXReader();Documentread = saxReader.read(is);//得到student元素节点下一个sid为s003的name元素节点String xpath="/students/student[@sid='s003']/name";ElementnameElement = (Element)read.selectSingleNode(xpath);System.out.println(nameElement.getText());
2021年12月08日
112 阅读
0 评论
0 点赞
2021-12-08
通过域名访问web项目
1.首先把项目导出成*.war文件 2.把项目放到Linux系统tomcat中的webapps下(到此步骤重启tomcat可以通过ip地址加端口号加项目名访问项目如: 192.168.44.199:8080/项目名/index.jsp) 3.配置域名解析(注意:不管是在腾讯云或阿里云购买的域名,记得配置解析,不然不能通过域名访问项目记录值里填的是对应的) 4.打开tomcat中conf文件中的server.xml进行修改(此步骤为更改端口配置域名访问)在把此文件中的defaultHost的值改为自己的域名 ------------------------------------------------------在把name改为域名如果没有context则添加一行docBase 填的是对应项目名记得在安全组里添加80端口最后重启tomcat就可以通过域名访问项目
2021年12月08日
181 阅读
0 评论
0 点赞
2021-12-08
网络协议篇
(一)网络基础知识1)Http和Https的区别?答:Http协议运行在TCP之上,明文传输,客户端与服务器端都无法验证对方的身份;Https是身披SSL(Secure Socket Layer)外壳的Http,运行于SSL上,SSL运行于TCP之上,是添加了加密和认证机制的HTTP。二者之间存在如下不同: 端口不同:Http与Http使用不同的连接方式,用的端口也不一样,前者是80,后者是443; 资源消耗:和HTTP通信相比,Https通信会由于加减密处理消耗更多的CPU和内存资源; 开销:Https通信需要证书,而证书一般需要向认证机构购买; Https的加密机制是一种共享密钥加密和公开密钥加密并用的混合加密机制。2)对称加密与非对称加密答:对称密钥加密是指加密和解密使用同一个密钥的方式,这种方式存在的最大问题就是密钥发送问题,即如何安全地将密钥发给对方;而非对称加密是指使用一对非对称密钥,即公钥和私钥,公钥可以随意发布,但私钥只有自己知道。发送密文的一方使用对方的公钥进行加密处理,对方接收到加密信息后,使用自己的私钥进行解密。由于非对称加密的方式不需要发送用来解密的私钥,所以可以保证安全性;但是和对称加密比起来,它非常的慢,所以我们还是要用对称加密来传送消息,但对称加密所使用的密钥我们可以通过非对称加密的方式发送出去。3)三次握手与四次挥手答:(1). 三次握手(我要和你建立链接,你真的要和我建立链接么,我真的要和你建立链接,成功) 第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。 第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。 第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。 (2). 四次挥手(我要和你断开链接;好的,断吧。我也要和你断开链接;好的,断吧): 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。此时TCP链接处于半关闭状态,即客户端已经没有要发送的数据了,但服务端若发送数据,则客户端仍要接收。 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。 (3). 通俗一点的理解就是: 4)为什么 TCP 链接需要三次握手,两次不可以么?答:“三次握手” 的目的是为了防止已失效的链接请求报文突然又传送到了服务端,因而产生错误。 正常的情况:A 发出连接请求,但因连接请求报文丢失而未收到确认,于是 A 再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接。A 共发送了两个连接请求报文段,其中第一个丢失,第二个到达了 B。没有 “已失效的连接请求报文段”。 现假定出现了一种异常情况:即 A 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 B。本来这是一个早已失效的报文段。但 B 收到此失效的连接请求报文段后,就误认为是 A 再次发出的一个新的连接请求。于是就向 A 发出确认报文段,同意建立连接。 假设不采用“三次握手”,那么只要 B 发出确认,新的连接就建立了。由于现在 A 并没有发出建立连接的请求,因此不会理睬 B 的确认,也不会向 B 发送数据。但 B 却以为新的运输连接已经建立,并一直等待 A 发来数据。这样,B 的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。5)为什么要四次挥手?答:TCP 协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP 是全双工模式,这就意味着,当 A 向 B 发出 FIN 报文段时,只是表示 A 已经没有数据要发送了,而此时 A 还是能够接受到来自 B 发出的数据;B 向 A 发出 ACK 报文段也只是告诉 A ,它自己知道 A 没有数据要发了,但 B 还是能够向 A 发送数据。所以想要愉快的结束这次对话就需要四次挥手。6)TCP 协议如何来保证传输的可靠性答:TCP 提供一种面向连接的、可靠的字节流服务。其中,面向连接意味着两个使用 TCP 的应用(通常是一个客户和一个服务器)在彼此交换数据之前必须先建立一个 TCP 连接。在一个 TCP 连接中,仅有两方进行彼此通信;而字节流服务意味着两个应用程序通过 TCP 链接交换 8 bit 字节构成的字节流,TCP 不在字节流中插入记录标识符。对于可靠性,TCP通过以下方式进行保证: 数据包校验:目的是检测数据在传输过程中的任何变化,若校验出包有错,则丢弃报文段并且不给出响应,这时TCP发送数据端超时后会重发数据; 对失序数据包重排序:既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。TCP将对失序数据进行重新排序,然后才交给应用层; 丢弃重复数据:对于重复数据,能够丢弃重复数据; 应答机制:当TCP收到发自TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒; 超时重发:当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段; 流量控制:TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制。TCP使用的流量控制协议是可变大小的滑动窗口协议。 7)客户端不断进行请求链接会怎样?DDos(Distributed Denial of Service)攻击?答:服务器端会为每个请求创建一个链接,并向其发送确认报文,然后等待客户端进行确认(1). DDos 攻击: 客户端向服务端发送请求链接数据包 服务端向客户端发送确认数据包 客户端不向服务端发送确认数据包,服务器一直等待来自客户端的确认 (2). DDos 预防:(没有彻底根治的办法,除非不使用TCP) 限制同时打开SYN半链接的数目 缩短SYN半链接的Time out 时间 关闭不必要的服务 8)GET 与 POST 的区别?答:GET与POST是我们常用的两种HTTP Method,二者之间的区别主要包括如下五个方面:(1). 从功能上讲,GET一般用来从服务器上获取资源,POST一般用来更新服务器上的资源;(2). 从REST服务角度上说,GET是幂等的,即读取同一个资源,总是得到相同的数据,而POST不是幂等的,因为每次请求对资源的改变并不是相同的;进一步地,GET不会改变服务器上的资源,而POST会对服务器资源进行改变;(3). 从请求参数形式上看,GET请求的数据会附在URL之后,即将请求数据放置在HTTP报文的 请求头 中,以?分割URL和传输数据,参数之间以&相连。特别地,如果数据是英文字母/数字,原样发送;否则,会将其编码为 application/x-www-form-urlencoded MIME 字符串(如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII);而POST请求会把提交的数据则放置在是HTTP请求报文的 请求体 中。(4). 就安全性而言,POST的安全性要比GET的安全性高,因为GET请求提交的数据将明文出现在URL上,而且POST请求参数则被包装到请求体中,相对更安全。(5). 从请求的大小看,GET请求的长度受限于浏览器或服务器对URL长度的限制,允许发送的数据量比较小,而POST请求则是没有大小限制的。为什么在GET请求中会对URL进行编码?我们知道,在GET请求中会对URL中非西文字符进行编码,这样做的目的就是为了 避免歧义。看下面的例子,针对 “name1=value1&name2=value2” 的例子,我们来谈一下数据从客户端到服务端的解析过程。首先,上述字符串在计算机中用ASCII吗表示为: 6E616D6531 3D 76616C756531 26 6E616D6532 3D 76616C756532 6E616D6531:name1 3D:= 76616C756531:value1 26:& 6E616D6532:name2 3D:= 76616C756532:value2 服务端在接收到该数据后就可以遍历该字节流,一个字节一个字节的吃,当吃到3D这字节后,服务端就知道前面吃得字节表示一个key,再往后吃,如果遇到26,说明从刚才吃的3D到26子节之间的是上一个key的value,以此类推就可以解析出客户端传过来的参数。现在考虑这样一个问题,如果我们的参数值中就包含=或&这种特殊字符的时候该怎么办?比如,“name1=value1”,其中value1的值是“va&lu=e1”字符串,那么实际在传输过程中就会变成这样“name1=va&lu=e1”。这样,我们的本意是只有一个键值对,但是服务端却会解析成两个键值对,这样就产生了歧义。那么,如何解决上述问题带来的歧义呢?解决的办法就是对参数进行URL编码:例如,我们对上述会产生歧义的字符进行URL编码后结果:“name1=va%26lu%3D”,这样服务端会把紧跟在“%”后的字节当成普通的字节,就是不会把它当成各个参数或键值对的分隔符。9)TCP与UDP的区别答:TCP (Transmission Control Protocol)和UDP(User Datagram Protocol)协议属于传输层协议,它们之间的区别包括: TCP是面向连接的,UDP是无连接的; TCP是可靠的,UDP是不可靠的; TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多的通信模式; TCP是面向字节流的,UDP是面向报文的; TCP有拥塞控制机制;UDP没有拥塞控制,适合媒体通信; TCP首部开销(20个字节)比UDP的首部开销(8个字节)要大; 10)TCP和UDP分别对应的常见应用层协议答:(1). TCP 对应的应用层协议: FTP:定义了文件传输协议,使用21端口。常说某某计算机开了FTP服务便是启动了文件传输服务。下载文件,上传主页,都要用到FTP服务。 Telnet:它是一种用于远程登陆的端口,用户可以以自己的身份远程连接到计算机上,通过这种端口可以提供一种基于DOS模式下的通信服务。如以前的BBS是-纯字符界面的,支持BBS的服务器将23端口打开,对外提供服务。 SMTP:定义了简单邮件传送协议,现在很多邮件服务器都用的是这个协议,用于发送邮件。如常见的免费邮件服务中用的就是这个邮件服务端口,所以在电子邮件设置-中常看到有这么SMTP端口设置这个栏,服务器开放的是25号端口。 POP3:它是和SMTP对应,POP3用于接收邮件。通常情况下,POP3协议所用的是110端口。也是说,只要你有相应的使用POP3协议的程序(例如Fo-xmail或Outlook),就可以不以Web方式登陆进邮箱界面,直接用邮件程序就可以收到邮件(如是163邮箱就没有必要先进入网易网站,再进入自己的邮-箱来收信)。 HTTP:从Web服务器传输超文本到本地浏览器的传送协议。 (2). UDP 对应的应用层协议: DNS:用于域名解析服务,将域名地址转换为IP地址。DNS用的是53号端口。 SNMP:简单网络管理协议,使用161号端口,是用来管理网络设备的。由于网络设备很多,无连接的服务就体现出其优势。 TFTP(Trival File Transfer Protocal):简单文件传输协议,该协议在熟知端口69上使用UDP服务 (3). 图示: 11)TCP 的拥塞避免机制答:拥塞:对资源的需求超过了可用的资源。若网络中许多资源同时供应不足,网络的性能就要明显变坏,整个网络的吞吐量随之负荷的增大而下降。拥塞控制:防止过多的数据注入到网络中,使得网络中的路由器或链路不致过载。拥塞控制的方法:(1). 慢启动 + 拥塞避免:慢启动:不要一开始就发送大量的数据,先探测一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小;拥塞避免:拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍,这样拥塞窗口按线性规律缓慢增长。 (2). 快重传 + 快恢复:快重传:快重传要求接收方在收到一个 失序的报文段 后就立即发出 重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。 快恢复:快重传配合使用的还有快恢复算法,当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半,但是接下去并不执行慢开始算法:因为如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将cwnd设置为ssthresh的大小,然后执行拥塞避免算法。 12)浏览器中输入:“www.xxx.com” 之后都发生了什么?请详细阐述。解析:经典的网络协议问题。答: 由域名→IP地址 寻找IP地址的过程依次经过了浏览器缓存、系统缓存、hosts文件、路由器缓存、 递归搜索根域名服务器。 建立TCP/IP连接(三次握手具体过程) 由浏览器发送一个HTTP请求 经过路由器的转发,通过服务器的防火墙,该HTTP请求到达了服务器 服务器处理该HTTP请求,返回一个HTML文件 浏览器解析该HTML文件,并且显示在浏览器端 这里需要注意: HTTP协议是一种基于TCP/IP的应用层协议,进行HTTP数据请求必须先建立TCP/IP连接 可以这样理解:HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。 两个计算机之间的交流无非是两个端口之间的数据通信,具体的数据会以什么样的形式展现是以不同的应用层协议来定义的。 13)什么是 HTTP 协议无状态协议?怎么解决Http协议无状态协议?答:HTTP 是一个无状态的协议,也就是没有记忆力,这意味着每一次的请求都是独立的,缺少状态意味着如果后续处理需要前面的信息,则它必须要重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就很快。HTTP 的这种特性有优点也有缺点: 优点:解放了服务器,每一次的请求“点到为止”,不会造成不必要的连接占用 缺点:每次请求会传输大量重复的内容信息,并且,在请求之间无法实现数据的共享 解决方案: 使用参数传递机制:将参数拼接在请求的 URL 后面,实现数据的传递(GET方式),例如:/param/list?username=wmyskxz问题:可以解决数据共享的问题,但是这种方式一不安全,二数据允许传输量只有1kb 使用 Cookie 技术 使用 Session 技术 14)Session、Cookie 与 Application答:Cookie和Session都是客户端与服务器之间保持状态的解决方案,具体来说,cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。(1). Cookie 及其相关 API :Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie,而客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器,服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。 (2). Session 及其相关 API:同样地,会话状态也可以保存在服务器端。客户端请求服务器,如果服务器记录该用户状态,就获取Session来保存状态,这时,如果服务器已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用;如果客户端请求不包含sessionid,则为此客户端创建一个session并且生成一个与此session相关联的sessionid,并将这个sessionid在本次响应中返回给客户端保存。保存这个sessionid的方式可以采用 cookie机制 ,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器;若浏览器禁用Cookie的话,可以通过 URL重写机制 将sessionid传回服务器。 (3). Session 与 Cookie 的对比: 实现机制:Session的实现常常依赖于Cookie机制,通过Cookie机制回传SessionID; 大小限制:Cookie有大小限制并且浏览器对每个站点也有cookie的个数限制,Session没有大小限制,理论上只与服务器的内存大小有关; 安全性:Cookie存在安全隐患,通过拦截或本地文件找得到cookie后可以进行攻击,而Session由于保存在服务器端,相对更加安全; 服务器资源消耗:Session是保存在服务器端上会存在一段时间才会消失,如果session过多会增加服务器的压力。 (4). Application:Application(ServletContext):与一个Web应用程序相对应,为应用程序提供了一个全局的状态,所有客户都可以使用该状态。15)滑动窗口机制答:由发送方和接收方在三次握手阶段,互相将自己的最大可接收的数据量告诉对方。也就是自己的数据接收缓冲池的大小。这样对方可以根据已发送的数据量来计算是否可以接着发送。在处理过程中,当接收缓冲池的大小发生变化时,要给对方发送更新窗口大小的通知。这就实现了流量的控制。16)常用的HTTP方法有哪些?答: GET: 用于请求访问已经被URI(统一资源标识符)识别的资源,可以通过URL传参给服务器 POST:用于传输信息给服务器,主要功能与GET方法类似,但一般推荐使用POST方式。 PUT: 传输文件,报文主体中包含文件内容,保存到对应URI位置。 HEAD: 获得报文首部,与GET方法类似,只是不返回报文主体,一般用于验证URI是否有效。 DELETE:删除文件,与PUT方法相反,删除对应URI位置的文件。 OPTIONS:查询相应URI支持的HTTP方法。 17)常见HTTP状态码答: 1xx(临时响应) 2xx(成功) 3xx(重定向):表示要完成请求需要进一步操作 4xx(错误):表示请求可能出错,妨碍了服务器的处理 5xx(服务器错误):表示服务器在尝试处理请求时发生内部错误 常见状态码: 200(成功) 304(未修改):自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容 401(未授权):请求要求身份验证 403(禁止):服务器拒绝请求 404(未找到):服务器找不到请求的网页 18)SQL 注入答:SQL注入就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。(1).SQL注入攻击的总体思路: 寻找到SQL注入的位置 判断服务器类型和后台数据库类型 针对不通的服务器和数据库特点进行SQL注入攻击 (2). SQL注入攻击实例:比如,在一个登录界面,要求输入用户名和密码,可以这样输入实现免帐号登录:用户名: ‘or 1 = 1 -- 密 码: 用户一旦点击登录,如若没有做特殊处理,那么这个非法用户就很得意的登陆进去了。这是为什么呢?下面我们分析一下:从理论上说,后台认证程序中会有如下的SQL语句:String sql = “select * from user_table where username=’ “+userName+” ’ and password=’ “+password+” ‘”;因此,当输入了上面的用户名和密码,上面的SQL语句变成:SELECT * FROM user_table WHERE username=’’or 1 = 1 – and password=’’分析上述SQL语句我们知道,username=‘ or 1=1 这个语句一定会成功;然后后面加两个-,这意味着注释,它将后面的语句注释,让他们不起作用。这样,上述语句永远都能正确执行,用户轻易骗过系统,获取合法身份。(3). 应对方法:1.参数绑定:使用预编译手段,绑定参数是最好的防SQL注入的方法。目前许多的ORM框架及JDBC等都实现了SQL预编译和参数绑定功能,攻击者的恶意SQL会被当做SQL的参数而不是SQL命令被执行。在mybatis的mapper文件中,对于传递的参数我们一般是使用#和$来获取参数值。当使用#时,变量是占位符,就是一般我们使用javajdbc的PrepareStatement时的占位符,所有可以防止sql注入;当使用$时,变量就是直接追加在sql中,一般会有sql注入问题。2.使用正则表达式过滤传入的参数19)XSS 攻击答:XSS是一种经常出现在web应用中的计算机安全漏洞,与SQL注入一起成为web中最主流的攻击方式。XSS是指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些脚本代码嵌入到web页面中去,使别的用户访问都会执行相应的嵌入代码,从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。(1). XSS攻击的危害: 盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号 控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力 盗窃企业重要的具有商业价值的资料 非法转账 强制发送电子邮件 网站挂马 控制受害者机器向其它网站发起攻击 (2). 原因解析: 主要原因:过于信任客户端提交的数据! 解决办法:不信任任何客户端提交的数据,只要是客户端提交的数据就应该先进行相应的过滤处理然后方可进行下一步的操作。 进一步分析细节:客户端提交的数据本来就是应用所需要的,但是恶意攻击者利用网站对客户端提交数据的信任,在数据中插入一些符号以及javascript代码,那么这些数据将会成为应用代码中的一部分了,那么攻击者就可以肆无忌惮地展开攻击啦,因此我们绝不可以信任任何客户端提交的数据!!! (3). XSS 攻击分类: 反射性 XSS 攻击(非持久性 XSS 攻击): 漏洞产生的原因是攻击者注入的数据反映在响应中。一个典型的非持久性XSS攻击包含一个带XSS攻击向量的链接(即每次攻击需要用户的点击),例如,正常发送消息:http://www.test.com/message.php?send=Hello,World! 接收者将会接收信息并显示Hello,World;但是,非正常发送消息:http://www.test.com/message.php?send=<script>alert(‘foolish!’)</script>! 接收者接收消息显示的时候将会弹出警告窗口! 持久性XSS攻击 (留言板场景): XSS攻击向量(一般指XSS攻击代码)存储在网站数据库,当一个页面被用户打开的时候执行。也就是说,每当用户使用浏览器打开指定页面时,脚本便执行。与非持久性XSS攻击相比,持久性XSS攻击危害性更大。从名字就可以了解到,持久性XSS攻击就是将攻击代码存入数据库中,然后客户端打开时就执行这些攻击代码。例如,留言板表单中的表单域:<input type=“text” name=“content” value=“这里是用户填写的数据”> 正常操作流程是:用户是提交相应留言信息 —— 将数据存储到数据库 —— 其他用户访问留言板,应用去数据并显示;而非正常操作流程是攻击者在value填写:<script>alert(‘foolish!’);</script> <!--或者html其他标签(破坏样式)、一段攻击型代码--> 并将数据提交、存储到数据库中;当其他用户取出数据显示的时候,将会执行这些攻击性代码。(4). 修复漏洞方针:漏洞产生的根本原因是 太相信用户提交的数据,对用户所提交的数据过滤不足所导致的,因此解决方案也应该从这个方面入手,具体方案包括: 将重要的cookie标记为http only, 这样的话Javascript 中的document.cookie语句就不能获取到cookie了(如果在cookie中设置了HttpOnly属性,那么通过js脚本将无法读取到cookie信息,这样能有效的防止XSS攻击); 表单数据规定值的类型,例如:年龄应为只能为int、name只能为字母数字组合。。。。 对数据进行Html Encode 处理 过滤或移除特殊的Html标签,例如: <script>, <iframe> , < for <, > for>, " for 过滤JavaScript 事件的标签,例如 “οnclick=”, “onfocus” 等等。 需要注意的是,在有些应用中是允许html标签出现的,甚至是javascript代码出现。因此,我们在过滤数据的时候需要仔细分析哪些数据是有特殊要求(例如输出需要html代码、javascript代码拼接、或者此表单直接允许使用等等),然后区别处理!20)OSI 网络体系结构与 TCP/IP 协议模型答:OSI 是一个理论上的网络通信模型,而 TCP/IP 则是实际上的网络通信标准。但是,它们的初衷是一样的,都是为了使得两台计算机能够像两个知心朋友那样能够互相准确理解对方的意思并做出优雅的回应。现在,我们对 OSI 七层模型的各层进行简要的介绍: 1). 物理层参考模型的最低层,也是OSI模型的第一层,实现了相邻计算机节点之间比特流的透明传送,并尽可能地屏蔽掉具体传输介质和物理设备的差异,使其上层(数据链路层)不必关心网络的具体传输介质。2). 数据链路层(data link layer)接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,拆装为位流形式的数据转发到物理层。这一层在物理层提供的比特流的基础上,通过差错控制、流量控制方法,使有差错的物理线路变为无差错的数据链路,即提供可靠的通过物理介质传输数据的方法。3). 网络层将网络地址翻译成对应的物理地址,并通过路由选择算法为分组通过通信子网选择最适当的路径。 4). 传输层(transport layer)在源端与目的端之间提供可靠的透明数据传输,使上层服务用户不必关系通信子网的实现细节。在协议栈中,传输层位于网络层之上,传输层协议为不同主机上运行的进程提供逻辑通信,而网络层协议为不同主机提供逻辑通信,如下图所示。 实际上,网络层可以看作是传输层的一部分,其为传输层提供服务。但对于终端系统而言,网络层对它们而言是透明的,它们知道传输层的存在,也就是说,在逻辑上它们认为是传输层为它们提供了端对端的通信,这也是分层思想的妙处。5). 会话层(Session Layer)会话层是OSI模型的第五层,是用户应用程序和网络之间的接口,负责在网络中的两节点之间建立、维持和终止通信。6). 表示层(Presentation Layer):数据的编码,压缩和解压缩,数据的加密和解密表示层是OSI模型的第六层,它对来自应用层的命令和数据进行解释,以确保一个系统的应用层所发送的信息可以被另一个系统的应用层读取。7). 应用层(Application layer):为用户的应用进程提供网络通信服务21)网络层的 ARP 协议工作原理?答:地址解析协议(ARP) 是通过解析网路层地址来找寻数据链路层地址的一个在网络协议包中极其重要的网络传输协议。网络层的ARP协议完成了IP地址与物理地址的映射。首先,每台主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址的对应关系。当源主机需要将一个数据包要发送到目的主机时,会首先检查自己ARP列表中是否存在该IP地址对应的MAC地址:如果有,就直接将数据包发送到这个MAC地址;如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。此ARP请求数据包里包括源主机的IP地址、硬件地址、以及目的主机的IP地址。网络中所有的主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致。如果不相同就忽略此数据包;如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个ARP响应数据包,告诉对方自己是它需要查找的MAC地址;源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息开始数据的传输。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。22)IP地址的分类答:整个的因特网就是一个单一的、抽象的网络。IP 地址就是给因特网上的每一个主机(或路由器)的每一个接口分配一个在全世界范围是唯一的 32 位标识符,它是一个逻辑地址,用以屏蔽掉物理地址的差异。IP地址编址方案将IP地址空间划分为A、B、C、D、E五类,其中A、B、C是基本类,D、E类作为多播和保留使用,为特殊地址。每个IP地址包括两个标识码(ID),即网络ID和主机ID。同一个物理网络上的所有主机都使用同一个网络ID,网络上的一个主机(包括网络上工作站,服务器和路由器等)有一个主机ID与其对应。A~E类地址的特点如下: A类地址:以0开头,第一个字节范围:0~127; B类地址:以10开头,第一个字节范围:128~191; C类地址:以110开头,第一个字节范围:192~223; D类地址:以1110开头,第一个字节范围为224~239; E类地址:以1111开头,保留地址 1). A类地址:1字节的网络地址 + 3字节主机地址,网络地址的最高位必须是“0”一个A类IP地址是指, 在IP地址的四段号码中,第一段号码为网络号码,剩下的三段号码为本地计算机的号码。如果用二进制表示IP地址的话,A类IP地址就由1字节的网络地址和3字节主机地址组成,网络地址的最高位必须是“0”。A类IP地址中网络的标识长度为8位,主机标识的长度为24位,A类网络地址数量较少,有126个网络,每个网络可以容纳主机数达1600多万台。A类IP地址的地址范围1.0.0.0到127.255.255.255(二进制表示为:00000001 00000000 00000000 00000000 - 01111110 11111111 11111111 11111111),最后一个是广播地址。A类IP地址的子网掩码为255.0.0.0,每个网络支持的最大主机数为256的3次方-2=16777214台。2). B类地址: 2字节的网络地址 + 2字节主机地址,网络地址的最高位必须是“10”一个B类IP地址是指,在IP地址的四段号码中,前两段号码为网络号码。如果用二进制表示IP地址的话,B类IP地址就由2字节的网络地址和2字节主机地址组成,网络地址的最高位必须是“10”。B类IP地址中网络的标识长度为16位,主机标识的长度为16位,B类网络地址适用于中等规模的网络,有16384个网络,每个网络所能容纳的计算机数为6万多台。B类IP地址地址范围128.0.0.0-191.255.255.255(二进制表示为:10000000 00000000 00000000 00000000—-10111111 11111111 11111111 11111111),最后一个是广播地址。B类IP地址的子网掩码为255.255.0.0,每个网络支持的最大主机数为256的2次方-2=65534台。3). C类地址: 3字节的网络地址 + 1字节主机地址,网络地址的最高位必须是“110”一个C类IP地址是指,在IP地址的四段号码中,前三段号码为网络号码,剩下的一段号码为本地计算机的号码。如果用二进制表示IP地址的话,C类IP地址就由3字节的网络地址和1字节主机地址组成,网络地址的最高位必须是“110”。C类IP地址中网络的标识长度为24位,主机标识的长度为8位,C类网络地址数量较多,有209万余个网络。适用于小规模的局域网络,每个网络最多只能包含254台计算机。C类IP地址范围192.0.0.0-223.255.255.255(二进制表示为: 11000000 00000000 00000000 00000000 - 11011111 11111111 11111111 11111111)。C类IP地址的子网掩码为255.255.255.0,每个网络支持的最大主机数为256-2=254台。4). D类地址:多播地址,用于1对多通信,最高位必须是“1110”D类IP地址在历史上被叫做多播地址(multicast address),即组播地址。在以太网中,多播地址命名了一组应该在这个网络中应用接收到一个分组的站点。多播地址的最高位必须是“1110”,范围从224.0.0.0到239.255.255.255。5). E类地址:为保留地址,最高位必须是“1111”23)IP地址与物理地址答:物理地址是数据链路层和物理层使用的地址,IP地址是网络层和以上各层使用的地址,是一种逻辑地址,其中ARP协议用于IP地址与物理地址的对应。24)影响网络传输的因素有哪些?答:将一份数据从一个地方正确地传输到另一个地方所需要的时间我们称之为响应时间。影响这个响应时间的因素有很多。 网络带宽:所谓带宽就是一条物理链路在 1s 内能够传输的最大比特数,注意这里是比特(bit)而不是字节数,也就是 b/s 。网络带宽肯定是影响数据传输的一个关键环节,因为在当前的网络环境中,平均网络带宽只有 1.7 MB/s 左右。 传输距离:也就是数据在光纤中要走的距离,虽然光的传播速度很快,但也是有时间的,由于数据在光纤中的移动并不是走直线的,会有一个折射率,所以大概是光的 2/3,这个时间也就是我们通常所说的传输延时。传输延时是一个无法避免的问题,例如,你要给在杭州和青岛的两个机房的一个数据库进行同步数据操作,那么必定会存在约 30ms 的一个延时。 TCP 拥塞控制:我们知道 TCP 传输是一个 “停-等-停-等” 的协议,传输方和接受方的步调要一致,要达到步调一致就要通过拥塞控制来调节。TCP 在传输时会设定一个 “窗口”,这个窗口的大小是由带宽和 RTT(Round-Trip Time,数据在两端的来回时间,也就是响应时间)决定的。计算的公式是带宽(b/s)xRTT(s)。通过这个值就可以得出理论上最优的 TCP 缓冲区的大小。Linux 2.4 已经可以自动地调整发送端的缓冲区的大小,而到 Linux 2.6.7 时接收端也可以自动调整了。 本文转自https://www.cnblogs.com/bokeyuanlongbin/p/9072399.html
2021年12月08日
181 阅读
0 评论
0 点赞
1
...
4
5
6
...
20