《Struts2学习总结.ppt》由会员分享,可在线阅读,更多相关《Struts2学习总结.ppt(56页珍藏版)》请在三一办公上搜索。
1、项目开发的顺序,Struts2能做什么呢,Struts2的流程图,Struts2框架的完整工作流程,Struts2请求页面 的工作流程,In the diagram,an initial request goes to the Servlet container(such as Jetty or Resin)which is passed through a standard filter chain.The chain includes the(optional)ActionContextCleanUp filter,which is useful when integrating tech
2、nologies such as SiteMesh Plugin.Next,the required FilterDispatcher is called,which in turn consults the ActionMapper to determine if the request should invoke an action.If the ActionMapper determines that an Action should be invoked,the FilterDispatcher delegates control to the ActionProxy.The Acti
3、onProxy consults the framework Configuration Files manager(initialized from the struts.xml file).Next,the ActionProxy creates an ActionInvocation,which is responsible for the command pattern implementation.This includes invoking any Interceptors(the before clause)in advance of invoking the Action it
4、self.Once the Action returns,the ActionInvocation is responsible for looking up the proper result associated with the Action result code mapped in struts.xml.The result is then executed,which often(but not always,as is the case for Action Chaining)involves a template written in JSP or FreeMarker to
5、be rendered.While rendering,the templates can use the Struts Tags provided by the framework.Some of those components will work with the ActionMapper to render proper URLs for additional requests.Interceptors are executed again(in reverse order,calling the after clause).Finally,the response returns t
6、hrough the filters configured in the web.xml.If the ActionContextCleanUp filter is present,the FilterDispatcher will not clean up the ThreadLocal ActionContext.If the ActionContextCleanUp filter is not present,the FilterDispatcher will cleanup all ThreadLocals.,其工作流程,模拟Struts2工作原理,创建javaweb工程,模拟Stru
7、ts2工作原理,客户端有两个请求链接,test.jspsuserWorld,模拟Struts2工作原理,分别由两个action来处理,模拟Struts2工作原理,客户端请求提交给Servlet或过滤器来处理,public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException,ServletException HttpServletRequest req=(HttpServletRequest)request;HttpServletResponse re
8、s=(HttpServletResponse)response;String path=req.getServletPath();System.out.println(path=+path);if(/test.jsp.equals(path)chain.doFilter(req,res);else Action userAction=new UserAction();userAction.execute();req.getRequestDispatcher(/success.jsp).forward(req,res);,模拟Struts2工作原理,客户端请求提交给Servlet或过滤器来处理,
9、public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException,ServletException HttpServletRequest req=(HttpServletRequest)request;HttpServletResponse res=(HttpServletResponse)response;String path=req.getServletPath();System.out.println(path=+path);if(/test
10、.jsp.equals(path)chain.doFilter(req,res);else Action userAction=(Action)Class.forName(cn.itcast.action.UserAction).newInstance();userAction.execute();req.getRequestDispatcher(/success.jsp).forward(req,res);,利用Class.forName()方法取得类的完整路径,然后在利用newInstance()方法创建一个实例,模拟Struts2工作原理,客户端请求提交给Servlet或过滤器来处理,p
11、rivate Map map=new HashMap();public void init(FilterConfig filter)throws ServletException map.put(/primer/userAction.action,cn.itcast.action.UserAction);map.put(/helloWorld/helloAction.action,cn.itcast.action.HelloAction);,try Action userAction=(Action)Class.forName(map.get(path).newInstance();userA
12、ction.execute();req.getRequestDispatcher(/success.jsp).forward(req,res);catch(InstantiationException e)e.printStackTrace();catch(IllegalAccessException e)e.printStackTrace();catch(ClassNotFoundException e)e.printStackTrace();,用Map保存客户端请求链接和要访问action的对应值,模拟Struts2工作原理,public class Struts2Filter imple
13、ments Filter private Map map=new HashMap();public void init(FilterConfig filter)throws ServletException map.put(/primer/userAction.action,cn.itcast.action.UserAction);map.put(/helloWorld/helloAction.action,cn.itcast.action.HelloAction);,如果现在客户端请求再增加一个链接,这个时候是不是需要在Struts2Filter类中修改init()方法?,考虑是否可以增加一
14、个配置文件,将这些请求链接和action的对应值保存在配置文件中?,模拟Struts2工作原理,增加一个struts.xml的配置文件,public void init(FilterConfig filter)throws ServletException/解析struts.xml文件,放置xml文件到信息集合中-struts2框架实现 map.put(/primer/userAction.action,cn.itcast.action.UserAction);map.put(/helloWorld/helloAction.action,cn.itcast.action.HelloAction
15、);,Struts2框架中哪些是需要我们来编写的?,Struts2的基本配置,访问HelloWorld应用的路径的设置,在struts2中,访问struts2中action的URL路径由两部份组成:包的命名空间+action的名称例如:访问本例子HelloWorldAction的URL路径为:/primer/helloWorldAction.action(注意:完整路径为:http:/localhost:端口/内容路径/primer/helloWorldAction.action)。另外我们也可以加上.action后缀访问此Action。/success.jsp,Action名称的搜索顺序,1
16、获得请求路径的URI,例如url是:http:/server/struts2/path1/path2/path3/test.action2首先寻找namespace为/path1/path2/path3的package,如果存在这个package,则在这个package中寻找名字为test的action,如果不存在这个package则转步骤3;3寻找namespace为/path1/path2的package,如果存在这个package,则在这个package中寻找名字为test的action,如果不存在这个package,则转步骤4;4寻找namespace为/path1的package,如
17、果存在这个package,则在这个package中寻找名字为test的action,如果仍然不存在这个package,就去默认的namaspace的package下面去找名 字为test的action(默认的命名空间为空字符串“/”),如果还是找不到,页面提示找不到action。,Action配置中的各项默认值,问题:如果没有为action指定class,默认是com.opensymphony.xwork2.ActionSupport 执行ActionSupport中的execute方法 由struts-default.xml文件 决定/success.jsp/success.jsp 1如果没
18、有为action指定class,默认是ActionSupport。2如果没有为action指定method,默认执行action中的execute()方法。ActionSupport的execute方法里面就一句话return success;3如果没有指定result的name属性,默认值为success。,Action配置中的各项默认值,问题:如果请求的路径查找不到action的情况下,程序运行会抛出异常,可以通过配置当找不到action的情况下,会执行默认的action/success.jsp/success.jsp,ActionSupport,类是默认的 Action 类.在编写 Ac
19、tion 类时,通常会对这个类进行扩展,Struts 2处理的请求后缀,StrutsPrepareAndExecuteFilter是Struts 2框架的核心控制器,它负责拦截由/*指定的所有用户请求,当用户请求到达时,该Filter会过滤用户的请求。默认情况下,如果用户请求的路径不带后缀或者后缀以.action结尾,这时请求将被转入Struts 2框架处理,否则Struts 2框架将略过该请求的处理。根据配置文件:struts2-core-2.1.8.1.jar包下的 org.apache.struts2/default.properties文件定义的常量决定 struts.action.e
20、xtension=action,默认处理的后缀是可以通过常量”struts.action.extension“进行修改的,如下面配置Struts 2只处理以.do为后缀的请求路径:如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。如:,细说常量定义,常量可以在struts.xml或struts.properties中配置,建议在struts.xml中配置,两种配置方式如下:在struts.xml文件中配置常量 在struts.properties中配置常量,(struts.properties文件放置在src下)struts.action.extension=do.go因为常量
21、可以在多个配置文件中进行定义,所以我们需要了解下struts2加载常量的搜索顺序:1 struts-default.xml2 struts-plugin.xml3 struts.xml4 struts.properties(自己创建)5 web.xml如果在多个文件中配置了同一个常量,则后一个文件中配置的常量值会覆盖前面文件中配置的常量值.,常用的常量介绍,指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker、velocity的输出 该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配
22、*.action的请求都由Struts2处理。如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 配置当国际化文件修改时,重新加载该国际化资源文件,默认值是false(不重新加载),true为重新加载 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值是false(不重新加载),true为重新加载 开发模式下使用,这样可以打印出更详细的错误信息,默认值为false(生产环境下使用),开发阶段最好打开 默认的视图主题 与spring集成时,指定由spring负责action对象的创建
23、该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性 为 false 上传文件的大小限制,指定多个struts配置文件,在大部分应用里,随着应用规模的增加,系统中Action的数量也会大量增加,导致struts.xml配置文件变得非常臃肿。为了避免struts.xml文件过于庞大、臃肿,提高struts.xml文件的可读性,我们可以将一个struts.xml配置文件分解成多个配置文件,然后在struts.xml文件中包含其他配置文件。下面的struts.xml通过元素指定多个配置文件:通过这种方式,我们就可以将Struts 2的Ac
24、tion按模块添加在多个配置文件中。,Struts2的结果类型,结果类型转发举例,action中增加:HttpServletRequest request=ServletActionContext.getRequest();request.setAttribute(username,username);success.jsp页面中增加:resulttype:$requestScope.username得出结果:在success.jsp页面中得到username的值。,resulttype:username,result,每个 action 方法都将返回一个 String 类型的值,Struts
25、 将根据这个值来决定响应什么结果.每个 Action 声明都必须包含有数量足够多的 result 元素,每个 result 元素分别对应着 action 方法的一个返回值.result 元素可以有下面两个属性name:结果的名字,必须与 Action 方法的返回值相匹配,默认值为 successtype:响应结果的类型.默认值为 dispatcher,北京传智播客教育,结果类型,在struts2-core-2.3.3.jar包下的struts-default.xml配置文件:,结果类型:dispatcher,dispatcher 结果类型是最常用的结果类型,也是 struts 框架默认的结果类
26、型该结果类型有一个 location 参数,它是一个默认参数查看API文档org.apache.struts2.dispatcher.ServletDispatcherResult dispatcher 结果类型将把控制权转发给应用程序里的某个资源.dispatcher 结果类型不能把控制权转发给一个外部资源.若需要把控制权重定向到一个外部资源,应该使用 redirect 结果类型,等同,结果类型:dispatcher的两种写法,/resulttype/success.jsp/resulttype/success.jsp,结果类型:dispatcher的底层代码说明,在struts-defau
27、lt.xml文件中找到ServletDispatcherResult.actionpublic class ServletDispatcherResult extends StrutsResultSupport public void doExecute(String finalLocation,ActionInvocation invocation)throws Exception RequestDispatcher dispatcher=request.getRequestDispatcher(finalLocation);dispatcher.forward(request,respon
28、se);StrutsResultSupport.actionpublic abstract class StrutsResultSupport implements Result,StrutsStatics public void setLocation(String location)this.location=location;,结果类型:redirect,redirect 结果类型将把响应重定向到另一个资源,而不是转发给该资源.redirect 结果类型接受下面这些参数:location:用来给出重定向的目的地parse:用来表明是否把 location 参数的值视为一个 OGNL 表达
29、式来解释.默认值为 trueredirect 结果类型可以把响应重定向到一个外部资源struts-default.xml中的,等同,结果类型:redirect的底层代码说明,在struts-default.xml文件中找到ServletRedirectResult.actionpublic class ServletRedirectResult extends StrutsResultSupport implements ReflectionExceptionHandler protected void doExecute(String finalLocation,ActionInvocati
30、on invocation)throws Exception sendRedirect(response,finalLocation);protected void sendRedirect(HttpServletResponse response,String finalLocation)throws IOException response.sendRedirect(finalLocation);StrutsResultSupport.actionpublic abstract class StrutsResultSupport implements Result,StrutsStatic
31、s public void setLocation(String location)this.location=location;,北京传智播客教育,结果类型:redirectAction,redirectAction 结果类型把响应重定向到另一个 ActionredirectAction 结果类型接受下面这些参数:actionName:指定“目的地”动作的名字.它是默认属性namespace:用来指定“目的地”动作的命名空间.如果没有配置该参数,Struts 会把当前 Action 所在的命名空间作为“目的地”的命名空间,查看API文档,结果类型:redirectAction的底层代码说明,
32、在struts-default.xml文件中找到ServletActionRedirectResult.actionpublic class ServletActionRedirectResult extends ServletRedirectResult public void setActionName(String actionName)this.actionName=actionName;public void setNamespace(String namespace)this.namespace=namespace;ServletRedirectResult.actionpubli
33、c class ServletRedirectResult extends StrutsResultSupport implements ReflectionExceptionHandler protected void doExecute(String finalLocation,ActionInvocation invocation)throws Exception sendRedirect(response,finalLocation);protected void sendRedirect(HttpServletResponse response,String finalLocatio
34、n)throws IOException response.sendRedirect(finalLocation);,通配符和动态方法调用,通配符举例-BookAction,public class BookAction extends ActionSupport public String execute()throws Exception System.out.println(BookAction*execute();return null;/*显示图书添加页面*/public String add()System.out.println(显示图书添加页面);return add;,通配符
35、举例-struts-pattern.xml,/pattern/BookAction.jsp,通配符举例BookAction如何自定义方法,在action中增加新的方法的要求:方法最好要用public修饰 方法的名称自定义 方法没有参数 方法的返回值为String,要定义的方法就是与execute方法的方法名称不同,其他的都一样,只有这样的定义方法struts2才识别,通配符映射,一个 Web 应用可能有成百上千个 action 声明.可以利用 struts 提供的通配符映射机制把多个彼此相似的映射关系简化为一个映射关系通配符映射规则若找到多个匹配,没有通配符的那个将胜出若指定的动作不存在,St
36、ruts 将会尝试把这个 URI 与任何一个包含着通配符*的动作名及进行匹配若 Struts 找到的带有通配符的匹配不止一个,最后一个匹配将胜出被通配符匹配到的 URI 字符串的子串可以用 1,2 来引用.1 匹配第一个子串,2 匹配第二个子串0 匹配整个 URI*可以匹配零个或多个字符,但不包括/字符.如果想把/字符包括在内,需要使用*.如果需要对某个字符进行转义,需要使用.,通配符映射示例(1),包声明:,上面的包声明可以由正确的命名空间和_add 组成的 URI 来调用,/pattern/BookAction.jsp/pattern/BookAction.jsp/pattern/Book
37、Action.jsp,通配符映射示例(2),包声明:,上面的包可改写为:,通配符映射示例(3),包声明:,上面的包可改写为:,动态方法调用,动态方法调用:通过 url 动态调用 Action 中的方法如果Action中存在多个方法时,我们可以使用!+方法名调用指定方法默认情况下,Struts 的动态方法调用处于激活状态,若想禁用该功能,则可以在 struts.xml 文件中添加如下 constant 元素:,Action的配置:,Jsp页面的代码:,使用通配符定义action,Action的配置:,Jsp页面的代码:,开发中比较常用这种方式调用action中的方法,全局结果,当多个action
38、中都使用到了相同result,这时我们应该把result定义为全局结果/message.jsp注:局部的会覆盖全局全局结果和局部结果的区别:*全局结果:对该包下所有的action配置起作用*局部结果:只对当前的action起作用Struts2中 应用范围内action的实例,每个请求都会创建一个action实例,Interceptor 的工作流程,Struts2的流程图,Struts2的处理流程,StrutsPrepareAndExecuteFilter,Interceptor,Action,Result,Jsp/html,用户请求,Struts2内置的一些拦截器或用户自定义拦截器,用户编写的
39、action类,类似struts1中的Action,类似struts1中的forward,响应,Struts2的拦截器举例,如果写一段程序来完成一项功能的话,有可能是这样做的:class Aaa()第1步;第2步;第3步;第4步;,Struts2的拦截器举例,class Aaa()第1步;第2步;第3步;第4步;,class A1第1步;class A2第2步;class A3第3步;class A4第4步;,分离关注,Struts2的拦截器中的分离关注,把过滤器要完成的事情委托给多个类完成,这种观点就是分离关注,过滤器负责调用这些类。处理Cookies的拦截器(处理web中的cookies)
40、令牌拦截器(处理表单重复提交)参数拦截器 文件上传拦截器 i18n拦截器(处理国际化)自定义拦截器,拦截器和过滤器的区别,相同点 都是拦截作用不同点 过滤器是J2EE中的规范,任何javaWeb程序都可以使用 拦截器是Struts2框架独有的,离开了Struts2框架,拦截器将不能使用,拦截器是依赖于Struts2框架的 完成的功能不同 过滤器负责拦截请求的路径,解析xml文件 其他拦截功能交给拦截器处理 调用顺序:过滤器拦截器,拦截器概述(struts-default.xml),拦截器概述(演示过滤器和拦截器的执行顺序),使用如下三个拦截器演示struts的执行流程(断点演示)默认的是defaultStack,在栈中的顺序如下:,