1,框架概述
1.1,什么是框架(了解)
将一些重复性的代码进行封装,简化程序员的编程操作,可以使得程序员在编码中把更多的精力放到业务需求的分析和理解上面,相当于一个半成品软件。
1.2,三大框架(掌握)
SSH:struts、hibernate、spring
SSM:springmvc、mybatis、spring(现在更流行)
1.3,三层架构(掌握)
表现层-->业务层-->数据层 即:Web-->Service-->Dao
MVC架构(Model,View,Controller):模型层(javabean class) --> 视图层 (jsp,html) --> 控制层 (Servlet,Filter)
1.4,Servlet 和 Filter(重点)
Servlet:
Filter:
Servlet能做的事情,过滤器也可以做到。并且过滤器比Servlet还多了一个放行的功能,因此过滤器比Servlet功能更为强大。
结论就是:过滤器同样也适合做控制器。
2,Struts简介
2.1,struts2概述(了解)
Struts2是Apache发行的MVC开源框架。注意:它只是表现层web(MVC)框架。
2.2,Struts2与Struts1的关系(了解)
Struts1:
Struts1也是apache开发的一套mvc的开源框架。在2005年之前非常流行。
弊端:Struts1的核心控制器就是一个Servlet。随着使用者的增多,弊端开始出现。
Struts2:
- 在long long ago,有一个设计超前的框架XWork,后来推出了XWork1和WebWork2。
- Struts2就是apache和OpenSymphony组织合并开发出来。
- 里面包含了WebWork2的核心及Struts的一些特性和功能。除此之外,和Struts1没有任何关系了。
3,Struts的环境搭建
3.1,下载Struts2的开发包: http://struts.apache.org
3.2,解压后的目录结构(掌握):
apps 官方提供的案例Demo
docs 官方提供的文档
lib 官方提供的jar包,需要用到哪个才导入哪个
src 源码
3.3,struts jar包介绍(了解)
在apps目录中,提供了一个struts2-blank.war包,初始学者在项目集成中,导入lib下的所有包即可。
3.4,创建第一个Struts2项目(IDEA)(掌握)
创建Struts2项目:
如果是使用IDEA搭建Struts2项目,则会自动在web.xml中配置Filter。如果是eclipse,则需要手动的将下面代码添加进web.xml,同时还需要把struts2-blank里classes目录下的struts.xml配置文件拷贝到自己创建工程的src中,然后删除struts标签的所有内容,IDEA则会自动完成该步骤。
在web.xml中,配置Filter的代码如下:
1 <filter>
2 <filter-name>struts2</filter-name>
3 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
4 </filter>
5 <filter-mapping>
6 <filter-name>struts2</filter-name>
7 <url-pattern>/*</url-pattern>
8 </filter-mapping>
配置的目的是用于拦截请求,由Struts的规则去处理请求,而不是用以前的servlet去处理。
Tomcat运行Web工程:
如果tomcat运行没有报错,就代表配置成功。但是,在IDEA中,有可能会报下面错误:
1 [2016-08-31 09:20:10,763] Artifact newClassProject1:war exploded: Error during artifact deployment. See server log for details.
2
3 [2016-08-31 09:20:10,764] Artifact newClassProject1:war exploded:
4 com.intellij.javaee.oss.admin.jmx.JmxAdminException: com.intellij.execution.ExecutionException:
5 D:\xxx\xxx\xxx\xxx\out\artifacts\xxx_war_exploded not found for the web module.
解决方案为:
3.5,Struts2的Action配置(配置一个请求的完整流程)(重要)
第一步: 在struts.xml中配置package和action,写如下代码
1 <struts>
2 <package name="p1" extends="struts-default" namespace="/user">
3 <!--
4 package:表示包
5 name:包名(唯一性)
6 extends;继承 固定写法: struts-default
7 abstract:抽像包,被用与继承,一般不声明action
8 namespace:命名空间,访问路径,默认值为空字符串(加长路径阶数)
9
10 action :动作,
11 name : 相当于Servlet的映射路径
12 class : 处理请求的类,相当于Servlet类
13 method: 处理请求的方法
14
15 result : 结果,写返回的jsp页面
16 -->
17 <!--访问路径-->
18 <!--http://localhost:8080/day01_structs/user/hello-->
19 <action name="hello" class="com.gyf.web.action.HelloAction" method="sayHello">
20 <result name="success">/success.jsp</result>
21 </action>
22 </package>
23 </struts>
第二步:写一个HelloAction的类,并需要写个sayHello方法
1 public class HelloAction {
2 public String sayHello() throws Exception {
3 System.out.println("Hello world");
4 return "success";
5 }
6 }
在IDEA中被配置的类会有特殊标识,若出现下图所示的标识,则代表配置成功。
第三步:添加一个success.jsp页面
1 <%@ page contentType="text/html;charset=UTF-8" language="java"
2 pageEncoding="utf-8" %>
3 <html lang="en">
4 <head>
5 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
6 <title>demo1</title>
7 </head>
8 <body>
9 Hello,world!
10 </body>
11 </html
第四步:浏览器访问
http://localhost:8080/day01_structs/user/hello 或者:http://localhost:8080/day01_structs/user/hello.action
struts默认是处理.action的请求,或者不带action也可以,其它后缀的都不会拦截,会放行,如jsp
3.6,struts.xml没有标签提示问题(了解)
1,电脑联网,会自动搜索struts的dtd
2,配置本地dtd,打开偏好设置,设置本地的dtd文件
struts-2.3.dtd文件可以从struts2-core-2.3.33.jar包内找到
4,Struts2的执行流程图(了解)
5,Struts2的内部结构(了解)
其中,只有黄色的部分是我们需要写的。
6,Struts2配置文件的加载顺序
6.1,加载时机
当应用被tomcat加载的时候,struts2的配置文件就已经被加载过了。
6.2,加载顺序
6.3,default.properties的一些默认配置
6.4,struts-defaults中默认的拦截器分组
如图,默认的包里有一结果类型,如转发和重定向。
如图,默认情况下,struts会使用defaultStack的拦截器分组。
struts-defualts中主要的内容:结果类型、拦截器分组,默认使用的接替器分组。
6.5,修改struts的访问后缀(了解)
第一种方式:在struts.xml的配置文件中添加下列代码,修改后缀名为.do
1 <constant name="struts.action.extension" value="do"></constant>
第二种方式: 在src下创建struts.properties,添加struts.action.extension=htm
注意:如果这样配置会覆盖struts.xml的配置。
第三种方式:在web.xml中配置
1 <filter>
2 <filter-name>struts2</filter-name>
3 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
4
5 <init-param>
6 <param-name>struts.action.extension</param-name>
7 <param-value>do</param-value>
8 </init-param>
9
10 </filter>
6.6,配置struts的开发模式(可以显示更多的错误信息)
1 <!--配置开发模式(显示错误信息更多点)-->
2 <constant name="struts.devMode" value="false"></constant>
7,Struts配置文件的主要元素讲解(重要)
7.1,package元素
作用: 在struts2的配置文件中引入了面向对象思想,使用了分包管理。易于管理动作类。便于模块化开发动作类。
属性:
namespace详解:
1,namespace的默认取值是一个"",
注意:默认值不是/,写自定义的namespace时需要加/
注意:需要在访问action前添加红色命令空间
2,namespace的查找规则
7.2,action元素
作用:处理动作,处理请求路径。
属性:
name:动作名称
class:动作类名称
method:动作类中的方法名称。默认是public String execute() {}
方法的要求:
1,public 的
2,返回值必须是String
3,没有参数
动作类的第一种写法:
直接写个Action类,不需要继承任何类,然后在struts.xml中配置。
1 package com.gyf.web.action;
2
3 public class HelloAction {
4 public String sayHello() throws Exception {
5 // int i = 3 / 0;
6 System.out.println("Hello world");
7 return "success";
8 }
9 }
1 <package name="p1" extends="struts-default" namespace="/user">
2 <!--访问路径-->
3 <!--http://localhost:8080/day01_structs/user/hello-->
4 <action name="hello" class="com.gyf.web.action.HelloAction" method="sayHello">
5 <result name="success">/success.jsp</result>
6 </action>
7 </package>
动作类的第二种写法:
写个Action类实现Action接口,然后实现execute方法。
1 public class HelloAction2 implements Action {
2
3 @Override
4 public String execute() throws Exception {
5 return SUCCESS;
6 }
7 }
1 <!--第二种配置方法(默认会访问execute()方法)-->
2 <action name="login2" class="com.gyf.web.action.HelloAction2">
3 <result name="success">/success.jsp</result>
4 </action>
Action接口中,有一些静态常量,如下图:
常量说明:
动作类的第三种写法:(推荐使用的方式)
写个Action类继承ActionSuport类(ActionSupport是实现Action接口的类)
1 public class HelloAction3 extends ActionSupport {
2
3 public String login() {
4
5 return SUCCESS;
6 }
7
8 }
1 <!--第三种,继承ActionSupport-->
2 <action name="login3" class="com.gyf.web.action.HelloAction3">
3 <result name="success">/success.jsp</result>
4 </action>
默认的动作类:
在struts-default.xml中定义了默认动作类和方法。
就是com.opensymphony.xwork2.ActionSupport 这个类。
struts.xml:可以在Action中不配置 class 和method,会由默认的动作类来处理,ActionSupport的excute方法返回的就是success
1 <!--默认的动作请求,默认的处理类ActionSupport-->
2 <action name="login4">
3 <result name="success">/success.jsp</result>
4 </action>
修改默认的动作类:(一般很少改)
1 <package name="m1" extends="struts-default" namespace="/god">
2 <!--更改默认处理的Action-->
3 <default-class-ref class="com.gyf.web.action.UserAction"></default-class-ref>
4 </package>
动作访问的通配符:
案例:用户的增删改查
1 public class UserAction extends ActionSupport {
2 //添加用户
3 public String add() {
4 return SUCCESS;
5 }
6 public String delete() {
7 return SUCCESS;
8 }
9 public String update() {
10 return SUCCESS;
11 }
12 public String find() {
13 return SUCCESS;
14 }
15 }
1 <action name="add" class="com.gyf.web.action.UserAction" method="add">
2 <result name="success">/add.jsp</result>
3 </action>
4 <action name="delete" class="com.gyf.web.action.UserAction" method="delete">
5 <result name="success">/delete.jsp</result>
6 </action>
7 <action name="update" class="com.gyf.web.action.UserAction" method="update">
8 <result name="success">/update.jsp</result>
9 </action>
10 <action name="find" class="com.gyf.web.action.UserAction" method="find">
11 <result name="success">/find.jsp</result>
12 </action>
Jsp:所有的jsp页面(4个)简单写上文字
*号通配符优化struts.xml代码
1 <!--动作访问的通配符/{1}指第一个*号-->
2 <action name="*" class="com.gyf.web.action.UserAction" method="{1}">
3 <result name="success">/{1}.jsp</result>
4 </action>
多个*号通配符:升级版:【很少用】
优先级:绝对匹配优先。使用通配符的按照在配置文件中的先后顺序进行匹配的。
动态方法的调用:(不经常用)
7.2,result元素
作用:为动作指定结果视图
属性:
name:逻辑视图的名称,对应着动作方法的返回值。默认值是success
type:结果类型,指的就是用什么方式转到定义的页面。默认是dispatcher转发。
result 中 type 的取值:
result中type的取值有四种类型
type的默认取值是dispatcher
type属性的取值在struts-default.xml中定义着
redirect重定向:
chain 转发到同一个名称空间的动作
redirectAction 重定向到同一个名称空间的动作
chain 转发到不同一个名称空间的动作
redirectAction重定向到不同一个名称空间的动作
result元素中param子元素
在转发或者重定向到不同包下的动作时,都用到了result元素的子元素param。
param元素的作用:依赖注入(Dependence Injection)思想
我们通过struts-default.xml中的resultTypes元素中配置可以看出,每个结果类型视图其实都是靠一个类来实现的。
而param元素就是将配置的参数,注入到该类中。
调用的是对应类的setter方法进行注入的。
1 <!--result属性-->
2 <action name="action1" class="com.gyf.web.action.Demo1Action">
3 <!--type属性-->
4 <!--
5 dispatcher:转发到一个页面(jsp),默认值
6 redirect:重定向到一个页面
7 chain:转发到action
8 redirectAction:重定向到另一个action
9
10 -->
11 <!--suppress Struts2ModelInspection -->
12 <!--转发到同一个包下-->
13 <!--<result name="success" type="chain">action2</result>-->
14 <!--转发到不同包下-->
15 <result name="success" type="chain">
16 <!--依赖注入-->
17 <param name="namespace">
18 /n2
19 </param>
20
21 <param name="actionName">
22 action3
23 </param>
24 </result>
25 </action>
自定义结果类型:
其实结果类型就是一个类,这些类都实现com.opensymphony.xwork2.Result接口
或者继承自该接口的实现类org.apache.struts2.dispatcher.StrutsResultSupport。
这些类都有一个doExecute方法,用于执行结果视图。【查看源码各种结果类型的类结构】
struts的内部实现就是Servlet
综上所述自己写一个结果视图
例子:输出CAPTCHA图像的结果类型
CAPTCHA(Completely Automated Public Turing Test to Tell Computers and Humans Apart 全自动区分计算机和人类的图灵测试)————>简称:验证码。
优化自定义结果类型:
目的:更加灵活的设置验证码的宽度和高度
全局视图和局部视图:
动作类中的servlet api访问:
获取servlet 的api方式:
第一种:通过ServletActionContext获取 【推荐使用】
第二种:通过注入方式:先让Action实现两个接口ServletRequestAware,ServletResponseAware
1 package com.gyf.web.action;
2
3 import com.opensymphony.xwork2.ActionSupport;
4 import org.apache.struts2.ServletActionContext;
5 import org.apache.struts2.interceptor.ServletRequestAware;
6 import org.apache.struts2.interceptor.ServletResponseAware;
7 import org.apache.struts2.util.ServletContextAware;
8
9 import javax.servlet.ServletContext;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12 import javax.servlet.http.HttpSession;
13 import javax.xml.ws.spi.http.HttpContext;
14
15 public class TestAction extends ActionSupport implements ServletRequestAware,ServletResponseAware, ServletContextAware {
16
17 public String test() {
18 //1,获取servlet的api
19 //第一种方式,通过ServletActionContext
20 //1,response
21 HttpServletResponse response = ServletActionContext.getResponse();
22 //2,request
23 HttpServletRequest request = ServletActionContext.getRequest();
24 //3,session
25 HttpSession session = request.getSession();
26 //4,application(ServletContext)
27 ServletContext application = ServletActionContext.getServletContext();
28
29 // none不跳转,也就是不用找result标签
30 System.out.println(request);
31 System.out.println(response);
32 System.out.println(session);
33 System.out.println(application);
34 return NONE;
35 }
36
37 HttpServletResponse response;
38 HttpServletRequest request;
39 ServletContext context;
40 public String test2(){
41
42 //1,获取servlet的api
43 //第二种方式:通过实现接口,让struts自动注入进来
44 System.out.println(request);
45 System.out.println(response);
46 return NONE;
47 }
48
49 @Override
50 public void setServletRequest(HttpServletRequest httpServletRequest) {
51 this.request = request;
52
53 }
54
55 @Override
56 public void setServletResponse(HttpServletResponse httpServletResponse) {
57
58 this.response = response;
59 }
60
61 @Override
62 public void setServletContext(ServletContext servletContext) {
63
64 this.context = context;
65 }
66 }
第二种注入方式原理是因为struts有个拦截器
<interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>来实现的