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";

}

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐