servlet(springMVC struts2)
jdbc(myBatis,Hibernate)
java基础,javaSE(Spring框架)
ajax
框架:软件的半成品,可以复用代码
三个阶段:
第一个:基本模块(ioc,springmvc,..)会用
第二个:项目(利用基本模块搭建项目)加深理解
第三个:懂得框架的设计思想,研究源代码(架构师)
spring基础:
ioc 控制反转
springmvc
mybatis
spring jdbc/myBatis
ajax
作者(Rode johnson)
spring是什么?(一站式框架)
是一个开源的,轻量级的。用来简化企业级应用开发的框架。
(1)简化开发
JDBC:
jdbc加载驱动,创建连接,Statement,执行查询,关闭连接
spring对常用的api进行简化
比如使用(springjdbc)访问数据库,就不在需要考虑连接和关闭连接
(2)解耦(要求低耦合)
Spring帮我们管理对象的之间的关系,使其软件很好维护
(3)集成
任务调度
Spring可以集成其他的框架(比如,可以集成任务调度的框架Quartz 集成访问数据库的框架mybatis)
spring容器是什么?是spring框架中的一个模块,用来管理对象。
容器:可以创建对象,初始化,调用,销毁等
如何启动spring容器?
1.导包spring-webmvc 3.28
2.添加配置文件
阿姨容器 菜对象 自己点的菜就是配置文件
3.启动spring容器
applicationContext.xml
<xml>
<beans>根元素
限制,约定条件xmlns
如何让容器创建对象?(重要)
方式一:使用无参构造器
1.为类提供一个无参构造器(缺省构造器)
2.在配置文件当中添加一个bean元素.
3.启动spring容器,调用getBean方法来获得对象
方式二:静态工厂方法。
<!-- 使用静态工厂方法创建对象
Calendar抽象方法
Calendar c = Calendar.getInstance();
factory-method属性:指定一个静态方法,容器会调用该方法来创建对象
调类的静态方法来创建对象
-->
方式三:实例工厂方法。
<!-- 使用实例工厂方法创建对象
factory-bean属性:要调用方法的对象的id
factory-method:该对象的方法.
注:该方法是一个实例方法不加Static
Spring容器会调用该对象的方法来创建对象. -->
作用域:(scope)
默认情况下,针对一个bean的配置,spring容器只会创建一个实例.(即作用域为singleton单例)
如果值是prototype(原型,即会创建多个实例)
配置作用域名 默认值(缺省值)是singleton(单例,
即容器只会创建针对一个bean的配置,只会创建一个实例)
如果值是prototype(原型,即会创建多个实例此时(eb1 == eb2);为false)
在TestCase中再创建
ExampleBean eb2 = ac.getBean("eb1",ExampleBean.class);
system.out.println(eb1 == eb2);为false
构造器ExampleBean()会调用两次(输出)
scope="prototype"
生命周期相关的几个方法。
(1)初始化方法(创建好容器的时候)
init-method属性来指定.
(2)销毁方法(关闭容器时候)
AbstractApplicationContext ac
ac.close();
注意:只有作用域为单例(singleton)时候,销毁方法才有作用。
如果作用域为原型的时候,销毁失效
延迟加载(了解)
(1)默认情况下,容器在启动之后,会将所有作用域为单例(singleton)的bean先创建好.
(2)如果设置lazy-init属性值为"true",则容器启动
之后不再将作用域为单例(singleton)的bean创建好
设计 开闭原则 修改尽量避免 扩展开放
IOC(Inversion Of Controll控制反转)(重要)
IOC是什么?
对象之间的依赖关系由容器来建立。
原来处理方式:
A:B b = new B();
b.f1()
B:f1()
A--->B
AB之间的依赖关系由A自己来负责
通过依赖注入方式:
DI(Dependency Injection 依赖注入)是什么?
容器可以通过调用对象提供的set方法或构造器来建立依赖关系。
(1)采用set方法来注入
<!-- ioc包中B类 创建B无参构造 -->
<bean id="b1" class="ioc.B"/>
<bean id="c1" class="ioc.C"/>
<!-- 配置set方式的注入
容器在创建好A对象之后,接下来会调用该对象对应的set方法 -->
<!-- 创建好A再调用set方法
property的id="b1"的参数name="b"
如果name="bcd"则setBcd-->
<bean id="a1" class="ioc.A">
<!-- 原b1改为:ref="c1"指定元素是容器中的另一个bean实例 -->
<property name="b" ref="c1"/>
</bean>
11.24
Java Bean 具有约束的Java类
包
序列化
无参数构造器
Bean属性-->getXXX setXXX
一般情况下,所有类都是JAVA Bean规则
Spring 两大核心功能:IOC AOP
(2)构造器方式的注入
index属性:指定参数的下标(从0开始)
index参数下标 参数的位置
<bean id="a1" class="ioc.A">
<constructor-arg index="0" ref="b1"/>
</bean>
自动装配(了解)
(1)默认情况下,容器不会自动装配
(2)autowire (装配)编织
3个属性值(byName,byType,constructor)
byName属性(常用):容器查找与bean的id与属性名一致的bean,然后调用set方法来完成注入(找wt 查找set方法)
byType属性:byType属性:容器查找与属性类型一致的bean),然后调用set方法来完成注入. 注:如果找到多个,则报错
constructor属性:容器查找与属性类型一致的bean,然后调用构造器来完成注入
<bean id="wt" class="autowire.Waiter"/>
<!-- 自动装配autowire
byName属性:容器查找与bean的id与属性名一致的bean,
然后调用set方法来完成注入(找wt 查找set方法).
注意:如果找不到对应的bean,注入null.
byType属性:容器查找与属性类型一致的bean(此时为Writer),然后调用set方法来完成注入.
注:如果找到多个,则报错
constructor属性:容器查找与属性类型一致的bean,然后调用构造器来完成注入
-->
<bean id="rest" class="autowire.Restaurant" autowire="byType"/>autowire=""的值可以为(byName,byType..)
//找到A对象指向方法区中的方法
A a = ac.getBean("a1",A.class);
注入基本类型的值
<!-- 要赋值的属性name 值value-->
<property name="name" value="苍老师"/>
<property name="age" value="25"/>
注入集合类型的值
(get,set,toString,
//启动spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("autowire.xml");
//通过容器得到一个对象
A a = ac.getBean("a1",A.class);
a.execute();)
list:
<!-- 注入集合类型的值 -->
<property name="cities">
<list>
<value>北京</value>
<value>上海</value>
<value>广州</value>
</list>
</property>
Set:
<property name="interest">
<list>
<value>钓鱼</value>
<value>台球</value>
<value>篮球</value>
</list>
</property>
Map:
<property name="score">
<map>
<entry key="english" value="100"/>
<entry key="math" value="100"/>
<entry key="chinese" value="98"/>
</map>
</property>
properties:
<property name="db">
<props>
<prop key="user">lh</prop>
<prop key="password">1234</prop>
</props>
</property>
引用方式注入集合类型的值
<!-- 将集合类型的值配置成一个bean
原型:<bean id="ciitesBean"
命名空间:util:表示使用util命名空间的元素(用来区分同名元素)
例子:1.<c:if test=""> c为命名空间
2.<%@taglib uri=""(""里面为命名空间,域名是唯一的) prefix(别名)="c"%/>
util:真正命名空间是上面的地址:util="http://www.springframework.org/schema/util"
util:list表示使用的是util命名空间的list元素。
-->
<util:list id="citiesBean">
<value>深圳</value>
<value>成都</value>
<value>昆明</value>
</util:list>
<util:set id="interestBean">
<value>游泳</value>
<value>足球</value>
<value>旅游</value>
</util:set>
<util:map id="scoreBean">
<entry key="english" value="100"/>
<entry key="math" value="100"/>
<entry key="chinese" value="98"/>
</util:map>
<util:properties id="dbBean">
<prop key="user">lh</prop>
<prop key="password">1234</prop>
</util:properties>
<!-- 引用的方式注入集合类型的值 -->
<bean id="eb2" class="value.ExampleBean">
<!-- 调取的对象ref(referance)="" -->
<property name="cities" ref="citiesBean"/>
<property name="interest" ref="interestBean"/>
<property name="score" ref="scoreBean"/>
<property name="db" ref="dbBean"/>
</bean>
输出:ExampleBean [name=null, age=0, cities=[深圳, 成都, 昆明], interest=[游泳, 足球, 旅游], score={english=100.0, math=100.0, chinese=98.0}, db={user=lh, password=1234}]
<!-- 读取properties文件的内容 写法location="classpath: "-->
<util:properties id="config" location="classpath:config.properties"/>
<!-- #{config.pagesize properties文件中的key} -->
<property name="pageSize" value="#{config.pagesize}"/>
输出:{pagesize=10}
注入Spring表达式值
<!-- 使用Spring表达式读取bean的属性值 -->
<bean id="sb1" class="value.SpelBean">
<property name="name" value="#{eb1.name}"/>
<!-- #{eb1的cities属性}
#{eb1.cities[1]}id:eb1集合中第二个元素-->
<property name="city" value="#{eb1.cities[1]}"/>
<!-- id.name(<property name="score">).key-->
中文写法:#{eb1.score['英语']}
<property name="score" value="#{eb1.score.english}"/>
<!-- #{config.pagesize properties文件中的key} -->
<property name="pageSize" value="#{config.pagesize}"/>
</bean>
使用注解来简化配置
(1)组件扫描:
<环境:conmponent-scan 包=""/>
<context:conmponent-scan base-package="org.example"/>
相当于<bean id="" class=""/>
上面配置,容器会自动扫描org.example包机器子包下所有组件,并实例化bean
如果将这些类前面加上特殊的注解(如@Component)则容器会将这些类纳入容器进行管理
(相当于以前配置文件当中有响应的bean元素)
(2)如何进行组件扫描
步骤:
1.在配置文件中加conmponent-scan元素
2.在类名前,添加一些注解
(即能把容器当成bean来管理)
@Component 通用的注解(标注一个普通的Spring Bean类)
@Servive 业务层的类(标注一个业务逻辑组件类)
@Repository 持久层(标志一个DAO类)
@Controller 控制层(标注一个控制器组件类)
(3)声明周期相关的两个注解
@PostConstruct初始化回调方法
@PreDestroy销毁回调方法
注:这两个注解来自于javaee,不用属于spring框架.
注意:只有作用域为单例(singleton)时候,销毁方法才有作用。
(4)用于延迟加载的注解:
@Lazy(true)
@Lazy(true)此时@Scope("singleton")延迟加载起作用
延迟加载(了解)
(1)默认情况下,容器在启动之后,会将所有作用域为单例(singleton)的bean先创建好.
(2)如果设置lazy-init属性值为"true",则容器启动
之后不再将作用域为单例(singleton)的bean创建好
(5)用于指定作用域的注解
@Scope("singleton")
配置作用域名 默认值(缺省值)是singleton(单例,
即容器只会创建针对一个bean的配置,只会创建一个实例)
如果值是prototype(原型,即会创建多个实例此时(eb1 == eb2);为false)
在TestCase中再创建
ExampleBean eb2 = ac.getBean("eb1",ExampleBean.class);
system.out.println(eb1 == eb2);为false
构造器ExampleBean()会调用两次(输出)
scope="prototype"
(6)依赖注入相关的注解
@Autowired注解(写在构造器面前,声明需要为其注入bean)
@Qualifier注解(写在参数面前,声明需要为其注入bean的ID值)
//加在属性前面(最前面private Waiter wt;前)也可以等价于加在set方法前面(但是没输出setWt()其实就是只起到赋值作用)
//@Autowired
//@Qualifier("wt")
1.支持set方式的注入和构造器方式的注入。
2.set方式注入:
将@Autowired和@Qualifer加到set方法前面,也可以加到属性前面
其中Qualifer用于指定要注入的bean的ID.
注意:如果不指定ID则使用byType的方式来注入
3.构造器注入
将@Autowired和@Qualifer加到构造器前面
@Autowired注解
//告诉容器调get方法来完成依赖注入
//@Qualifier("wt")相当于ref=""让容器查找id=wt的bean,不加就是都会找
public void setWt(@Qualifier("wt") Waiter wt) {
System.out.println("setWt()");
this.wt = wt;
}
@Resource注解(常用)
1.只支持set方式的注入
2.可以将该注解加到set方法前面,或者加到属性前面,使用name属性来指定要注入的bean的id
@Value注解
可以注入Spring表达式的值
注:@value注解可以用在属性前,也可以用在set方法前.
另外,也可以使用该注解注入基本类型的值
springmvc
springmvc
springmvc
springmvc
springmvc
11.25
springmvc
是一个用来简化基于mvc架构的web开发框架
springmvc属于spring框架的一部分
M-Model模型(Dao..)
V-View视图(Jsp..)
C-Controller控制器(ActionServlet)
如何使用?
五大组件
(1)DispatcherServlet(前端控制器,请求入口)
控制器,相当于MainServlet
(2)HandlerMapping(前端控制器的秘书,请求派发)
请求地址和model的对应关系
(3)Controller(处理器,请求处理流程)
处理业务逻辑
(4)ModelAndView
封装处理结果(包含有视图名)
/**ModelAndView有两个构造器
* 第一个:
* ModelAndView(String viewName)
* viewName是jsp页面的名字.
* 第二个:
* ModelAndView(String viewName,Map model),model的
* 数据存储到request的attribute中
*/
(5)ViewResolver
负责将视图名解析成真正的视图对象
step1.DispatcherServlet收到请求之后,根据
HandlerMapping(接口)的配置,调用响应的处理器
step2.Controller将处理结果封装成ModelAndView对象
返回给DispatcherServlet
step3.DispatcherServlet依据ViewResolver的解析,
调用相应的视图对象(比如某个jsp),生成相应的页面
编程步骤
step1. 导包。
spring-webmvc
step2. 添加配置文件。
applicationContext.xml文件
注:配置先后顺序无关
<!-- 配置组件扫描 -->
<context:component-scan base-package="controller"/>base-package:包
<!-- 配置MVC注解扫描 (@RequestMapping 下面的方法才生效)-->
<mvc:annotation-driven/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀,后缀 -->
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
step3. 配置DispatcherServlet。
step4. 写Controller。
a. 实现Controller接口。
b. 在handleRequest方法当中,编写处理逻辑。
step5. 写jsp
step6. 配置HandlerMapping和ViewResolver。
基于注解的spring mvc应用
(1)编程步骤
step1.导包。
spring-webmvc
step2.添加配置文件。
step3.配置DispatcherServlet。
step4.写Controller。
1.不用实现Controller接口。
2.可以添加多个方法。
3.方法名不做要求,返回值类型可以是 ModelAndView,也可以是String。
4.在类名前添加@Controller(@Controller 控制层)。
5.使用@RequestMapping(映射)(浏览器请求路径)来告诉 DispatcherServlet,请求路径与处理器的对应关系。
step5.写jsp。
step6.spring配置文件中,需要配置:
组件扫描,mvc注解扫描,视图解析器。
no mapping found:处理方法,在所有方法都试过的时候,最后改jsp 里面只加句话试试,再改回来
@RequestMapping类型
类级别(Type-level),就是注释定义在类定义的上面。
方法级别(Method-level),就是注释定义在方法定义的上面。
举例说明(1)
@Controller
@RequestMapping("/a")
public class HelloWorldController {
@RequestMapping("/helloWorld")
public String helloWorld(Model model) {
model.addAttribute("message", "Hello World!");
return "helloWorld";
}
}
@RequestMapping("/a")为类级别(Class-level),@RequestMapping("/helloWorld")为方法级别(Method-level)。
这个例子是把请求地址/a/helloWorld映射到helloWorld处理器上。
举例说明(2)
@RequestMapping("/helloWorld.do")
public String helloWorld(ModelMap model) {
model.addAttribute("attributeName", "attributeNameValue3");
return "helloWorld";
}
这里返回的字符串"helloWorld"表示视图名称,而ModelMap类型的参数表示model。也可以把参数定义为Model类型。
(2)如何读取请求参数值
方式一:通过request对象.
/*
* 读取request对象对去请求参数值。
*
*/
@RequestMapping("/login.do")
public String checkLogin1(HttpServletRequest request){
System.out.println("checkLogin1()");
String adminCode = request.getParameter("adminCode");
String pwd = request.getParameter("pwd");
System.out.println("adminCode:"+adminCode+"pwd:"+pwd);
return "index";
}
方式二(常用参数少):获取请求参数的第二种方式,
使用@RequestParam(String Param),Param是实际请求参数名.
//还可以这样写:@RequestParam("pwd")里面是实际的参数
//正式的写法
//@RequestParam("adminCode") String adminCode
//@RequestParam("pwd") String pwd
@RequestMapping("/login2.do")
public String checkLogin2(String adminCode,@RequestParam("pwd") String password){
System.out.println("checkLogin2()");
System.out.println("adminCode:"+adminCode+"pwd:"+password);
return "index";
}
注意:建议,即使实际请求参数名与形参名一致,也要添加@RequerstParam进行说明
方式三(常用参数多):
封装成一个javabean.一个实例类AdminParam
用于封装请求参数值的类,要求:
*(1)属性名与实际请求参数名一致.
*(2)提供相应的get,set方法
*
@RequestMapping("/login3.do")
public String checkLogin3(AdminParam ap){
System.out.println("checkLogin3()");
System.out.println("adminCode:"+ap.getAdminCode());
return "index";
}
(3)向页面传值
方式一(常用,简洁):通过请求对象绑定数据
将数据保定到request对象,然后转发给jsp来展现.
@RequestMapping("/login4.do")
public String checkLogin4(AdminParam ap,HttpServletRequest request){
System.out.println("checkLogin4()");
request.setAttribute("adminCode", ap.getAdminCode());//绑定名,绑定值 request.setAttribute 获得的值绑定到request
//默认使用转发,所以不用转发器
return "index";
}
注意:springmvc默认使用转发机制
方式二:通过session对象.
@RequestMapping("/login5.do")
public String checkLogin5(AdminParam ap,HttpSession session){
System.out.println("checkLogin5()");
session.setAttribute("adminCode", ap.getAdminCode());
//默认使用转发,所以不用转发器
return "index";
}
方式三(常用,简洁):通过ModelMap对象.
通过ModelMap对象,然后调用该对象的addAttribute方法
@RequestMapping("/login6.do")
public String checkLogin6(AdminParam ap,ModelMap mm){
System.out.println("checkLogin6()");
//mm的方法addAttribute
/**
* 前端控制器调用处理方法,如果有ModelMap,就会
* 使其绑定到请求对象里(相当于request.setAttribute)
* 绑定名就是"adminCode"
*/
mm.addAttribute("adminCode",ap.getAdminCode());
//默认使用转发,所以不用转发器
return "index";
}
方式四:通过ModeAndView
将处理结果添加到ModelAndView对象里面
/**
* 向页面传值的第四种方式:
* 通过ModeAndView
*
*/
/**ModelAndView有两个构造器
* 第一个:
* ModelAndView(String viewName)
* viewName是jsp页面的名字.
* 第二个:
* ModelAndView(String viewName,Map model),model的
* 数据存储到request的attribute中
*/
@RequestMapping("/login7.do")
public ModelAndView cheakLogin7(AdminParam ap){
System.out.println("checkLogin7()");
//将处理结果先放到Map里面
Map<String,Object> data = new HashMap<String,Object>();
//调用Map方法,相当于将数据绑定到了request 绑定名key
data.put("adminCode", ap.getAdminCode());
默认使用转发,所以不用转发器,构造一个ModelAndView对象.返回
return new ModelAndView("index",data);
}
(4)如何重定向?
重定向:服务器通知浏览器向一个新地址发请求。
情况1:如果方法的返回值String,在重定向地址前添加redirect,比如
"redirect:toIndex.do"
情况2:如果方法的返回值是ModeAndView
RediectView rv = new RediectView("toIndex.do");
ModelAndView mav = new ModelAndView(rv);
session验证
1.拦截器(spring框架中的)
注意:过滤器是servlet规范中定义的组件
(1)什么是拦截器?
spring的HandlerMapping处理器支持拦截器应用.
当需要为某些请求提供特殊功能时,例如对用户进行身份验证
然后再调用处理器(controller)
如何写拦截器?
step1.写一个java类,实现HandlerInterceptor接口
strp2.将拦截处理逻辑写在响应的接口方法里面3个方法
(1)preHandle()
处理器执行前被调用.方法返回true表示继续调用其他拦截器和处理器
false表示请求处理完毕,不会向下执行
(2)postHandle()
处理器执行后,视图处理前调用。
此时可以通过modeAndView对象对模型数据进行处理或对视图进行处理
返回给前端控制器controller之前执行该方法.可以在该方法里面,修改处理结果
(3)afterCompletion()
整个请求处理完毕后调用,如性能监控中使用
step3.配置拦截器
<mapping path>哪些请求需要拦截
<exclude-mapping>不拦截
<bean >拦截器类 包
<!-- 配置拦截器 -->
<!-- 注:如果有多个拦截器满足拦截的要求,则根据配置的先后顺序依次执行 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*"/>
<bean class="interceptors.SomeInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
注意:此时没有拦截因为<mvc:mapping path="/*"/>是/*要拦截加/**
@RequestMapping("/abc/hello2.do")
public String hello2(){
System.out.println("hello2()");
return "hello";
}
所有评论(0)