




已阅读5页,还剩60页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Struts2学习笔记Java相关课程系列笔记之十三笔记内容说明Struts2(李翊老师主讲,占笔记内容100%);目 录一、 Struts2概述11.1为什么要用Struts11.2什么是MVC11.3 JSP Model 1和JSP Model 211.4 Struts2发展史21.5衡量一个框架的标准21.6 Struts2使用步骤21.7 struts.xml内容详解41.8 Struts2提供的方便之处51.9案例:简单登录(使用Strust2)51.10案例:修改1.6、1.9案例使用户不能绕过前端控制器61.11 NetCTOSS项目:显示资费列表71.12 NetCTOSS项目:资费列表分页显示11二、 OGNL技术142.1什么是OGNL142.2 OGNL基本语法142.3 OGNL表达式中加“#”和不加“#”的区别152.4 OGNL体系结构162.5 XWord框架对OGNL进行了改造162.6 ValueStack对象结构162.7 ValueStack结构演示172.8 Struts2标签的使用182.9 Struts2对EL表达式的支持182.10案例:修改1.12案例(使用Struts2标签和OGNL表达式)18三、 Action193.1 Struts2的核心组件193.2 Struts2的工作流程193.3在Action中访问Session和Application193.4 NetCTOSS项目:用户登录203.5 Action属性注入233.6案例:重构NetCTOSS资费列表分页显示(使用属性注入)233.7使用通配符配置Action233.8案例:通配符配置(资费增、改、查)243.9 Struts2中Action的设计经验24四、 Result254.1 Result注册配置254.2 Result组件利用元素的type属性指定result类型254.3常见的Result组件类型254.4 NetCTOSS项目:资费删除254.5 NetCTOSS项目:基于StreamResult生成验证码274.6 NetCTOSS项目:基于JSONResult进行验证码检验294.7 NetCTOSS项目:添加资费模块中的验证资费名是否重复314.8自定义一个Result33五、 Struts2标签355.1 A开头的标签355.2 B开头的标签355.3 C开头的标签355.4 D开头的标签355.5 E开头的标签355.6 F开头的标签355.7 G开头的标签365.8 H开头的标签365.9 I开头的标签365.10 L开头的标签365.11 M开头的标签365.12 O开头的标签365.13 P开头的标签365.14 R开头的标签365.15 S开头的标签365.16 T开头的标签375.17 U开头的标签375.18所有标签都具备的属性375.19案例:常用标签37六、 拦截器406.1 Struts2详细流程图406.2拦截器的作用406.3拦截器的常用方法406.4自定义拦截器步骤406.5 Struts2内置的拦截器416.6案例:拦截器入门426.7拦截器栈456.8 fileUpload拦截器原理456.9案例:使用fileUpload拦截器实现文件上传456.10 NetCTOSS项目:登录检查拦截器47七、 Struts2中如何处理异常497.1异常一般出现在何处497.2如何配置异常49八、 Struts2中如何实现国际化508.1 i18n508.2如何获得中文的Unicode编码508.3浏览器如何决定用哪个资源文件508.4资源文件的命名508.5资源文件的分类508.6实现国际化的步骤50九、 NetCTOSS项目529.1 DAO优化、重构、封装!【重要】529.2资费更新549.3导航条56十、 项目经验5810.1主键用int还是Integer5810.2 “./”表示的意思5810.3导入静态页面,样式、JS失效问题5810.4 和标签5810.5四种情形下的绝对路径写法5810.6 URL和URI5810.7 util.Date和sql.Date5831、 Struts2概述1.1为什么要用Struts1)JSP用HTML与Java代码混用的方式开发,把表现与业务逻辑代码混合在一起给前期开发与后期维护带来巨大的复杂度。2)解决办法:把业务逻辑代码从表现层中清晰的分离出来。3)2000年,Craig McClanahan采用了MVC的设计模式开发Struts主流的开发技术,大多数公司在使用。1.2什么是MVC1)M-Model 模型模型(Model)的职责是负责业务逻辑。包含两部分:业务数据和业务处理逻辑。比如实体类、DAO、Service都属于模型层。2)V-View 视图视图(View)的职责是显示界面和用户交互(收集用户信息)。属于视图的类是不包含业务逻辑和控制逻辑的JSP。3)C-Controller 控制器控制器是模型层M和视图层V之间的桥梁,用于控制流程。比如我们之前项目中写的ActionServlet。1.3 JSP Model 1和JSP Model 21)JSP Model 1最早的JSP/Servlet模式被我们称之为JSP Model 1(JSP设计模式1),在其中有模型层M,但是视图层V的JSP中包含了业务逻辑或控制逻辑,JSP和Servlet紧密耦合。即:JSP(数据的展现和业务流程的控制)+ JavaBean(对数据的访问和运算,Model)。2)JSP Model 2JSP Model 2(JSP设计模式2)和JSP Model1不同之处再与将JSP中的业务逻辑和控制逻辑全部剔除,并全部放入控制层C中,JSP仅仅具有显示页面和用户交互的功能。编程理念:高内聚低耦合。即:M:Model,用JavaBean来做(对数据的访问和运算)V:View,用JSP来作(数据的展现)C:Controller,用Servlet来作(业务流程的控制)1.4 Struts2发展史1)最早出现的Struts1是一个非常著名的框架,它实现了MVC模式。Struts1简单小巧,其中最成熟的版本是Struts1.2。2)之后出现了WebWork框架,其实现技术比Struts1先进,但影响力不如Struts1。3)在框架技术不断发展的过程中,有人在WebWork的核心XWork的基础上包装了Struts1(算是两种框架的整合),由此,结合了Struts1的影响力和WebWork的先进技术,Struts2诞生了。4)Struts2不是Struts1的升级,它更像是WebWork的升级版本。1.5衡量一个框架的标准1)健壮性:Struts2.0不健壮(带0的就是实验品),Struts2.1.8是健壮的(2.1.6也不健壮,该版本BUG较多),3颗星。2)易用性:易用性越好,原理则越复杂,4颗星。3)扩展性:Struts2,5颗星。4)侵入性:即对写代码的要求(如:必须继承某个类才能怎么怎么样),越低越好。Struts2低但也有侵入性,4颗星。1.6 Struts2使用步骤step1:创建一个JavaWeb Project,命名为struts01(Struts2只能用在Web项目里)step2:拷贝Struts2的核心Jar包到WEB-INF/lib/下,基本功能核心jar包 5个:1)xwork-core-2.1.6.jar:Struts2核心包,是WebWork内核。2)struts-core-2.1.8.jar:Struts2核心包,是Struts框架的“外衣”。3)ognl-2.7.3.jar:用来支持OGNL表达式的,类似于EL表达式,功能比EL表达式强大的多。4)freemarker-2.3.15.jar:freemarker是比JSP更简单好用,功能更加强大的表现层技术,用来替代JSP的。在Struts2中提倡使用freemarker模板,但实际项目中使用JSP也很多。5)commons-fileupload.jar:用于实现文件上传功能的jar包。step3:在web.xml中配置Struts2的前端控制器,Struts2是用Filter(过滤器)实现的前端控制器,它只负责根据请求调用不同的Actionu 注意事项:原来的项目是用Servlet的方式作为控制器。web.xml内容: Struts2 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter Struts2/* step4:在WebRoot下新建jsp文件夹,并在其中创建nameform.jsp和welcome.jsp1)nameform.jsp $error 2) Welcome.jspWelcome,$namestep5:在com.tarena.action包下创建WelcomeAction类private String name;private String error;各自的get/set方法public String execute() System.out.println(WelcomeAction.execute().);if(name=null|.equals(name) error=用户名不能为空;return fail;System.out.println(name: + name);/用于测试if (test.equalsIgnoreCase(name) error=不能使用名字text登录;return fail;elsereturn success;step6:写Struts2所需要的控制器配置文件struts.xml,非常重要!该文件写请求与各个Action(Java类)的对应关系,前端控制器会根据配置信息调用对应的Action(Java类)去处理请求u 注意事项:v 在编写时struts.xml放在src目录中,而部署后该文件位于WEB-INF/classes/下!v 同样的,.properties文件也放src下,部署后也在WEB-INF/classes/下!v 程序一启动,struts.xml就会被加载到内存,并不是现读的。struts.xml内容如下: /jsp/welcome.jsp /jsp/nameform.jsp u 注意事项:xml文件内容严格按照.dtd格式要求,如:不在第一行可能会报错,标签中随意换行也会引起404!step7:部署,地址栏输入:http:/localhost:8080/struts01/day01/welcome.action进行测试,发现一进入页面,则错误提示信息已经显示!为了解决该问题,需要再定义一个用于读取页面,而不是发请求后立即执行WelcomeAction类进行处理,处理应当在点击提交后才执行。step8:在struts.xml中添加新的仅仅用于读取页面 /jsp/nameform.jspstep9:重新部署,地址栏输入:http:/localhost:8080/struts01/day01/welcomeform.action进行测试,发现问题已经解决,可正常执行1.7 struts.xml内容详解1) :作用是为分组,标签下可有多个,而标签有如下属性: name=helloworld:唯一的标识,表示包名为helloworld。u 注意事项:在相同包里的不能重复,不同包的可以重复!namespace=/day01:用来设置该包中的action的地址的命名空间。u 注意事项:v 命名空间中的“/”要写!v 也可以这么写:namespace=/,表示根命名空间,此时Action的访问路径为:http:/localhost:8080/appName/actionName.action 即:http:/localhost:8080/struts01/welcome.actionv 一般写法为:namespace=/day01,此时Action的访问路径为:http:/localhost:8080/appName/namespace/actionName.action 即:http:/localhost:8080/struts01/day01/welcome.actionextends=struts-default:继承的包名,一般继承Struts2默认提供的struts-default包,该包中定义了很多Struts2应用必须的组件(比如:拦截器);该package声明的位置在struts2-core-2.1.8.jar/struts-default.xml文件中。u 注意事项:v appName是部署时项目的名字!v 包只能继承包。不能说包继承某个类!2) :作用是指明每个请求对应的Action类之间的对应关系(一个对应一个请求 ),下可有多个。而标签有如下属性:name=welcome:表示请求的名字为welcome(即welcome.action)class=com.tarena.action.WelcomeAction:格式为“包名.类名”。指定了对应的Action类(Java类)来处理请求。class属性可以不写,不写则Struts2会默认为该添加一个class(自动创建一个类,该类中的execute()方法只有一个return success;语句),作用是转发到对应的中指定的页面。method=xxx:用于指定在对应的Action类中要执行的方法名,该方法的返回值必须是String类型(这是规定!)例如:public String xxx().return string;/返回的string是标签中某个name属性的值(结果的名字)!若没有method属性或method=,则默认调用方法名为execute的方法,即:public String execute().return string。3) :作用是指明执行相应的Action类之后,显示哪种结果页。而标签有如下属性:name=success:是该result的名称,Action返回哪一个result的name值,意味着要转发到哪一个result 所对应的JSP地址,不写name属性,则默认为success。type=:默认dispatcher(转发),还可写json、stream、等10种1.8 Struts2提供的方便之处1)数据的自动封装(输入属性) 根据页面组件的name属性,自动封装到Action中对应的name属性中,即自动调用某属性的set方法。 例如:在JSP页面,而在Action中则会自动给属性private String name赋值。u 注意事项:必须有name属性对应的get和set方法。2)数据的自动传递(输出属性) Action中的属性在JSP页面可以直接用EL表达式拿到,即自动调用某属性的get方法。 例如:Action中的属性private String name;在JSP页面上可以直接$name得到对应的值。1.9案例:简单登录(使用Strust2)step1:新建Web工程struts01,导入Struts2的五个基本核心包,并在web.xml中配置Struts2的前端控制器,web.xml代码,见1.6中step3step2:在WebRoot下创建jsp文件夹,并放入loginform.jsp和welcome.jsp1)loginform.jsp 用户名: 密码: $errorMsg u 注意事项:v 应用名前的“/”要写。v 标签中的action属性只写action=login.action也可!如果写成action=day01/login.action,则会出现叠加问题!可参考Spring笔记12.2节。2)welcome.jsp Welcome,$namestep3:在包com.tarena.action下新建LoginAction类private String name;private String pwd;private String errorMsg;各自的get/set方法public String execute()if(chang.equals(name)&123.equals(pwd)/模拟登录成功return success;/ 与struts.xml某一个对应,用来生产视图elseerrorMsg=用户名或密码错误;return fail;step4:在struts.xml中配置 /jsp/welcome.jsp/jsp/loginform.jsp step5:部署,地址栏输入:http:/localhost:8080/struts01/day01/login.action进行测试,发现一进入页面,则错误提示信息已经显示!为了解决该问题,需要再定义一个用于读取页面,而不是发请求后立即执行LoginAction类进行处理,处理应当在点击登录后才执行。step6:在struts.xml中添加新的仅仅用于读取页面 /jsp/loginform.jspu 注意事项:当前配置指明了class,则需要自己再写一个LoginFormAction类step7:在包com.tarena.action下新建LoginFormAction类public class LoginFormAction public String execute() return success;step8:重新部署,地址栏输入:http:/localhost:8080/struts01/day01/loginform.action进行测试,发现问题已经解决,可正常执行step9:优化:step6也可这么写,此时也不用写step8中的LoginFormAction类了 /jsp/loginform.jsp1.10案例:修改1.6、1.9案例使用户不能绕过前端控制器1)问题描述:1.6和1.9案例都存在一个问题,用户可以绕过前端控制器,直接访问JSP页面,如地址栏直接输入:http:/localhost:8080/struts01/jsp/welcome.jsp,可显示页面,只是获取的名字为空。2)如何解决: step1:将jsp文件夹放入WEB-INF目录下。因为WEB-INF目录中的内容是受保护的,不能直接访问!但能转发过来。step2:修改1.9案例struts.xml中result的转发路径,1.6也同理 /WEB-INF/jsp/loginform.jsp /WEB-INF/jsp/welcome.jsp /WEB-INF/jsp/loginform.jspstep3:测试http:/localhost:8080/struts01/WEB-INF/jsp/welcome.jsp不能直接访问http:/localhost:8080/struts01/WEB-INF/jsp/loginform.jsp也不能直接访问http:/localhost:8080/struts01/day01/loginform.action只能根据请求,访问登录页面1.11 NetCTOSS项目:显示资费列表step1:新建Web工程:NetCTOSS,导入需要的包:Struts2核心包、Oracle数据库驱动包、JSTL包(若为J2EE5.0则不需要导这个包了,若为J2EE1.4则需要导入!)step2:创建COST_CHANG表,并插入数据,别忘记commitcreate table cost_chang( id number(4) constraint cost_chang_id_pk primary key, name varchar2(50) not null, base_duration number(11), base_cost number(7,2), unit_cost number(7,4), status char(1) constraint cost_chang_status_ck check(status in (0,1), descr varchar2(100), creatime date default sysdate, startime date, cost_type char(1);insert into cost_chang values (1,5.9元套餐,20,5.9,0.4,0,5.9元20小时/月,超出部分0.4元/时,default,null,2);insert into cost_chang values (2,6.9元套餐,40,6.9,0.3,0,6.9元40小时/月,超出部分0.3元/时,default,null,2);insert into cost_chang values (3,8.5元套餐,100,8.5,0.2,0,8.5元100小时/月,超出部分0.2元/时,default,null,2);insert into cost_chang values (4,10.5元套餐,200,10.5,0.1,0,10.5元200小时/月,超出部分0.1元/时,default,null,2);insert into cost_chang values (5,计时收费,null,null,0.5,0,0.5元/时,不使用不收费,default,null,3);insert into cost_chang values (6,包月,null,20,null,0,每月20元,不限制使用时间,default,null,1);u 注意事项:在Oracle数据库中,语句大小写都可,但最终在数据库中显示的是大写形式。step3:新建perties到src目录下,将username和password修改为自己的数据库的用户名和密码 user=system password=chang url=jdbc:oracle:thin:localhost:1521:dbchang driver=oracle.jdbc.driver.OracleDriverstep4:在ctoss.util包中创建DBUtils工具类,用于打开连接接和关闭连接public class DBUtils private static String driver;private static String url;private static String user;private static String password;static try Properties props = new Properties(); rops.load(DBUtils.class.getClassLoader().getResourceAsStream(perties); driver = props.getProperty(driver); url = props.getProperty(url); user = props.getProperty(user);password = props.getProperty(password); Class.forName(driver); catch (Exception e) throw new RuntimeException(数据库驱动加载错误,e); public static Connection openConnection() throws SQLException Connection con = DriverManager.getConnection(url, user, password);return con;public static void closeConnection(Connection con) if (con != null) try con.close(); catch (SQLException e) public static void main(String args) throws Exception Connection con = openConnection();/简单测试下System.out.println(con);step5:在ctoss.entity包中创建实体类Cost private Integer id; /资费IDprivate String name; /资费名称 NAMEprivate Integer baseDuration; /包在线时长 BASE_DURATIONprivate Float baseCost; /月固定费 BASE_COSTprivate Float unitCost; /单位费用 UNIT_COSTprivate String status; /0:开通;1:暂停;STATUSprivate String descr; /资费信息说明 DESCRprivate Date startTime; /启用日期 STARTTIMEprivate Date creaTime;/创建时间 CREATIME private String costType;/资费类型 COST_TYPE 各自的get/set方法step6:在ctoss.dao包中新建DAOException类,并继承Exceptionpublic class DAOException extends Exception public DAOException(String message, Throwable cause) super(message, cause);step7:在ctoss.dao包中新建CostDAO接口public interface CostDAO public List findAll() throws DAOException; step8:在ctoss.dao.impl包中新建CostDAOImpl类,并实现CostDAOpublic class CostDAOImpl implements CostDAO private static String findAll = select ID, NAME, BASE_DURATION, BASE_COST, UNIT_COST, CREATIME, STARTIME, STATUS, DESCR, COST_TYPE from COST_CHANG;public List findAll() throws DAOException Connection con = null;try con = DBUtils.openConnection();PreparedStatement stmt = con.prepareStatement(findAll);ResultSet rs = stmt.executeQuery();List costList = new ArrayList();while (rs.next() costList.add(toCost(rs); return costList; catch (SQLException e) e.printStackTrace();throw new DAOException(访问异常, e);/抛自己定义的DAOException finally DBUtils.closeConnection(con);/* 将结果集中的每一条数据转换成每一个Cost对象 */private Cost toCost(ResultSet rs) throws SQLException Cost cost = new Cost();cost.setId(rs.getInt(ID);cost.setName(rs.getString(NAME);cost.setBaseDuration(rs.getInt(BASE_DURATION);cost.setBaseCost(rs.getFloat(BASE_COST);cost.setUnitCost(rs.getFloat(UNIT_COST);cost.setStartTime(rs.getDate(STARTIME);cost.setStatus(rs.getString(STATUS);cost.setCreaTime(rs.getDate(CREATIME);cost.setDescr(rs.getString(DESCR); cost.setCostType(rs.getString(COST_TYPE);return cost;step9:在ctoss.dao包中新建DAOFactory工厂类private static CostDAO costDAO = new CostDAOImpl();public static CostDAO getCos
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年燃烧单词考研真题及答案
- 2025年智能家居互联互通标准与产业布局优化策略报告
- 新能源行业2025年储能技术协同创新趋势报告
- 激光医学测试题目及答案
- 小学音乐会考试题及答案
- 法警专业能力测试题及答案
- 高中物理光的颜色 色散教学设计
- 新能源产品创新2025:市场需求变化与调整策略分析报告
- 甘肃省武威市第十七中学七年级地理上册 2.1 大洲和大洋说课稿2 新人教版
- 2025年初二上册英语试卷及答案
- 宁波银行2025-2026年招聘考试笔试题内容历年考试真题
- 心力衰竭健康教育
- 锂电池实验室管理办法
- 学堂在线 新闻摄影 期末考试答案
- 统编版语文五年级上册 第一单元核心素养展示
- 患者出院健康指导
- 校本研修教学课件
- 物业客服部日常工作
- 宫颈癌的个案护理
- 一例外周静脉炎的护理个案讲课件
- 2025年云南省中考英语试卷真题(含标准答案及解析)
评论
0/150
提交评论