开发者学堂课程【高校精品课-上海交通大学 -互联网应用开发技术:SSH】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/76/detail/15771
SSH
内容介绍:
一、 SSH-Annotation
二、数据储存-NOSQL & MONGODB
一、 SSH-Annotation
做一个工程,是将之前讲解的几个框架进行了融合。如果不使用,可全占用Spring。
Spring core既依赖输入的,包括Concrolete接受前端请求+JPA,也可以做数据库访问。意思是:如果前端接受请求的都是struts的Action,数据库访问的H指的是hibernate,SSH的第二个S指的是使用spring,既两个中有个spring,靠其去执行依赖租户,这样的三个东西如何整合到一起成为一个工程。
因为这也是一种解决方案,所以要进行讲解,因为在外面发现有些公司是这样进行开发的。
需要注意的是:
1、全部都是最新版本latest,按最新版本的这三个东西进行集成。
2、全部使用Annotation,没有书写xml文件。下面对集成的方案进行讲解。
1、SshApplication,java
首先是该工程是什么?为了简化期间,做了有关person的代码。接着是Spring Boot的工程。既Spring Boot的工程为如下代码:@SpringBootApplication public class SshApplication {
public static void main(String[] args) {
SpringApplication.run(SshApplication.class args);
}
}
上面代码类似于系统生成后没有执行。在其里面可以看到一个action目录,里面含有struts的一些action既JSONDDataAction PersonAction WelcomeAction。既和spring conturole意思一样,它在接收前端的请求,action调用service。
其中里面service为了讲解刚才的概念,将实线类放入实线包里,service里的子包impl,就有service的接口PersonService和实线类PersonServiceImpl,service Dao的接口PersonDao和实线类impl,接着访问entity,只是进行简化,没有分为两层,既直接简化person,既访问person。这一部分既dao、impl、personDao与hibernate相关,impl PersonServiceImpl PersonService包括前面有些注入的参数配置都是靠spring实现,AppConfig是spring注入的依据。
Struts.xml在描述如何接受请求,如何调度。后面有两个页面,页面为左边所看到的,实际上后台是这个结构,前台应是read或者是VUE,前后台传递为JSON,为了体现概念,放入Get Persons 和Get JSON。在点击时既可看到后台组装的对象[[“54”,”Cao”,”Cao”,][“50”,””Bei”,”Liu”],[“27”,”Quan”,”Sun”]]就将其传回。所以未来在index.html,error.html界面里,可能会欠脚本或者WEB-INF error.html index.html被挪走,变成前台的框架,前后端交互,后端为集成的东西。当Get Persons时会返回person的数组。
当Get JSON时会将数组里的内容转换成一个json,既把所有人转换成json,可看出使用大括号括出的三个json对象放入一个数组里,用age对其进行描述。如果只是getperson,直接组一个年龄和姓名和姓和名构成的一个三元组数组。写入这两个目的是:如果前后台传json,后台为基本为右边的框架,前端替换掉Reat框架。
2、struts.xml
这些在运行时要注意:struts.xml的写法。struts.xml仔细理解会发现需要讲解的东西很多,既展开讲解很多东西。
大体上主要东西有:第一、说清楚希望struts从哪里开始帮助托管,里面所有东西既当前工程的包,对应于org.reins.ssh包。第二、Struts的对象工厂全部托管给spring,让spring帮助生成所有对象,包括action对象,Struts会帮助创建action,既什么时候创建什么时候结束。
<constant name="struts.convention.exclude.pa rentClassLoader" value= "false">< /constant>
<constant name="struts.convention.default.parent.package"value="convention-default" />
<constant name="struts.convention.action.packages" value="org.reins.ssh.action"
以上代码一个都不能少,少一个会出错。
表达的含义:false struts.convention.default.parent.package
org.reins.ssh.action表示action在哪里,既托管的action在哪里。org.reins.ssh.action org.reins.ssh spring这三个东西需在标准的struts.xml里进行修改。
其他可使用strust.xml里的即可。
唯一注意的是:value="convention-default" /里必须写入convention-default。因直接使用default会出错,使用convention-default才能运行。因查找的官方文档也没有解释清楚,既这个文件大概上要按以上的要求进行书写。
3、AppConfig.java
书写一个配置类,configuration都位于里面,接着扫描所有空间ComponentScan,里面含有刚才书写的Bean。第一个Bean是表示:有一个personDao。
PersonDao要为PersonDaolmpl类,所以凡事需要获取personDao类型对象所通过创建PersonDaolmpl才能得到。
同样道理,第二个Bean表示:service和上面一样,通过创建Personservicelmpl既service实线类得到。
第三个Bean表示:如果代码要创建hibernate session.Factory对象。
创建一个org.hibernate.cfg.Configuration()配置类里面放入了键值对,有driver class驱动类既前面书写的满mysql驱动类,url位于哪个数据库,username用户名,password密码,dialect方言。在这里写好后,因这里是自己指定的数据库,在去说明在当前的工程里哪些类要进行托管,比如:Person.class。
这就相当于前一部分相当于写hibernate时的hibernate的配置文件既hibernate.hfgxml文件。Person.class表示为在这文件里有哪些类要进行托管。
第三个Bean下方的代码为原来的hibernate的配置文件,现靠Annotate编码的方式来实现,依靠config.buildSessionFactory()创建一个session.Factory。
第四个Bean是关于strutsPrepareAndExecuteFilter的内容,struts接管既拦截请求,写入StrutsPrepareAndExecuteFilter();有预备和执行过滤器,接着返回struts的过滤器。
Bean是从教程中拿的,不需要进行任何修改。写好后,就去写前端。
4、action/WelcomeAction.java
首先需要spring帮忙创建action这些类,所以书写的都是struts的action。需要spring帮助创建,就必须是spring的Controller才能帮忙创建。
后面为struts的Annotation,这是action,action在响应根目录“/“的请求,其返回结果是success,直接跳掉index.html里。底下显示,这种方法进出后,控制台上会输出Welcome,返回SUCCESS。因返回SUCCESS,因在success还没有找到,就跳到/index.html页面。
所以当用户直接访问根时,既为在toucaket控制台看到Welcome。直接跳到index.html页面。就产生这样的效果。
5、action/PersonAction.java
第二个Controller action响应的是,页面上的Get Persons 和Get JSON,对于Get Persons的action产生这样的动作,执行下面的方法。
同样,Controller是Spring,Autowired也是Spring,既针对接口编程,Spring会组装一个实现personservice对象。如何组装?在AppConfig.java配置里有。为Bean既PersonServicelmpl的一个对象。创建PersonService对象住入。Controller为Spring的Annotation。Autowired也为Spring的Annotation。getperson为struts的Annotation,既响应的是getperson这样的请求。如果有错error,会跳到error.html的页面上。
底下为getpersons,getpersons在控制台输出This is an action,因在调试时要注意有没有运行到这里。
底下就要通过service调取queryAll得到所有的元素,拿回来后得到一个数组Iterator<Person>it, Iterator<Person>it数组有迭代器进行迭代,迭代后,往ArrayList<JSONArray>放入JSONA对象,所以每次迭代一个it.next(),取出里面的年龄,姓名,既getAge Firstname Lastname三个。拿到后将其添加到JSONArray数组中,再将JSONArray数组添加到JSONA的personsion对象里,既数组类型的JSONA对象,既由JSONA构成的数组对象里。
6、action/PersonAction.java
然后将其整个转成一个字符串,JSONA.toJSONAStrina这些代码之前有提到,只是直接搬过来,没有进行特别处理。
在ServiceActionContext得到响应getResponse,将响应设置成utf-8,因可能带中文。
将响应写回去。因已将响应写回,所以在action/PersonAction.java的Result如果是success如何解决。
因只说明了如果是error的情况,如果在过程中如果抛错,直接跳到error.html,只要不抛错,因已经直接将响应写入,不需要在Result再写入如果是success如何解决。注意reponse.必须reset(),既将里面内容清空,接着往里放入东西。这就是过程。
7、action/JSONDDataAction.java
Annotation含有JSONDDataAction。Controller和Autowired都是spring的,但ParentPackage(“json-default”)为struts的。
ParentPackage(“json-default”)必须要这么书写,因是反JSONA对象,所以为json-default。
既刚才看到在struts.xml里的差异在哪,默认情况下,整个parent.package既为convention- default,既所有的action都是使用convention- default的值,
但在action/JSONDDataAction.java里面是JSONA情况下,需要改写。将值改成json-default。其他假设响应这个getjson请求,返回的结果为error就跳到error,html。
如果返回的结果类型为json类型,里面为jsonlist,其有个参数root,list,必须要这么写。然后请求过来后,进行执行,执行刚才的queryAll,如果queryAll里有东西,就不断输出person,既表示在后台将person的内容拿出,返回jsonlist,既与上面的jsonlist名字对应,对应后的作用为将list的值放入第二个的list里,返回迭代器的list的结果。既一旦query后,将所有的人全部放入第四个list里既附到这里面,如果返回类型为jsonlist,就将list作为Result结果返回。所以这里的action可能会短些。
8、service/PersonService.java
其他类就与前面的算法一致,既与前面讲解的后端是一样的,没有区别。既Service会使用Dao,实线类会使用Dao。这些都没有变化。
9、dao/impl/PersonDaoImpl.java
有变化的是PersonDaoImpl,因sessionFactory为注入,现用hibernate进行操作时,sessionFactory不需要进行定义既sessionFactory等于什么。
直接让spring注入,注入后就会将AppConfig.java里的参数去产生sessionFactory注入,于是dao/impl/PersonDaoImpl.java
底下就会产生sessionFactory。拿到sessionFactory才能产生执行逻辑。底下的逻辑跟之前提到的hibernate的实线一样,没有什么别的。
Service注释类型,同时是Repository,因在执行时,没有获取session,但没有在session上beghg tronvent,在底下comid,但这地方没写入,是因为在上面添加入了Transactional,Transactional表示底下的方法都要在一个事物里执行,关于事物先不展开讲解。如果学习数据库的话,可能会讲解该问题。
如果现在不了解,可忽略。但保证事物可操作。既底下就是为hibernate操作。
10、entity/Entity.java
底下的person还是原来的person,没有任何变化。
11、index.html
页面上实际只有两个链接,为GetPersons和GetJSON。GetPersons和GetJSON分别对应action/JSONDataAction.java的action进行操作。一个为GetJSON,一个为GetPersons。既他们就关联起来。
12、error.html
Error直接为一个页面,执行Sorry。既执行的效果为:
Get Person Get.JSON
当8080时既什么都不写时,就会跳到刚才的代码,既Welcome action。什么都不写相当于发送了如下的请求:
@Action(value = "/",results = {
@Result(name = " success" , Location
})
public String welcome() {
System.out.println( "Welcome!");
return SUCCESS;
}
}
首先struts将其既上面的代码进行拦截,struts里action类型对象的生成要依靠Spring。Struts拦截后,找到什么都不写的“/”action是靠@Action(value = "/",results = {
的action实现。
同时告诉Spring帮助创建Controller既创建Welcome Action对象,创建好后。由底下请求执行操作。底下的请求显示什么都不写,可在左边写入一个Welcome,写入Welcome后返回success。如返回类型为success,直接跳到index.html页面。index.html是什么?既为Get Person Get.JSON
的页面。所以什么都不写直接访问,直接跳到Get Person Get.JSON
的页面上,既背后发生的这些事情。Get Person返回[[“54”,”Cao”,”Cao”,][“50”,””Bei”,”Liu”],[“27”,”Quan”,”Sun”]]的结果。Get Person是如何执行的呢?
既getpersons发送了请求出去,Struts再次拦截后,Get Person是由@Action(value = "getperson"进行处理。接着告诉Spring对象,让Spring帮助创建Controller对象,既Spring创建Controller对象,创建对象后发现,Person Service需要spring帮助创建好让其注入。于是查找配置文件,配置文件为Configuration,配置文件里的PersonService,Spring会接管PersonService,返回PersonServiceImpl对象,所以创建了PersonServiceImpl类型的对象。创建对象时还会再依赖创建PersonServiceImpl时,发现PersonDao还要创建,于是又回去查找配置文件,发现PersonDao为PersonServiceImpl的对象,所以创建PersonDao 注入Autowired里。
PersonDaoImpl里需要注入一个sessionFactory,所以再回去看底下有sessionFactory。创建一个sessionFactory。sessionFactory再没有其他注入,就回到DaoImpl,并将其注入。看到底下没有对象创建的,既为对象创建好,现只是在创建对象,DaoImpl创建好后,就意味着Service可以注入,既为Service已经创建好。
Service已经创建好,既意味着action创建好。所以Dao action才创建好。创建好后,才执行getperson的方法,既在PersonService,调取query,接着调取上面内容就可执行进而得出结果。返回结果直接写入响应,既产生[[“54”,”Cao”,”Cao”,][“50”,””Bei”,”Liu”],[“27”,”Quan”,”Sun”]]的结果,这不是页面,只是返回的字符串。所以执行到这里后就不能返回,只能点击返回键进行返回,返回后调Get JOSNA,以下代码为Get JOSNA返回的结果:
[ ("age" :54," firstname" :"Cao","id":1,"lastname":"Cao"),l" age" :50," firstna
Get JOSNA过来后,还是Struts拦截掉。Struts拦截掉后,发现Get JOSNA为action在执行,所以去调用底下execute执行。同样是Controller告诉spring帮助创建public class JSONDataAction extends ActionSupport{对象,创建好后才能调用execute的方法。创建public class JSONDataAction extends ActionSupport{对象后,在注入PersonService,接着在里面执行。执行完后,看到组JSONA对象,既拿回来的list里包含所有的人后,将list放入JSONDataAction,返回一个jsonlist。上面如果返回类型为jsonlist,就将list对象塞入,既作为返回的参数,返回给用户。这时在前端可以拿到看到的,返回其实和刚才看到的道理一样写入响应的返回。既返回JOSNA的数组,代码如下:
[ ("age" :54," firstname" :"Cao","id":1,"lastname":"Cao"),l" age" :50," firstna,即为拿到。
所以看到的代码的过程表示为:当URL进入后台时,Struts dispatuther会拦截所有的请求,Struts dispatuther根据当前使用的action,Annotation描述的拦截的依据。Struts调度给某个action。但是这个action只知道给的是这个Action对象,现没有这个action对象,没法在上面执行。Struts需要Spring帮助管理action对象的创建工作,所以spring创建Action对象,创建的依据为APPConfig里的东西。既action里注入有Autowired,既依赖于一个personservice,就将personservice创建后设置给Action,既Action里的变量。Spring就是做这种操作。执行完操作后,action就拥有一个对象。Struts才能调用对象上的方法。比如:execute,将action注释到上面。调用完execute后,再返回。注意执行execute时,可能execute调用数据库,所以使用hibernate进行处理。这就是三者的关系。所以前端action是Struts,Spring执行所有依赖注入的管理。
hibernate执行DB的访问。既这就是三者之间的关系。现给出的例子是,后端在把JSON数据往回传,所以如果后端使用的是SSH的架构,可参考所给出的例子。
可写出一个例子,前段是JSON的东西,不在是前面为了单独去讲解每一块时所写的JSP的页面。所以前端现不需要靠JSON,前后端传递的就是JSON对象。所以做后端处理时,第一种方案为SSH,第二种方案为Spring的全占。前面都已进行讲解,可根据个人情况选择方案。如使用SSH,一开始,SSH也带分层架构,只是没有写impl这层,因为这块为了演示代码就没有写入。如果要加入orgDB的东西,要进行分层,分层结构一样,所以两种方案都可使用。不管使用哪种,后端的分层结构都类似。甚至层数都近似相同,都至少包含讲解的这些层。如果想往特殊的功能加入更多的层数,肯定是可以。至少要包含这里所有的层。这就是有关SSH例子有关的结构。
总结:
Spring是执行IoC,既针对的是接口编程,将接口和实线解开,需要Spring进行依赖注入。
Struts是执行MVC,既将后端和View解开,看到Struts在处理东西。返回什么样的数据类型。再将数据返回到前端进行处理。
Hibernate是执行ORM映射,解关系型数据库里表的结构与对象之间的映射。
关于这点前面反复讲解,表是受数据库二维表的限制,只能是一对一或者为一对多的关系。但对象不同,RelationDBM和Objects有数量的差异和关联方向的差异,Relation和Objects都解偶解开。以上三个都在一定程度上做解偶,因里面都含有解偶这个词Decoupling,所以解偶很关键,解偶主要是通过接口和实线进行分离的,但总的来说,是指系统上的解偶。解偶意味着各个部分可以独立的去演化,另外就是整个系统在分层。所以重点是Points。至于使用哪个工具,哪个框架。使用的是SSH还是全占Spring,都是没有差异,其实只是个工具。
回答问题:将它写入Config文件里,难道这不是不是源码吗?为什么好维护吗?
分两层面进行解释:如果将配置集中于一类,会比较好维护。比如:Year这个问题或者PersonAction。假设PersonAction里注入personservice,在后面JSONData还要注入PersonService。既在这两个地方写入PersonService代码等于New PersonServiceimpl类好,还是将其集中到一个地方,就像在AppConfig,java写好。其实一个地方到处去用,进行修改时集中于一点,就会比较好。第二层面:使用Annotation写java类,将Annotation注释到Java类上,既Configuration类也是这样写,这是一种java类。这是一种方案。还有一种方案,将所有的配置信息全部写入XML文件里。现先对比Java和XML这两种方案的优缺点:Java的优点既XM的缺点,XM的缺点既Java的优点。
使用Annotation是要在各个java类里相应的地方写入。就像前面的代码,如果是Entity,就在实体类person里写。
如果为action,这里既有spring又有Struts,分别在需要的地方写入。比如有的是方法上写,有的是在属性上写。Java缺点为散布在整个代码的各个地方,XML比较集中,将代码都写在一个地方。但各有各的好处,Java分散好处为:看类,就可看出要修饰谁。修饰type、execute,既这种方法。
如果不进行这种操作是不是有Struts的xml在描述action映射的类叫什么名字,映射为哪个URL。所以Result如果是success会出现什么情况;如果是error会出现什么情况,会跳转到哪里。所有的action配置全部集中于这个Struts.xml文件上,代码就不存在这些东西。很显然左边的写法就比较直观。Struts.xml就不是很直观。因所有东西都集中,再去找action位于哪里等。所以使用这种方式,一种是分散,一种是集中,但集中的方式不直观,分散的方式比较直观,所以之前需要这两种方式对等,既等价的。XML里直接写,确实是不需要源码。直接修改。使用Annotation,确实需要修改源码。在XML里写Annotation。
但是java比较直观,XML不太直观。即使是写了Annotation,在XML里使用Annotation确实是需要源码,但可把Annotation的配置相对独立的放入一个类里,修改的地方还是集中在一个地方。既能配置的属性集中一个地方去处理。确实两种方案各有各的优势,各有各的缺点。既有人习惯使用XML,有人习惯使用Annotation。
所以能注意到在第十二课的IoC例子里给出两个工程,spring 里的一个是Annotation,一个是XML。这两个效果是一模一样。但是实线方式不同。所以使用哪种方法都可以。但现在使用更多的是Annotation。因为比较直观。但是XML的方式仍然是兼容的。现在仍可使用。现在可看到使用框架的组合去开发后端,现给出的例子已经能保证前端后端传出的为JSONA,所以迭代二需要前端的工程现要与后端的能进行结合。
后端的工程是一个分层的架构,里面使用到多个框架,组合起来。不一定使用SSH,也可全部使用spring。但需要两者间进行沟通,使后面与前面集成起来。这是两个工程,所以跨域的问题始终存在。
这是Peferences文件。需注意的是,为了上面的例子,将可能存在的问题都列在参考文件里,通过这个参考文件,可能知道可能存在的问题,进而如何去解决。可能存在的问题已经其列在参考文件里,可自行观看,了解如何操作。
这是有关SSH集成的。不一定使用该框架既这三个的组合,可使用Spring,或者可在前面进行变化。使用Spring的JPA,也可使用struts,可不使用hibernate,或者直接使用Spring加上hibernate,或者全部使用Spring。无论如何操作,工程都要体现两个概念Decoupling Laying,体现编程的思想,掌握编程思想才是课程重要的东西。所以是有关后端代码集成的。给出的例子可自行在下节课运行。尤其Struts的SSH的例子。因后面这段使用的都是之前的代码。只是前面的一段稍微进行了修改。第二次迭代时,后端应该就是完整的后端了。
后端还有个问题要解决。既为了配合数据库这门课进行讲解。进而再回到前端,讲解移动端的开发。需要注意的是:在讲解移动端开发时,后端只有一个,所以使用的例子都是之前看到都的例子里的后端。
二、数据储存-NOSQL & MONGODB
NOSQL是什么意思。NOSQL为 Not only SQL既不仅仅只是SQL。实现NOSQL的目的不是NOSQL里面只有SQL。而NOSQL数据库非常多,以MONGODB为例子,在MONGODB中将三国的人物画出,用图片拿出,在MONGODB里。而人物的信息都在关系性数据库里。通过NOSQL为例子来讲解数据存储到一定程度或者在现在的状态下,存储的数据为什么SQL没有办法去处理?
或者SQL处理不够好,才出现NOSQL。而具体的是指MONGODB也未必。
因实验做了许多项目,也不一定使用MONGODB。可使用Conxiagate等这一类的东西。
MONGODB只是用来体现NOSQL的好处,想理解MONGODB,必须要关注。
因为数量大,结构化差,导致使用NOSQL会比较好。MONGODB是一种NOSQL,MONGODB的基本操作方法是怎么样,关键是使用JAVA代码访问如何去访问。
例子:
使用Spring访问MONGODB会显得较简单。Replication&Sharding -Mechanism of Sharding -Auto-sharding是深入MONGODB,既MONGODB实线上的机制。
为什么要讲解该问题?
因为理解MONGODB实线的机制对将来使用好会比较有帮助,但不会深入讲解。只会讲解一些简单的地方。