1、 Spring MVC 工作过程6.1 关于关于Spring MVC配置文件配置文件/WEB-INF/web.xmlcontextConfigLocation/WEB-INF/spring/root-context.xmlorg.springframework.web.context.ContextLoaderListenerappServlet org.springframework.web.servlet.DispatcherServletcontextConfigLocation/WEB-INF/spring/appServlet/servlet-context.xml1appServl
2、et/2./WEB-INF/spring/appServlet/servlet-context.xml3./WEB-INF/spring/appServlet/controllers.xml 4/WEB-INF/root-context.xml6.2 Spring MVC控制器控制器Spring控制器的请求和处理风格符合控制器的请求和处理风格符合REST架构的设计。具体表现有如下几点:架构的设计。具体表现有如下几点:具有具有REST风格的风格的URI模板模板:Spring的方法前通过注解符的方法前通过注解符RequestMapping定义定义URI模板,模板,URI的标识定义形式符合的标识定义
3、形式符合REST路径表示路径表示风格。对于路径标识中的变量可在方法的参数定义中通过风格。对于路径标识中的变量可在方法的参数定义中通过PathVariable进进行说明,并在方法中引用。行说明,并在方法中引用。支持内容协商支持内容协商,Spring提供了丰富的内容表现形式,可采用提供了丰富的内容表现形式,可采用HTML、XML、Json等,符合等,符合REST风格中由使用者决定表示形式的特征。一般通过风格中由使用者决定表示形式的特征。一般通过HTTP请请求头的求头的Accept标识的应用类型、请求文件标识的类型、标识的应用类型、请求文件标识的类型、URI参数等内容来识参数等内容来识别对资源的表示
4、。在别对资源的表示。在HTTP响应消息中通过响应消息中通过Content-Type给出响应消息的类给出响应消息的类型。型。支持支持HTTP 方法变换方法变换:REST将将HTTP请求分为请求分为 GET,PUT,POST和和DELETE四种情形四种情形,而而HTML仅支持仅支持 GET和和POST两种方法。为了实现方法请求动作的两种方法。为了实现方法请求动作的转换,可将实际请求的动作信息作为附加参数或通过表单的隐含域传递给方转换,可将实际请求的动作信息作为附加参数或通过表单的隐含域传递给方法。在处理请求的控制器中可根据其方法参数进行过滤处理。法。在处理请求的控制器中可根据其方法参数进行过滤处理
5、。【程序清单程序清单6-4】文件名为文件名为HomeController.javapackage chapter6.jx.cai;import org.slf4j.*;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.*;Controllerpublic class HomeController private static final Logger logger=LoggerFactory.getLogger(HomeController.class)
6、;/获取日志记录对获取日志记录对象象RequestMapping(value=/,method=RequestMethod.GET)public String home()logger.info(Welcome home!);/记录日志记录日志return home;6.2.1 Spring MVC 3.0的的RESTful特性特性URI模板允许在模板允许在URI模式中包含嵌入变量(通过大括号标注)。模式中包含嵌入变量(通过大括号标注)。URI模板通过把模板通过把URI路径的某一字段设置为路径变量的方式来区别不同的资源,例如路径的某一字段设置为路径变量的方式来区别不同的资源,例如:URI模板:
7、模板:/users/user/orders/order对应的对应的URI为为http:/localhost/myapp/users/ding/orders/623835在在URI设计中,建议的设计中,建议的URI规则如下:规则如下:(1)用路径变量来表达层次结构用路径变量来表达层次结构Domain/SubDomain/BusinessAction/ID。比如:比如:hotels/bookings/cancel/id 表示此表示此URI匹配匹配hotels域的域的bookings子域子域,将要进行的是取消某项,将要进行的是取消某项booking的操作。的操作。(2)用逗号或者分号来表达非层次结构
8、用逗号或者分号来表达非层次结构,如:如:/parent/child1;child2(3)用查询变量表达算法参数的输入用查询变量表达算法参数的输入,如:如:http:/ 与控制器相关的注解符与控制器相关的注解符注解符注解符含义含义ControllerController表示该类为一个控制器。表示该类为一个控制器。RequestMappingRequestMapping定义映射方法的访问规则。其所标注方法的参数用来获取定义映射方法的访问规则。其所标注方法的参数用来获取请求输入数据,方法的返回产生响应。请求输入数据,方法的返回产生响应。RequestParam(name)RequestParam(n
9、ame)作为方法参数,获取作为方法参数,获取http请求中请求参数的值。请求中请求参数的值。PathVariable(name)PathVariable(name)作为方法参数,获取作为方法参数,获取URI路径变量的值。路径变量的值。RequestHeader(name)RequestHeader(name)作为方法参数,获取作为方法参数,获取http请求头的值。如:请求头的值。如:Accept-Language得到使用的语言。得到使用的语言。CookieValue(name)CookieValue(name)作为方法参数,访问作为方法参数,访问Cookie变量。变量。SessionAttri
10、butes(name)SessionAttributes(name)作为方法参数,访问作为方法参数,访问Session变量。变量。RequestBodyRequestBody作为方法参数,获取作为方法参数,获取http请求体。请求体。ResponseBodyResponseBody加在方法前,定义方法的返回为加在方法前,定义方法的返回为http响应消息。响应消息。其他类型的标准对象,如:其他类型的标准对象,如:HttpServletRequest、HttpServletResponse、HttpSession、Principal、Locale、Model等也可在控制器等也可在控制器的方法参数中
11、声明,然后在方法内通过参数变的方法参数中声明,然后在方法内通过参数变量访问,这些对象将自动完成依赖注入。量访问,这些对象将自动完成依赖注入。RequestMapping也可能用于类前面,用于定义统一的父路径,而在方法前面也可能用于类前面,用于定义统一的父路径,而在方法前面RequestMapping则要给出子路径。例如:则要给出子路径。例如:ControllerRequestMapping(/users/*)public class AccountsController RequestMapping(active)public ResponseBody List active()等价于以下的定
12、义等价于以下的定义:public class AccountsController RequestMapping(/users/active)public ResponseBody List active()6.2.3 REST其他类型的请求方法的实现其他类型的请求方法的实现由于浏览器由于浏览器form表单只支持表单只支持GET与与POST请求,而请求,而DELETE、PUT等等method并并不支持,不支持,spring3.0添加了一个过滤器,提交处理时可将隐藏的添加了一个过滤器,提交处理时可将隐藏的“_method”参参数转换为相应的数转换为相应的HTTP方法请求。使得支持方法请求。使得支
13、持GET、POST、PUT与与DELETE请求。请求。HiddenHttpMethodFilter org.springframework.web.filter.HiddenHttpMethodFilter HiddenHttpMethodFilter yourServletName 以下针对删除某个栏目功能给出以下针对删除某个栏目功能给出delete操作的实现方法。操作的实现方法。控制器设计如下:控制器设计如下:RequestMapping(value=/column,method=RequestMethod.DELETE)public String deleteColumn(Request
14、Param(title)String title)ColumnDao.delete(title);/业务逻辑实现指定标题栏目的删除业务逻辑实现指定标题栏目的删除 return“redirect:columndelete.jsp”;/重定向到继续删除页面重定向到继续删除页面在调用服务的访问请求中,可通过如下一些方式发送在调用服务的访问请求中,可通过如下一些方式发送DELETE请求:请求:在页面的输入表单中指定一个名称为在页面的输入表单中指定一个名称为“_method”的参数,值为的参数,值为“delete”;通过通过Spring表单标签表单标签中指定一个中指定一个“method”属性,值属性,值
15、为为“delete”;利用利用6.6节将介绍的节将介绍的Spring的的RestTemplate类的类的delete方法调用服务方法调用服务。有的浏览器可用有的浏览器可用AJAX方式来发送方式来发送DELETE操作请求。以下为相应操作请求。以下为相应Javascript代码:代码:xmlhttp=new ActiveXObject(Microsoft.XMLHTTP);myurl=column?title=java;xmlhttp.Open(DELETE,myurl,false);xmlhttp.send(null);。6.3 关于关于MVC显示视图显示视图Spring提供了视图解析器实现对模
16、型数据的显提供了视图解析器实现对模型数据的显示处理,示处理,Spring内置了对内置了对JSP、Velocity、FreeMarker和和XSLT等视图显示模板的支持。等视图显示模板的支持。显示模板中的变量将被模型的实际数据所替换显示模板中的变量将被模型的实际数据所替换。6.3.1 ViewResolver视图解析器视图解析器典型视图解析器 AbstractCachingViewResolver:抽象视图解析器实现了对视图的缓存。:抽象视图解析器实现了对视图的缓存。在视图使用前,通常要一些准备工作,从它继承的视图解析器对要解析的视在视图使用前,通常要一些准备工作,从它继承的视图解析器对要解析的
17、视图进行缓存。图进行缓存。XmlViewResolver:支持:支持XML格式的配置文件,默认的配置文件是格式的配置文件,默认的配置文件是/WEB-INF/views.xml。ResourceBundleViewResolver:实现资源绑定的视图解析,在一个:实现资源绑定的视图解析,在一个ResourceBundle中寻找所需中寻找所需bean的定义,这个绑定通常定义在位于的定义,这个绑定通常定义在位于classpath路径的一个属性文件中,默认的属性文件是路径的一个属性文件中,默认的属性文件是views.properties。UrlBasedViewResolver:UrlBasedVie
18、wResolver实现实现ViewResolver,将视图名直接解析成对应的将视图名直接解析成对应的URL,不需要显式地映射定义。,不需要显式地映射定义。InternalResourceViewResolver:支持:支持InternalResourceView(用于对(用于对Servlet和和JSP的包装),以及其子类的包装),以及其子类JstlView和和TilesView等的解析处理。等的解析处理。VelocityViewResolver:支持对:支持对Velocity模板的解析处理。模板的解析处理。FreeMarkerViewResolver:支持对:支持对FreeMarker模板的解
19、析处理。模板的解析处理。1.使用使用JSP作为视图作为视图 2.使用使用Freemarker作为视图作为视图 6.3.2 栏目显示的栏目显示的MVC实现方案实现方案1控制器设计控制器设计RequestMapping(value=/topmenu,method=RequestMethod.GET)public ModelAndView display(HttpServletRequest request)ApplicationContext applicationContext=RequestContextUtils.getWebApplicationContext(request);UserD
20、ao userDao=(UserDao)applicationContext.getBean(userDAO);ColumnDao coldao=(ColumnDao)applicationContext.getBean(columnDao);List columns=coldao.getAll();String user=request.getRemoteUser();/假设采用假设采用Spring安全认证安全认证int score=userDao.getScore(user);ModelMap modelMap=new ModelMap();modelMap.put(columns,col
21、umns);/定义若干模型参数定义若干模型参数modelMap.put(user,user);modelMap.put(score,score);return new ModelAndView(“topmenu”,modelMap);2显示视图设计显示视图设计 $item.title 用户用户:$user, 积分积分:$score .6.4 用用Spring MVC 实现文件上传应用实现文件上传应用 首先,在服务器的首先,在服务器的lib目录下引入目录下引入Apache的的“commons-fileupload-1.2.2.jar”和和“commons
22、-io-2.0.1.jar”两个两个JAR文件,这两个包可以从相关网站下载。文件,这两个包可以从相关网站下载。其次,在其次,在web应用程序上下文配置文件中定义如下解析器:应用程序上下文配置文件中定义如下解析器:第三,设置页面中请求表单的第三,设置页面中请求表单的enctype属性为属性为“multipart/form-data”,在表单中通过类型为在表单中通过类型为“file”的输入元素选择上传文件;表单的提交方法为的输入元素选择上传文件;表单的提交方法为“POST”。第四,在处理上传请求的控制器中,通过第四,在处理上传请求的控制器中,通过CommonsMultipartFile类型的参数对
23、象获取上传文类型的参数对象获取上传文件数据信息。以下为件数据信息。以下为CommonsMultipartFile的两个的两个常用方法常用方法:byte getBytes():获取上传文件的数据内容;:获取上传文件的数据内容;String getOriginalFilename():获取上传文件的文件:获取上传文件的文件名。名。6.4.1文件上传表单在用户输入界面中提供了文件上传表单。表在用户输入界面中提供了文件上传表单。表单的单的action参数指定相应控制器的参数指定相应控制器的URI。6.4.2 文件上传处理控制器Controllerpublic class FileUpoadContro
24、ller RequestMapping(value=/upload,method=RequestMethod.POST)public String handleFormUpload(RequestParam(file)MultipartFile file)if(!file.isEmpty()String path=d:/images/;/文件上传的目标位置文件上传的目标位置try byte bytes=file.getBytes();/获取上传数据获取上传数据FileOutputStream fos=new FileOutputStream(path+file.getOriginalFilename();/获取文件名获取文件名fos.write(bytes);/将数据写入文件将数据写入文件fos.close();catch(IOException e)return uploadSuccess;elsereturn uploadFailure;