11SSH

来源:互联网 发布:淘宝不能和客服聊天 编辑:程序博客网 时间:2024/06/13 07:25
————————————经典Bug——————————————————————————————————————
@Component
@Aspect
public class AuditBean {
@Around("within(cn.tedu.cloudnote.service..*)")  //service包下所有子包所有类的所有方法
public Object log(ProceedingJoinPoint point) throws Throwable{
Object obj = new Object();
try {
long startTime = System.currentTimeMillis();
obj = point.proceed(); //代表了具体方法的执行。通过执行返回一个对象
long endTime = System.currentTimeMillis();
//要知道哪个方法的耗时多少
String str = point.getSignature().toString();

//需要获取方法名,否则测试的方法太多不知道是哪个方法的时间
//签名:返回的是一个对象,包含方法名和参数类型.
//导包apectj.lang.Signature
Signature s = point.getSignature();
System.out.println(s+"耗时:"+(endTime-startTime));

} catch (Throwable e) {

e.printStackTrace();
throw e;  //!!!!!!注意:异常要扔出,否则事务处理遇到异常无法回滚
}
return obj;
}

业务层进行事务处理的时候遇到异常就终止,进行事务回滚。
如果该业务层还加入了AOP,如这里的性能审计,而且该AOP的catch没有抛出异常,则事务回滚失败!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
所以一定要抛异常!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!






————————————————————————————————————————————————




SSH




SSM:好处:spring-mvc已经把web相关都设置好了。
分工合作,dao/service分开写






SSH:
mybatis:优势:零编码。如10行做完
hibernate:有编程量。需要20-30行
jdbc:需要200行




struts相当于spring-mvc


struts相当于拦截器:在servlet之前执行


sun推荐在web使用MVC
Apache struts1实现了MVC 编码多
Webwork xwork 编码少
合并,apache名字,webwork内容。变成
apache strut2(webwork) 编码少
spring MVC 编码更少


上面的底层都是servlet


————————————————————————————————————
注意:
过滤器属于servlet规范当中定义的特殊的组件
而拦截器属于spring框架






来自Apache基金会的软件: http://struts.apache.org
Struts2 与 Struts1 完全没有关系
Struts2 的前身是 WebWorks
Spring MVC\Struts2\Struts1 都是 MVC 模式的Web框架
MVC是非常流行的 用户界面设计模式。
MVC是3层架构中的表现层


更改查看项目视图:
window-》showview-other-java-package explorer


pom:struts2-core  2.3.24
jar包如果有小纸片说明有源代码


struts在web.xml配置时不需要loadonstart配置,因为过滤器天生在容器启动时初始化,
而spring-mvc在web.xml配置dispatcherservlet的时候需要配置loadon...




file-》new-》other-web--》filter--
--》create filter中勾选use exsting,然后browsing选择现有的filter
选择StrutsPrepareAndExecuteFilter


下一步,把filter mappings的URL Pattem/Servlet Name改成/*


点击完成。即可自动在web.xml配置executeFilter


按照路径分层/授权


————————————————————————————————————————————
webapp(项目,如cloudnote)
|-WEB-INF 用户不能直接访问
| |-web.xml部署描述文件
| |-classes 开发的Servlet/Service/Dao...
| | |-conf/spring-mybatis.xml
| |-lib 第三方的jar包:dbcp...
| |-jsp
| | |-*.jsp 是用户不能直接访问的,界面视图组件,需要服务器提供数据拼接的
|-*.jsp完整的有数据的jsp
|-*.html
|-js/*.js
|-css/*.css




tomcat部署目录结构:




|-webapps
| |-cloudnote
(拷贝项目cloudnote下的文件目录)






部署web应用
1.copy
2.eclipse(copy)
3.maven(copy)。maven:开发部署打包测试








tomcat/jBoss/Weblogic




strut2默认是到class中找struts.xml
struts是默认名,不能写成struts2,否则相当于无用




strut2支持两种请求:路径或.action
如:
/login/form
或带action的
/login/form.action


当需要接收的参数很多的时候,
struts2提供了实体封装//域模型封装






有两种方式可以从页面向控制器传输数据:


基本Bean属性传递方式
域模型属性传递方式
————————————————————————————
域模型属性传递方式
浏览器
用户名 name=user.name
密码 password=user.password


strut2封装成一个BeanUserInfo
表单
用户名 name
密码 password




如login和update的表单是雷同的,此时这个BeanUserInfo就能重用了


在服务器的Login2Action{
User user;
setUser(User user){
this.user=user
}
}
只需要传User即可,不需要用传大量bean属性


UpdateAction{
User user;
....
}


————————————————————————————


有id的类需要重写equals




LoginAction2先调用getUser,如果为空,再调用setUser


每次都创建一个对象,只填一个属性。
如第一次创建对象User,但只填了属性name
第二次再调用对象,但只填了password


所以,调用对象或者属性都要设置get和set方法






——————————————————————————————————————————————


public String execute(){
/**
* ActionContext在Strut2中代表当前Strut2
* 环境相关信息.ActionContext能获取很多很多信息,get...
*/
ActionContext ctx = ActionContext.getContext();
/**
* Map类型的session不依赖于ServletAPI
* HttpSession(与Servlet API耦合性低)就可以进行与容器无关的测试等离线操作。

* 离线:脱离web容器单独使用,比如进行junit测试
*  
* 在底层strut2容器会将map session中的信息同步到httpsession中
* 也就是不会用到servlet api也就是单独的bean,也就是单独的类/方法,也就是可以用junit测试。
* 正常来说,junit不能测试servlet
* 因为servlet测试需要httpservletrequest和response。
*/
Map<String,Object> session = ctx.getSession();




——————————————————————————————————————
正因为更servlet没关系才可以进行外部测试


————————————————————————————————————————


strut2与spring整合:
1.利用Spring管理Action
2.spring管理Action,同时可以为控制器注入业务层
最终目的:将控制器与业务层整合
导包strut2-spring-plug 2.3.24






spring有另外一个加载方式:spring listener


org.springframework.web.context.ContextLoaderListener用来初始化spring容器,不初始化spring
无法帮我们管理bean


在部署描述文件也就是web中配置


spring的xml配置文件需要将3.2版本改成3.0
只需配置component scan扫描指定包的controller即可,这样strut2和spring就能一起工作了






——————————————————————————————————————————————————
//为何?web应用是多线程的
@Scope("prototype")  
public class WebAction extends BaseAction{




查看线程:关闭tomcat后debug开启,bio即是用户线程






一个浏览器发送给服务器都天生是串行发送的




当多个线程并发访问同一个临界资源就会出现线程安全问题




!!!!!!!!!!!!!
strut2的Action如何避免线程安全性问题?:每个请创建一个Action对象,如果使用spring管理Action对象,
请使用@Scope(prototype)


spring-mvc有没有安全问题?
有!默认就是单例的。因此避免写公共变量


strut2默认是一个请求一个线程的,可以不加scope,但是如果使用了spring,则必须加scope




service没有定义公共变量,因此可以不必担心线程安全问题
保证service内没有公共变量
访问session和application的时候一定要同步,尤其是application,如果只读可不必在意,只要有写就要注意


dao默认都是单例的


———————————————————————————————————————————————————


现在的抢购网站都是用队列处理




spring提供了多种result,支持各种文件的转发,图片视频...
<result type=? name="success">/WEB-INF/success.jsp</result>




http响应协议支持:jpg/png/mp3/avi/json
strut2在服务端支持了多种响应类型,多种result类型,也就对应上面的类型,以及301重定向


301url
第一次,控制器响应回浏览器301 url 
第二次:然后浏览器再向服务器发一次请求


http网页支持多种媒体类型的下载


多种resulet类型
despatcher
stream
json
redirect
redirectAction


把流属性放在控制器上,就能下载


后面半小时json只序列化了字符串,看day02课件




map用得更多,键值对的




任何一个result。。。


default。xml有:
 <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>


然后查看strut2api的struts2/struts2-core/apidocs/

org.apache.struts2.dispatcher
Class StreamResult


可见ContentType
可以设置媒体类型




contentType=image/jpeg
contentType=application/json
contentType=mpeg/audio




despatcher--->html
stream
--->jpg
--->png
--->mp3
--->avi


json--->json
redirect--->301重定向
redirectAction--->301重定向








public class StreamResult
extends StrutsResultSupport


A custom Result type for sending raw data (via an InputStream) directly to the HttpServletResponse. Very useful for allowing users to download content.


This result type takes the following parameters:


  ***重要  contentType - the stream mime-type as sent to the web browser (default = text/plain).
    contentLength - the stream length in bytes (the browser displays a progress bar).


 ***重要   contentDisposition - the content disposition header value for specifing the file name (default = inline在浏览器默认直接显示, values are typically attachment如果设置为附件形式,则变成下载;filename="document.pdf".  //点击下载,而不是显示


  ***重要  inputName - the name of the InputStream property from the chained action (default = inputStream). //用哪个流,把哪个流发给客户。如果是照片就把照片放入到这个流,如果是音乐则放到这里发,如果是doc则生成doc放到这里。如果bean写了默认属性,则这里可以不写??


    bufferSize - the size of the buffer to copy from input to output (default = 1024).
    allowCaching if set to 'false' it will set the headers 'Pragma' and 'Cache-Control' to 'no-cahce', and prevent client from caching the content. (default = true)
    contentCharSet if set to a string, ';charset=value' will be added to the content-type header, where value is the string set. If set to an expression, the result of evaluating the expression will be used. If not set, then no charset will be set on the header






——————————————————————————————————————————————


extends="struts-default">因为json-default的媒体类型比较全






BufferedImage img = new BufferedImage(400, 300, BufferedImage.TYPE_3BYTE_BGR);
//照片:大号的二维数组。横400pix,竖300pix。
//一个pix是3个byte,每个字节第一个是blue,第二个字节是green,第三个字节是red 








要导包strut2-json




contentType的配置,查看tomcat的conf的web.xml
   <mime-type>video/x-msvideo</mime-type> 对应的avi的contentType的配置




Excel新的:
 <extension>xlsx</extension>
        <mime-type>application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</mime-type>
    </mime-mapping>


Excel旧的:
     <extension>xls</extension>
        <mime-type>application/vnd.ms-excel</mime-type>




————————————————————————————————————
重定向:


ServletRedirectResult


 <result name="success" type="redirect">
   <param name="location">foo.jsp</param>
   <param name="parse">false</param>
   <param name="anchor">FRAGMENT</param>
 </result>


————————————————————————————————————————


<!-- servletresult -->
<action name="test" class="redirectAction">
<result name="doc" type="redirect">
http://doc.tedu.cn
<!--  因为location是默认属性,可以不写xml标签,即下面和上面一样的
<param name="location">  
http://doc.tedu.cn
</param>
-->
</result>
<!-- redirectAction用于重定向到action。photo是Action的名字,因为是默认值,因此只写photo
写demo/photo也行
-->
<result name="photo" type="redirectAction">
photo
</result>




——————————————————————
浏览器地址输入:
http://localhost:8080/struts_day03/demo/test?type=0


拦截器:
Interceptor不改变控制器的前提下,在控制器前后执行,增加功能
intercept(
//控制器前执行的代码
invocation.invoke()//有这句调用则调用子控制器,没有调用则跳过
//控制器后执行的代码




strut2本身也是依靠拦截器工作的,所有的控制器,但凡注入了,都用到了拦截器
strut2天生有一个拦截器。需要带上basicStack,否则strut都半残废了。
parameter调用


————————————————————————————————————————
所有的标签库都是在服务器端执行的,无论是jstl还算strut2的lib
java所有的包括jsp都是在服务器端执行的
————————————————————————————————————————
ValueStack:
浏览器-->主控制器-->子控制器执行,收到数据--->将数据保存的ValueStack
包括控制器本身放到ValueStack


在jsp中利用OGNL/EL读取ValueStack值


<s:debug/>展示ValueStack数据


是控制器向jsp传送数据的通道,就是一个集合




————————————————————————————————
OGNL:spring/mybatis等获取属性的时候用过,都是OGNL


stack Context
#key获取环境信息


ValueStack:
两个区:


内容区:控制器的对象
content:保存所有的环境信息




因为key包含了点,只能用[]
<s:property value="#request['struts.actionMapping']"/>


具体为何要用,看以下js的演示:




javascript中对象就是一个map
在浏览器的console中的:


"tom", "jerry", "andy"]
ary
["tom", "jerry", "andy"]
ary[0
SyntaxError: Unexpected token }
ary[0]
"tom"
ary[1]
"jerry"
ary[2
SyntaxError: Unexpected token }
ary[2]
"andy"
ary[1].length
5
obj = new Object();
Object {}
obj.name=tom;
ReferenceError: tom is not defined
obj.name="tom";
"tom"
obj
Object {name: "tom"}
obj.age=20;
20
obj.height=5.6;
5.6
obj
Object {name: "tom", age: 20, height: 5.6}
obj["phone"]="110";
"110"
obj
Object {name: "tom", age: 20, height: 5.6, phone: "110"}


obj['user.address']='beijing';
"beijing"
obj
Object {name: "tom", age: 20, height: 5.6, phone: "110", user.address: "beijing"}
obj.name 获取name,没问题
"tom"
obj.age 获取age,也正常
20
obj.user.address 但是,获取user.address,就或报错,
因为obj会去找user,可是并没有user,而是只有user.address。
obj['001']="Dog";
"Dog"
obj
Object {name: "tom", age: 20, height: 5.6, phone: "110", user.address: "beijing"…}
obj.001  //这样获取也一样报错。所以也许要用中括号!!
因此<s:property value="#request['struts.actionMapping']"/>需要中括号


先有js,el的语法也跟js一样


如果是map套map,获取时则方括号套方括号


————————————————————————————————————
在js中:


data=[{name:'tom',age:20},{name:'jerry',age:33}]
[
Object

Object
]
data[1].age
33
data[1]['age']
33
data[1]['name'].length
5


同样,el也能这样用


OGNL在做计算的时候不区分list/map的








map {age=20, name=Tom, user.address=北京, 001=狗狗}
sun公司在数组对象上没有很好地重写toString,
而直接输出结构
data [Ljava.util.Map;@3ebfd8


@3ebfd8不是地址,而是通过运算转换的值


可以把data类型换成list,因为list重写过了




————————————————————————————————
OGNL只能在strut标签内用
el配合jstl用
el为何也可以访问value
strut2把el底层做了修改,造成el可以直接方法ValueStack


现在都用ajax/json处理


ValueStack在面试会问题
用来从浏览器到服务器承载数据的




加入Property Name有两个texts呢??
从上往下查找,找到一个Property Name,剩下的就不管了




________________________________________________________________________________


Hibernate


不用写SQL,写HQL。所有数据库的子集,特定数据库则操作不了
mybatis:轻量化,不用写java,需要写sql


ORM:对象关系映射,将对象映射到关系数据库。可以实现对象的CRUD(增删改查)操作


EJB:调试实体bean很麻烦


JPA:java持久层api,sun招来Hibernate creator写的




JPA==Hibernate




1.导包:Hibernate+JDBC Driver
2.配置Hibernate主配置文件(连接db的参数)
当使用了spring,就不再需要了
3.映射文件
--一个实体类对应一个映射文件




mybatis:配置文件写sql
Hibernate:配置文件,类与表,属性与列的对应关系


4.创建session,跟mybatis的sqlsession(crud)相似
--Session对象提供了crud方法
5.使用session对象实现crud




只需要4




持久状态下(save以后),user对象转化为持久状态。持久状态的修改将直接影响数据库


游离状态一改属性状态不变,
一旦调用update方法,游离状态又变成持久状态,其属性也会一点点改到数据库






面试问题:出现异常:


ClassNotFoundException说明导包导少了
MethodNotFoundException:版本不对
空指针异常:变量没有正常赋值,正常赋值就行了




————————————————————————————————————————————
User user = new User("100","tom","123","ok","cat");

Session session = factory.openSession();
  
//执行了save数据库里面也没有。
//要加上Transaction和commit()正常有事务应该有try/catch的。
Transaction tx = session.beginTransaction();
session.save(user);


tx.commit();
session.close()






————————————————————————————————————————————————




Hibernate生成的sql不可控,无法知道低效还是高效,生成的是低效的










——————————————————————————————————————————————————————————


Spring哪个接口最重要?ApplicationContext


Hibernate哪个接口最重要?Session


Mybatis呢?SqlSession




















———————————————————————————————————————————————————————————


sqlsession:提供了crud的方法,利用它可以实现对数据库crud


指定某种dialect,Hibernate会自动生成sql语句


<hibernate-configuration>


<session-factory>
<!-- dialect -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>




PostgreSQL:学院化的数据库




<property name="show_sql">true</property> //调试需要,运行不需要。hibernate输出生成的接口
<property name="format_sql">true</property>   //分行显示,格式化输出。也是用来做调试的








POJO






一、PO:persistant object 持久对象,可以看成是与数据库中的表相映射的java对象。
最简单的PO就是对应数据库中某个表中的一条记录,多个记录可以用PO的集合。PO中应该不包含任何对数据库的操作。  


二、VO:value object值对象。通常用于业务层之间的数据传递,和PO一样也是仅仅包含数据而已。
但应是抽象出的业务对象,可以和表对应,也可以不,这根据业务的需要.个人觉得同DTO(数据传输对象),在web上传递。   


三、DAO:data access object 数据访问对象,此对象用于访问数据库。通常和PO结合使用,DAO中包含了各种数据库的操作方法。
通过它的方法,结合PO对数据库进行相关的操作。   


四、BO:business object 业务对象,封装业务逻辑的java对象,通过调用DAO方法,结合PO,VO进行业务操作。   


五、POJO:plain ordinary java object 简单无规则java对象,我个人觉得它和其他不是一个层面上的东西,VO和PO应该都属于它。    


O/R Mapping 是 Object Relational Mapping(对象关系映射)的缩写。
通俗点讲,就是将对象与关系数据库绑定,用对象来表示关系数据。
在O/R Mapping的世界里,有两个基本的也是重要的东东需要了解,即VO,PO。    VO,值对象(Value Object),PO,持久对象(Persisent Object),它们是由一组属性和属性的get和set方法组成。
从结构上看,它们并没有什么不同的地方。
但从其意义和本质上来看是完全不同的。  


1.VO是用new关键字创建,由GC回收的。    PO则是向数据库中添加新数据时创建,删除数据库中数据时削除的。
并且它只能存活在一个数据库连接中,断开连接即被销毁。  


2.VO是值对象,精确点讲它是业务对象,是存活在业务层的,是业务逻辑使用的,它存活的目的就是为数据提供一个生存的地方。    
PO则是有状态的,每个属性代表其当前的状态。它是物理数据的对象表示。
使用它,可以使我们的程序与物理数据解耦,并且可以简化对象数据与物理数据之间的转换。  


3.VO的属性是根据当前业务的不同而不同的,也就是说,它的每一个属性都一一对应当前业务逻辑所需要的数据的名称。    
PO的属性是跟数据库表的字段一一对应的。   PO对象需要实现序列化接口。






——————————————————————————————————————————————————————


Hibernate的生成周期:




刚new的时候,内存中有对象,数据库没有数据,属于新建状态
一调用save,,则变成持久状态
持久状态:对应的数据库有对应的行






get回来的对象就是持久状态的。
get回来直接set也会直接改掉数据库




session:一级缓存
调用了close则脱离session
clear:把session里面所有的对象全部清空,都变成游离状态
evict(对象):只清除指定对象




面试问题:被Hibernate管理的对象有哪几个状态?
临时状态
new之后
持久状态
调用了save,或get
游离状态
clear/evict之后






Spring最核心功能::IoC:管理对象
AOP:管理行为
Spring在管理对象的基础上还做了其他的扩展


————————————————————————————


导spring-orm后spring和hibernate有关的包都导进来的
orm:Object Relation Mapping




——————————————————————————
HibernateTemplate:底层封装了session,比session更简洁,把事务等封装了
HT也提供了CRUD
HT天生给dao使用的






只要涉及数据库操作,都会有事务管理




HibernateTemplate能够自动关连接,封装了事务
而session需要手动open,管理事务,手动close


一般都是在dao使用HT
如:


@Repository("userDao")
public class UserDaoImpl implements UserDao {
@Resource  //@Autowired---->Spring Standar
private HibernateTemplate hibernateTemplate;

public int addUser(User user)




HT是spring提供的


——————————————————————————————
NoSuchBean 'userDao' defined
注意是否组件扫描没加或者扫描路径未指定


<context:component-scan 
base-package="cn.tedu.dao"/>




————————————————————————————————————


hibernate执行sql是batch执行的,如删除2个user,
sql在控制台输出可见是先执行两次select,然后再两次delete
delete是最后commit才生效的




如果不是maven项目,maven导的包放到项目的lib里面




面试问题
hashmap有什么好处?
集合/数组?


————————————————————————————————————————————
poi:


实际上很多时候我们只利用POI来操作Excel。甚至只用xls这一种格式。
那么就没有必要全部都导入了。具体应该使用哪个JAR包请参考以下内容:




Component Application typeMaven artifactIdNotes
POIFS OLE2 FilesystempoiRequired to work with OLE2 / POIFS based files
HPSF OLE2 Property Setspoi 
HSSF Excel XLSpoiFor HSSF only, if common SS is needed see below
HSLF PowerPoint PPTpoi-scratchpad 
HWPF Word DOC poi-scratchpad  
HDGF Visio VSDpoi-scratchpad 
HPBF Publisher PUBpoi-scratchpad 
HSMF Outlook MSGpoi-scratchpad 
OpenXML4J OOXMLpoi-ooxml plus one of
poi-ooxml-schemas, ooxml-schemas Only one schemas jar is needed, see below for differences
XSSF Excel XLSXpoi-ooxml 
XSLF PowerPoint PPTXpoi-ooxml 
XWPF Word DOCXpoi-ooxml 
Common SS Excel XLS and XLSXpoi-ooxmlWorkbookFactory and friends all require poi-ooxml, not just core poi




————————————————————————————————————————————————————




读取properties


properties p = new properties();
try{
p.load(JdbcDao.class.getResoureceAsStream("config.properties"))


}




//HQL表中的属性换成了这个列。写*号的时候可以省略
//select * from cn_user where cn_user_name=?
// from User where name=?


mybatis的sql可以在控制台测试,而hibernate不行,hql需要hibernate下测试




hql工作的时候






responsebody是spring-mvc的




可以去tomcat查看已经编译的文件,如apache-tomcat-7.0.67/wtpwebapps/ssh/WEB-INF/classes的struts.xml
配置没错,服务器部署的时候出问题时,把服务器停止,右键clean
,然后在eclipse的菜单的project选择clean,则把整个项目重新编译




socket编程,就像DMS一样
DMS:服务器多线程接收,客户端单线程保存,
服务器:生产者/消费者模型






————————————————————————————————————————————


用map封装结果








UserAction 内两个方法都有try/catch,可以放到拦截器




strut2往web上解决了mvc,使开发更规范




spring框架和mvc的关系:


mvc不是3层结构。
mvc和3层结构没有任何关系,但是有交集
M:业务+数据层
v:浏览器
C:控制器(主/子控制器)


springMVC:
M:数据的存储
V:跟用户打交道
C:接收请求,访问模型,数据收回再发给V






三层结构:
表现层:用户看见的,包含了MVC中的V和C
业务层:MVC的M的一半
数据层:MVC的M的一半


springMVC/struct2:三层结构中的表现层
业务层:自己写的
持久层:mybatis/hibernate


spring不管业务层,而是管理bean,加aop,扩展代码


举例:
商品结算:数据来自哪里?
商品单价,数量,余额。从DB获取
账户钱消,商品数量消,物流发货,写到DB
service添加算法完成结算。外来的参数从控制器获取

一个功能怎么做?先想数据在哪里?
1.数据来自哪里?
2.算法实现
3.如何展现给浏览器






软件采用三层结构
表现层:使用SpringMVC框架 (或struts)
持久层:使用Mybatis(或hibernate)
整体的耦合使用spring




苍老师web
canglaoshi.org



















































0 0
原创粉丝点击