JavaWeb及其框架技术 课件 第11章 SSM整合应用案例_第1页
JavaWeb及其框架技术 课件 第11章 SSM整合应用案例_第2页
JavaWeb及其框架技术 课件 第11章 SSM整合应用案例_第3页
JavaWeb及其框架技术 课件 第11章 SSM整合应用案例_第4页
JavaWeb及其框架技术 课件 第11章 SSM整合应用案例_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第11章SSM整合应用案例了解系统架构和项目组织结构掌握Maven项目管理工具的使用熟悉系统环境搭建与配置文件管理掌握SSM框架整合方式掌握登录模板与客户管理模块的编写调试掌握图片文件的上传与显示学习目标在本章,我们将通过Maven进行配置管理,综合前面各章所学知识,使用Spring、SpringMVC、MyBatis、MySQL、JSP、JSTL等技术来设计一个简易的客户管理系统,整合SSM框架,实现系统登录与客户信息管理的功能。11.1系统概述设计一个简易的客户管理系统,系统要求合法的用户登录后进行访问,主要包含客户管理模块和客户类别管理模块。功能模块如图所示:11.1.1系统功能设计在MySQL中设计一个名为crmdb的数据库,并创建Customer表、Type表和User表,这3张表的表结构分别如表11-1、表11-2和表11-3所示。11.1.2数据库设计字段名类型长度是否为空说明idint11否指自动编号,为主键numberint11是指客户编号namevarchar20是指客户名称gendervarchar2是指性别ageint11是指年龄phonevarchar20是指联系电话filenamevarchar50是指照片文件名称type_idint11是指客户类别编号表11-1Customer表字段名类型长度是否为空说明idint11否指自动编号,为主键namevarchar20是指客户类别名称numberint11是指客户类别编号rateDecimal10是指折扣率,保留两位小数字段名类型长度是否为空说明userIdint11否指用户编号,为主键usernamevarchar20是指用户名passwordvarchar20是指密码roleint11是指角色statusbit1是指状态,其中值为1表示正常状态,值为0表示禁用状态表11-3User表表11-2Type表数据库设计完成后,可以根据数据库表建立对应的实体类。在面向对象的设计中,建立Customer类与Type类之间的多对一关系,是在“多”的一方(Customer)加入“一”的一方(Type)的属性关联。11.1.3实体类设计publicclassCustomer{ privateIntegerid; privateIntegernumber; privateStringname; privateStringgender; privateIntegerage; privateStringfilename; privateStringphone; privateTypetype; //省略Getter方法与Setter方法}publicclassType{privateIntegerid;privateStringname;privateIntegernumber;privateDoublerate;//省略Getter方法与Setter方法}publicclassUser{ privateintuserId; privateStringuserName; privateStringpassword; privateintrole; privatebooleanstatus; //省略Getter方法与Setter方法}Maven就是一个包含了项目对象模型(ProjectObjectModel,POM)的软件项目管理工具,可以通过配置描述信息来管理项目的构建、创建报告和文档。该工具可以帮助程序员从烦琐的项目配置工作中解放出来,轻松地进行工程构建、jar包管理、代码编译,自动运行单元测试、打包、生成报表,甚至还能部署项目、生成Web站点。11.2项目构建工具Maven与SSM项目创建1.下载Maven从官网上下载最新版本的Maven,以Maven3.9.0版本为例,下载完成后,将压缩包解压到计算机某一目录下。2.在IDEA中配置Maven在IDEA中配置Maven非常简单。首先打开IDEA,在菜单栏中单击“File”选项;其次单击“Settings”选项,弹出一个设置窗口,在窗口的左侧树形菜单中选择“Build,Execution,Deployment”→“BuildTools”→“Maven”选项,这时会出现如图11-3所示的Maven配置区域。单击“Mavenhomepath”右侧的“...”按钮,打开文件选择器。在文件选择器中,选择本机的Maven安装目录,这时Usersettingsfile和Localrepository的值会自动关联本机Maven的配置文件和在配置文件中指定的本地仓库。3.设置Maven参数详见“settings.xml”文件11.2.1Maven的使用在IDEA中新建项目,在窗口的左侧列表先选择“Maven”选项11.2.2利用Maven创建SSM项目2.输入项目的Name和选择保存位置Location,设置Maven项目的GroupId、ArtifactId和Version,其他可以保持默认设置。这里将Name设置为crmPrj,单击“Next”按钮。11.2.2利用Maven创建SSM项目3.窗口切换到设置Maven本地仓库的界面,如图11-6所示,因为在之前已经实现了在IDEA中集成Maven,所以在此不需要做修改,单击“Finish”按钮完成Module的创建。11.2.2利用Maven创建SSM项目4.创建Maven项目后,虽然在main目录下有存放Web资源的webapp目录,但没有存放Java文件和配置文件的目录。这时需要将java和resources目录设置为存放Java代码和配置文件的根目录。右击java目录,选择“MakeDirectoryas”→“SourcesRoot”,即可设置该目录为代码根目录。根据以上操作将resources目录设置为“ResourcesRoot”,即设置该目录为源代码配置文件的根目录.11.2.2利用Maven创建SSM项目项目创建完成后,需要在pom.xml文件中配置SSM的依赖。11.2.3配置SSM依赖pom.xml文件是Maven的核心文件,由该文件实现项目构建与项目管理等任务。用户根据pom.xml文件指定的目录结构,定义项目需要的各类组件及其他信息,Maven根据pom.xml文件中的内容,自动下载依赖库(包),并导入到项目中,从而完成项目的构建。pom.xml文件结构详见代码文件。例10-1配置文件的示例在SSM框架中,SpringMVC负责Controller层,MyBatis框架负责数据持久层,Spring框架负责使用DI和AOP解耦合、集成DAO层。要让它们协调工作,首先需要设计合适的Java包结构,其次使用配置文件整合SSM。11.3SSM框架整合使用三层架构模式对Java包的结构进行设计。在com.ssm包下创建子包,包的名称如表11-4所示。11.3.1项目结构包名描述entity封装各实体类controller控制器包,即SpringMVC类存放的位置service业务逻辑接口包,对一个或多个DAO层进行再次封装service.impl业务逻辑实现类包,调用DAO层的操作,封装成一个服务dao数据库访问接口包,即MyBatis接口存放的位置interceptor自定义拦截器util工具包,处理日志项目使用Maven工具管理,统一项目目录,使不同IDEA创建的Maven项目可以通用。将SSM项目涉及的多个配置文件统一放到resources文件夹下,描述如表11-5所示,结构如图11-9所示。11.3.1项目结构文件/文件夹描述mapper文件夹用于存放MyBatis映射文件applicationContext.xmlSpring核心配置文件perties数据库链接信息配置文件springmvc.xmlSpringMVC配置文件webapp文件夹存放Web资源,如HTML(HtyperTextMarkupLanguage,超文本标记语言)、CSS(CascadingStyleSheet,层叠样式表)、JavaScript等静态文件及JSP文件。在MVC架构思想下,由于所有请求都要经过控制器才能转发到视图,因此JSP文件一般要放到WFB-INF文件夹下,这样可防止他人通过浏览器直接访问,webapp文件夹的目录结构如图。11.3.1项目结构1.web.xml文件是JavaWeb项目的核心配置文件,主要包括以下3个配置。(1)配置Spring框架的监听器ContenxtLoaderListener,自动装配ApplicationContext,启动SpringIoC容器。(2)配置SpringMVC前端总控制器,处理URL请求与映射。(3)配置由SpringMVC提供的防止中文乱码的过滤器。web.xml文件的主要内容详见代码文件。2.perties文件,数据库的配置,详见代码文件。3.springmvc.xml文件主要配置和扫描使用@Controller注解的类、配置视图解析器和文件上传解析器等,详见代码文件。4.applicationContext.xml文件是Spring框架的配置文件,详见代码文件。11.3.2编写配置文件MyBatis框架提供了两种DAO层设计的方式。(1)使用SqlSession提供的insert()、update()、delete()、select()等方法访问数据库。(2)使用Mapper方式访问数据库,即将DAO层接口搭建在XML映射文件或注解中书写SQL语句。

尽管MyBatis3提供了基于注解的配置,但定义在XML映射文件中的Mapper方式更为灵活。

在使用MyBatis框架的Mapper方式时一般会使用Java接口和XML映射来实现。因为相较于定义在Java方法之上的注解,XML映射文件和Java文件可以做到更彻底的解耦合。11.4MyBatis框架整合软件设计中注重模块的高内聚、低耦合,而MyBatisMapper技术解决的正是Java与SQL耦合在一起的问题。通过XML映射文件和Java文件的分开设计,消除了大量模板型代码。但是正是因为Java代码和SQL语句分离了,SQL语句就无法再像在Java环境下使用String类提供的方法一样进行灵活的拼接、截取等操作,从而引发参数传递、关联关系、动态语句等问题。11.4.1解耦合MyBatis参数一般分为4种:单个基本类型参数、多个基本类型参数、单个JavaBean类型参数和多个混合类型参数。1.单个基本类型参数若传递的是单个基本类型参数,则在映射文件中可以随意命名参数。因为只有一个参效,在MyBatis框架内部处理时不会关心参数名称。2.多个基本类型参数若传递的是多个基本类型参数,则XML映射文件中要使用#{0}、#{1}、#{2}等数字索引形式(注意索引从0开始),或#{param1}、#{param2}、#{param3}等的param索引形式(注意索引从1开始)。3.单个JavaBean类型参数以JavaBean充当参数的一般是实体类,这类参数也被称为实体类型参数。在XML映射文件中接收参数可以直接将其在POJO类中的属性名作为参数名。4.多个混合类型参数多个混合类型参数可能是多个JavaBean类型参数,也可能是JavaBean类型参数和基本类型参数的混合,这时只能通过对Java方法加@Param注解的方式,为XML映射文件中的参数命名。5.#占位符以上使用#{}作为参数的占位符,类似于JDBC的PrepareStatementr的?占位符。若参数值是字符串类型,则会自动拼接前后的单引号。还会在赋值时进行转义操作,有效防止SQL注入。11.4.2参数传递MyBatis

框架的关联关系也被称为高级结果映射,本质上来说是多个表的联合查询过程。当实体与实体之间存在多对一、一对多、多对多三种关系时,MyBatis

框架提供了多种方法将查询结果组装到实体对象中。1.多对一以Customer类和Type类为例,由于Customer类中有一个Type类型的属性,则它和Type类构成了多对一的关系。当在CustomerDao类中设计search()方法时,要查询所有的customer对象和每个对象包含的type对象,这时可以使用别名或者定义ResultMap()方法。2.一对多对于一对多的情况,MyBatis框架提供了<resultMap>标签搭配<collection>标签的解决方案。3.多对多多对多关系在面向对象的实体中,就是在各方都有对方泛型的集合,从任意一方来看对方都是一对多的关系。11.4.3关联关系动态SQL标签是MyBatis框架的一大特色,通过使用动态SQL标签可以完成一些较复杂的操作并简化开发。动态SQL标签主要包括以下标签。if:用来进行简单的条件判断。choose:相当于Java语言中的switch,与JSTL中的choose类似。trim:对包含的内容加上prefix或suffix,即前缀或后缀。where:简化SQL语句中where条件的判断。set:用于设置更新的字段。foreach:一般在构建子查询的SQL语句时使用。11.4.4动态SQL标签完成映射文件设计之后,进行CustomerDao和TypeDao两个接口模块的开发。下面给出文件列表,内容详见代码文件。CustomerDao.java文件CustomerDao.xml文件TypeDao.java文件TypeDao.xml文件11.4.5DAO层设计11.5.1DIIoC(InversionofControl,控制反转)和DI(DependencyInjection,依赖注入)其实解决的是同一个问题,即使用Spring框架来管理接口对应的实现类,并为声明的接口类型变量生成和装配对象,避免使用new语句创建对象和使用大量的set语句为对象属性赋值。在Spring框架中使用XML配置方式或使用注解方式实现DI。其实现原理是当加载Spring框架时,解析XML映射文件或扫描包(找到以@Component、@Controller、@Service和@Repository注解的类),通过“反射机制”生成对象,将类型或名称作为Key放到Map容器中。在使用时,要根据类型(Type)或名称(Name)到容器中搜索,将找到的对象实例通过构造方法和Setter方法赋值,或者直接给@Autowired注解标注的属性赋值。11.5Spring整合1.5.2AOPAOP是面向切面编程,能够让我们在不影响原有功能的前提下,为软件横向扩展功能,如日志、事务等。Spring框架当前的AOP是由动态代理机制实现的,具体是使用JDK自带的动态代理类或CGLib库提供的动态代理工具实现的。使用SpringAOP实现日志程序,先要确保在applicationContext.xml文件中添加一行配置:<aop:aspecti-autoproxy></aop:aspectj-autoproxy>,即启用@AspectJ注解。@Component@AspectpublicclassLogPrint{@Before("execution(*com.ssm.service.impl.*.*(..))")publicvoidmethodBegin(JoinPointjoinPoint){System.out.println("方法开始了");}@After("execution(*com.ssm.service.impl.*.*(..))")publicvoidmethodEnd(){System.out.println("方法结束了");}}11.5Spring整合Spring框架对DAO层的支持主要体现在集成持久层框架上。使用Spring框架可以配置数据源,参见之前的applicationContext.xml文件。首先通过<beanid="dataSource">配置一个使用DBCP数据库连接池的数据源;其次使用<beanid="sqlSessionFactory">标签配置MyBatis框架的SqISessionFactory,并指定数据源和Mapper映射文件的存放路径;最后指定MyBatis框架的Mapper类所在的位置,即DAO层的完整路径。以上步骤可将MyBatis框架和Spring框架集成,由Spring框架管理生成的sqlSession对象并负责提交工作。Spring框架对Service层的支持主要体现在事务管理上,在applicationContext.xml代码中,使用<beanid="transactionManager">标签来定义一个事务管理器,并通过<tx:method>标签设计具体的事务,标签中的name属性指定生效的方法,propagation属性确定事务传播策略。11.5.3对DAO层和Service层支持在Service层中,调用一个或多个DAO层中的功能点组合成为业务逻辑,需要调度多个DAO层的方法进行事务控制,因此需要在applicationContext.xml文件中对方法配置事务。CustomerService接口的代码如下。publicinterfaceCustomerService{ List<Customer>search(Customercondition); CustomersearchById(Integerid); booleanadd(Customercus); booleanupdate(Customercus); booleandelete(Integerid);}CustomerServiceImpl实现类的代码如下。@ServicepublicclassCustomerServiceImplimplementsCustomerService{ @Autowired CustomerDaocusDao; @Override publicList<Customer>search(Customercondition){ List<Customer>list=cusDao.search(condition); returnlist; }//其他方法略}11.5.4Service层设计SpringMVC是基于Servlet封装的用于实现MVC控制的框架,实现前端和服务器端的交互。SpringMVC通过提供DispatcherServlet的Servlet作为网站入口,所有请求都会经过DispatcherServlet进行分发和指派,将具体的URL请求映射到Controller层的方法并进行调用。其配置请参见11.3.2节中web.xml文件的配置。11.6

SpringMVC使用使用SpringMVC提供的@RequestMapping注解可以将一个URL映射到一个类或一个方法,其在内部使用反射机制来实现。以下代码可以让前端发来的“cus/search”路径请求调用CustomerController类中的search()方法。@Controller@RequestMapping("cus")//一级映射publicclassCustomerController{@RequestMapping("search")//二级映射publicModelAndvViewsearch(){ ModelAndViewmv=newModelAndView("cus/show"); //其他代码略}}@RequestMapping注解还有一个method属性,可以指定HTTP请求方式,取值是枚举类型RequestMethod。该枚举类型包含HTTP协议请求方式的所有取值:GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS、TRACE。11.6.1

URL映射在实际使用SpringMVC接收多个参数的过程中,我们习惯使用JavaBean参数接收数据。比如在add()方法中可以改成使用JavaBean接收参数,只要确保前端传来的参数名和JavaBean中的属性名一致,SpringMVC便可以根据方法参数类型,组装对应类型的对象,并根据前端传来的数据对该对象进行属性的赋值。当这一系列的SpringMVC内部操作完成后,该对象就已经完成装配,可以直接传递给Service层的方法调用,这样就消除了创建对象和设置对象各个属性值的模板型代码,代码如下。@RequestMapping("add")publicStringadd(Customercus){ booleanflag=cusservice.add(cus); //其他代码略}11.6.2接收参数1.转发使用SpringMVC进行视图转发,则要先配置视图解析器。SpringMVC支持多种视图解析器,可以参见11.3.2节的springmvc.xml文件,其中<beanid=“viewResolver”>标签配置了JSTLView视图解析器,该解析器可以解析JSP和JSTL。若要找到视图,则可以使用默认方法名、返回字符串视图名和ModelAndView的方法。11.6.3转发、重定向、响应JSON//默认方式:视图名为“showAdd”@RequestMapping("showAdd")publicvoidshowAdd(){}//返回字符串视图名“add”@RequestMapping("showAdd")publicStringshowAdd(){return"add";}//ModelAndView方法返回视图名“add”@RequestMapping("showAdd")publicModelAndviewshowAdd(){ ModelAndviewmv=newModelAndView("add"); List<Type>typeList=typeService.search(); mv.addobject("typeList",typeList); returnmv;}2.重定向重定向是向浏览器响应一个302状态码,在响应header(头部文件信息)的Location属性上指定要重新定向的URL,此时浏览器会自动发起一个新的请求访问新的URL,浏览器地址发生变化。在Servlet中,使用response.sendRedirect("search")语句可以重定向到某个新的路径下,而SpringMVC是在方法的返回值上使用“redirect:路径名”方式实现重定向的,代码如下。 return"redirect:search";。11.6.3转发、重定向、响应JSON3.响应JSON若想要SpringMVC响应一个字符串,则只须在该方法上使用@ResponseBody注解,这样就标注了这个方法返回的字符串不再是要转发的JSP文件的名称,而是要响应给浏览器的字符串内容。@ResponseBodypublicStringhello(){ return"Hello!";}SpringMVC集成了Jackson,可以方便地返回JSON数据。当方法的返回类型是JavaBean或集合时,@ResponseBody注解会调用Jackson,将对象转换为JSON。@ResponseBodypublicList<Customer>query(){ List<Customer>list=cusService.search(); returnlist;}11.6.3转发、重定向、响应JSON以CustomerController类为例,设计增、删、改、查的方法,图片文件上传方法,以及显示新增页面、修改页面的方法,并将访问的URL请求映射到各个方法,示例代码如下。11.6.4Controller的设计@Controller

@RequestMapping("cus")//父路径

publicclassCustomerController{

@Autowired

CustomerServicecustomerService;

@Autowired

TypeServicetypeService;

@RequestMapping("search")

publicModelAndViewsearch(Customercondition){

ModelAndViewmv=newModelAndView("cus/show");

List<Customer>list=customerService.search(condition);

List<Type>typeList=typeService.search();

mv.addObject("list",list);

mv.addObject("typeList",typeList);

mv.addObject("c",condition);

System.out.println("cc1");

returnmv;

}11.6.4Controller的设计@RequestMapping("add")

publicStringadd(Customeremp,@RequestParam("photo")MultipartFilephoto,HttpServletRequestrequest){

if(!photo.isEmpty()){

try{

//使用UUID给图片重命名,并去掉四个“-”

Stringname=UUID.randomUUID().toString().replaceAll("-","");

//获取文件扩展名

Stringext=FilenameUtils.getExtension(photo.getOriginalFilename());

//设置图片上传路径

Stringdir=request.getSession().getServletContext().getRealPath("/upload/");

Filefilepath=newFile(dir);

if(!filepath.exists())filepath.mkdirs();

//以绝对路径保存重命名后的图片

photo.transferTo(newFile(dir+"/"+name+"."+ext));

//把图片储存路径保存到数据库

emp.setFilename("upload/"+name+"."+ext);

}catch(Exceptionex){

ex.printStackTrace();

}

booleanflag=customerService.add(emp);

return"redirect:search";

}11.6.4Controller的设计@RequestMapping(value="update

publicStringupdate(Customercus,@RequestParam("photo")MultipartFilephoto,HttpServletRequestrequest){

if(!photo.isEmpty()){

try{

//使用UUID给图片重命名,并去掉四个“-”

Stringname=UUID.randomUUID().toString().replaceAll("-","");

//获取文件扩展名

Stringext=FilenameUtils.getExtension(photo.getOriginalFilename());

//设置图片上传路径

Stringdir=request.getSession().getServletContext().getRealPath("/upload/");

//以绝对路径保存重命名后的图片

photo.transferTo(newFile(dir+"/"+name+"."+ext));

//把图片储存路径保存到数据库

cus.setFilename("upload/"+name+"."+ext);

}catch(Exceptionex){

ex.printStackTrace();

}

}

booleanflag=customerService.update(cus);

return"redirect:search";

}11.6.4Controller的设计@RequestMapping("delete")

publicStringdelete(Integerid){

booleanflag=customerService.delete(id);

return"redirect:search";

}11.6.4Controller的设计@RequestMapping("showAdd")

publicModelAndViewshowAdd(){

ModelAndViewmv=newModelAndView("cus/add");

List<Type>typeList=typeService.search();

mv.addObject("typeList",typeList);

returnmv;

}@RequestMapping("showUpdate")

publicModelAndViewshowUpdate(Integerid){

Customercus=customerService.searchById(id);

List<Type>typeList=typeService.search();

ModelAndViewmv=newModelAndView("cus/update");

mv.addObject("cus",cus);

mv.addObject("typeList",typeList);

returnmv;

}在com.ssm.interceptor包中,创建拦截器类UserInterceptor,代码如下。11.6.5拦截器的使用publicclassUserInterceptorimplementsHandlerInterceptor{

@Override

publicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,

Objecthandler)throwsException{

Stringurl=request.getRequestURI();

if(url.indexOf(“/login”)>=0){//除了login.jsp可以公开访问,其它URL都拦截

returntrue;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论