Spring MVC

来源:互联网 发布:java 内嵌chrome 编辑:程序博客网 时间:2024/06/08 02:21

Spring MVC
1.Spring MVC框架简介
1.1什么是Spring MVC
Spring MVC属于SpringFrameWork的后续产品。Spring框架提供了构建Web应用程序的全功能MVC模块。使用Spring可插入的MVC架构,从而在使用Spring进行Web开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1,Struts2等。

2.Spring MVC框架结构
这里写图片描述

package com.baobaotao.web;...@Controller                           ① 将UserController变成一个Handler@RequestMapping(“/user”)   ②指定控制器映射的URLpublic class UserController {    @RequestMapping(value = “/register”) ③处理方法对应的URL,相对于                                                                                    ②处的URL    public String register() {              return “user/register”; ④返回逻辑视图名    }}

体系结构:
SpringMVC是基于Model2实现的技术框架,Model2是经典的MVC模型在Web应用中的变体,这个改变主要源于HTTP协议的无状态性。Model2的目的和MVC一样,也是利用处理器分离模型(Model)、视图(View)和控制(Control),达到不同技术层级间松散层耦合的效果,让系统更有灵活、复用性和可维护性。

SpringMVC的整体模块架构:

分析:
1)、 由最先的HTTP发送请求,由所配置的XML中的DispatcherServlet处理。

2)、 DispatcherServlet接受到这个请求后,根据请求的信息及HandlerMapping的配置找到处理请求的处理器Handler。

3)、 得到HandlerMapping对应的Handler后,通过HandlerAdapter对Handler进行封装,再以统一的适配器接口调用Handler。

4)、 处理器完成业务逻辑的处理后返回一个ModelAndView给DispatcherServlet。

5)、 ModelAndView包含逻辑视图名,而非真正的视图对象,DispatcherServlet借由ViewResolver完成逻辑视图名到真实视图对象的解析工作。

6)、 当得到真实View对象后,DispatcherServlet就对这个View对象进行渲染。

7)、 最终返回到客户的HTTP响应。

3.Spring MVC 支持的URL
Spring MVC在启动前必须在web.xml中配置servlet,这样才能拦截到想要映射的url地址。
这里写图片描述
其中,servlet配置了servlet的实现类,而servlet-mapping则定义了Spring MVC起作用的URL模式,常见的配置有三种:
1)/:表示拦截所有的URL,如/test,/test.html;
2)/:这个模式含/,可以多拦截以.jsp结尾的URL
3).xxx这个拦截固定结尾的URL,常见的如:.do,.action,.json等等。

RequestMapping():
基于注解风格的Spring MVC就是通过这个方法来定义映射的URL的,常使用的方式如下:
1)基于普通的URL:这种是最简单的URL映射,可以接收到localhost:8080/contextName/hello
这样的请求
这里写图片描述

2)基于多个普通的url路径
这里写图片描述
3)基于路径变量的URL映射
这种URL映射可以直接在路径上指定变量,通过@PathVariable可以获得对象。
这里写图片描述
4)基于通配风格的URL映射
1.支持的风格:localhost:8080/context/ant12或localhost:8080/context/ant1a
这里写图片描述
2.支持的风格:localhost:8080/context/ant2aaaa或localhost:8080/context/ant2
这里写图片描述
3.支持的风格localhost:8080/context/ant3/aaaa或localhost:8080/context/ant3/123
这里写图片描述
4.支持的风格:localhost:8080/context/ant4/ 或localhost:8080/context/ant4/aaa或localhost:8080/context/ant4/aaa/123
这里写图片描述
5)混用通配和路径变量
这里写图片描述
匹配:localhost:8080/context/ant5/123 或者 localhost:8080/context/ant5/aaa/123 或者 localhost:8080/context/ant5/aaa/123/test
6)基于正则的URL映射
这里写图片描述
匹配:localhost:8080/context/student/wangwu-33 或者 localhost:8080/context/student/zhao4-22

4.Spring MVC 支持的Rest风格URL
REST,即Representational State Transfer的缩写。”表现层状态转化”。研究 计算机科学两大前沿—-软件和网络—-的交叉点
“表现层”其实指的是”资源”(Resources)的”表现层”。 所谓”资源”,就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在。你可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI。要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或独一无二的识别符。
restful URI的设计不该包含动词。因为”资源”表示一种实体,所以应该是名词,URI不应该有动词,动词应该放在HTTP协议中。
举例来说,某个URI是/arcticle/show/1,其中show是动词,这个URI就设计错了,正确的写法应该是//arcticle/1,然后用GET方法表示show。
优质Web架构五条关键原则列举如下:
1)为所有“事物”定义ID
2)将所有事物链接在一起 (超链接)
3)使用标准方法 (Get Post Delete Put)
4)资源多重表述 (针对不同的需求提供资源多重表述 arcticle/1 )
5)无状态通信 (节省服务器内存)

REST是设计风格而不是标准 目的只是让url看起来更简洁实用,是资源状态的一种表达,资源是由URI来指定,对资源的操作包括获取、创建、修改和删除资源这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。通过操作资源的表现形式来操作资源。
常用操作:
GET 获取
POST 提交
PUT 更新
Delete删除

5.Spring MVC 限定请求方法
请求方法,在HTTP中叫动词(verb),除了两个大家熟知的(GET和POST)之外,标准方法集合中还包含PUT、DELETE、HEAD和OPTIONS。这些方法的含义连同行为许诺都一起定义在HTTP规范之中。一般浏览器只支持GET和POST方法。

这里写图片描述

通过请求方法来限定:
示例1:

@RequestMapping(value=”/delete”) public String test1(@RequestParam("userId") String userId){    return "user/test1";            }

所有URL为/delete的请求由test1处理(任何请求方法)

示例2:

@RequestMapping(value="/delete",method=RequestMethod.POST) public String test1(@RequestParam("userId") String userId){    return "user/test1";            }

所有URL为/delete 且请求方法为POST 的请求由test1处理

通过在web.xml中配置一个org.springframework.web.filter.HiddenHttpMethodFilter
通过POST请求的_method参数指定请求方法,HiddenHttpMethodFilter动态更改HTTP头信息。
这里写图片描述

6.Spring MVC 模拟其他请求方法
params和headers分别通过请求参数及报文头属性进行映射,它们支持简单的表达式,下面以params表达式为例说明,headers可以参照params进行理解之。
“param1”:表示请求必须包含名为param1的请求参数。
“!param1”:表示请求不能包含名为param1的请求参数。
“param1!=value1”:表示请求包含名为param1的请求参数,但其值不能为value1。
{“param1=value1”,”param2”}:请求必须包含名为param1和param2的两个请求参数,且param1参数的值必须为value1。

7.消息转换器
这里写图片描述

这里写图片描述
使用@RequestBody/@ResponseBody :将HttpServletRequest的getInputStream()内容绑定到入参,将处理方法返回值写入到HttpServletResponse的getOutputStream()中。

@RequestMapping(value = "/handle41")public String handle41(@RequestBody  String requestBody ) {      System.out.println(requestBody);      return "success";}
@ResponseBody@RequestMapping(value = "/handle42/{imageId}")public byte[] handle42(@PathVariable("imageId") String imageId) throws IOException {       System.out.println("load image of "+imageId);       Resource res = new ClassPathResource("/image.jpg");       byte[] fileData =FileCopyUtils.copyToByteArray(res.getInputStream());       return fileData;}

优点:处理方法签名灵活不受限
缺点:只能访问报文体,不能访问报文头

使用HttpEntity/ResponseEntity:

@RequestMapping(value = "/handle43")public String handle43(HttpEntity<String> httpEntity){                                  long contentLen = httpEntity.getHeaders().getContentLength();       System.out.println(httpEntity.getBody());      return "success";}
@RequestMapping(params = "method=login")   public ResponseEntity<String> doFirst(){       HttpHeaders headers = new HttpHeaders();       MediaType mt=new MediaType("text","html",Charset.forName(“UTF-8"));       headers.setContentType(mt);       ResponseEntity<String> re=null;       String return = new String("test");       re=new ResponseEntity<String>(return,headers, HttpStatus.OK);       return re;   }

优点:处理方法签名受限
缺点:不但可以访问报文体,还能访问报文头

使用HttpEntity/ResponseEntity:

@RequestMapping(value = "/handle51")public ResponseEntity<User>  handle51(HttpEntity<User> requestEntity){      User user = requestEntity.getBody();      user.setUserId("1000");             return new ResponseEntity<User>(user,HttpStatus.OK);}

或者(注意 必须使用post提交 存在请求body部分才能转换 )

@RequestMapping(value = "/handle51")public @ResponseBody List  handle51(@RequestBody User puser){      List list=new ArrayList()      list.add(“hello”);          return list;}

对于服务端的处理方法而言,除使用@RequestBody/@ResponseBody或HttpEntity /ResponseEntity进行方法签名外,不需要进行任何额外的处理,借由Spring MVC中装配的HttpMessageConverter,它即拥有了处理XML及JSON的能力了。
自定义消息转换器MyMessageConventor :

public class MyMessageConventor extends AbstractHttpMessageConverter {    /**     * 该方法中读取http请求头中的数据 转换成被@RequestBody注解的参数类型并返回     */    @Override    public User readInternal(Class clazz,HttpInputMessage inputMessage) throws IOException,HttpMessageNotReadableException {        return new User();    }    /**     * 被@RequestBody注解的参数和@ResponseBody注解返回值 都会调用supports方法验证当前的转换器是否能用于处理该数据类型     * 如果支持  会调用 readInternal 将http消息 转换成方法中被@RequestBody注解的参数     *         会调用writeInternal 将被@ResponseBody注解的返回对象转换成数据字节响应给浏览器     */    @Override    public boolean supports(Class clazz) {        if(clazz==MyController.User.class) return true;        if(List.class.isAssignableFrom(clazz)) return true;        return false;    }    /**     * 将方法被@ResponseBody注解的返回对象转换成数据字节响应给浏览器     * @param t action返回的参数     * @param outputMessage 将消息输出到浏览器     */    @Override    protected void writeInternal(Object t, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException       {        if(t instanceof List){            List t1=(List)t;            outputMessage.getHeaders().set("Content-Type", "text/html;charset=UTF-8");            outputMessage.getBody().write(("a--"+t1.size()+"--a").getBytes("UTF-8"));            outputMessage.getBody().flush();        }    }}

配置消息转换器:
对于定义的消息转换器 必须通过 mvc:annotation-driven进行注册 消息转换器 会对请求的mini类型进行匹配 如果无法匹配 不会进行消息转换
这里写图片描述

8.文件上传下载
使用springMVC包装的解析器(CommonsMultipartResolver)进行文件上传控制 需要引入 apache的 common-fileupload组件包
1:设置表单属性

      <form action="<%=path %>/fileUpload.htm" method="post" enctype="multipart/form-data">        文件  <input type="file" name="myImg"/>      </form>

2:springmvc配置文件中添加文件解析器:

   <!--  名称必须使用  multipartResolver 因为spring容器使用名称注入 文件上传解析器-->   <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">           <property name="maxUploadSize" value="1048576"></property>   </bean>

3: action方法接受文件

   @RequestMapping(value="/fileUpload")   public String fileUpload(@RequestParam("myImg") MultipartFile file) throws        IllegalStateException, IOException{       File destFile=new File("c:/"+file.getOriginalFilename());       file.transferTo(destFile);       return "/param/suc.jsp";   }

SpringMVC使用消息转换器 ByteArrayHttpMessageConverter 设置文件内容为响应体 通过设置响应头ContentDisposition 通知浏览器下载的附件名称

 @RequestMapping(value="/fileDowload")   public ResponseEntity<byte[]> fileDowload() throws Exception{       String fileName="用户.txt";       //需要下载的目标文件       File file=new File("c:/"+fileName);       //设置响应头       HttpHeaders hh=new HttpHeaders();       //设置下载的文件的名称       hh.setContentDispositionFormData("attachment", URLEncoder.encode(fileName, "UTF-8"));       //读取目标文件为二进制数组       byte[] fileByte=FileCopyUtils.copyToByteArray(file);       //构建ResponseEntity对象       ResponseEntity<byte[]> re=new ResponseEntity<byte[]>(fileByte, hh, HttpStatus.CREATED);       return re;   }

9.数据绑定器–ConversionService
数据绑定机理如下图:
这里写图片描述
Spring 3.0在核心模型中添加了一个通用的类型转换模块, ConversionService是Spring类型转换体系的核心接口。
由于ConversionService在进行类型转换时,可以使用到Bean所在宿主类的上下文信息(包括类结构,注解信息),所以可以实施更加高级的类型转换,如注解驱动的格式化等功能。
这里写图片描述

以上User类,通过一个@RequestParam注解,将参数user转换为User对象类型
这里写图片描述

基于ConversionService体系,定义自定义的类型转换器:
这里写图片描述

注册自定义转换器:
这里写图片描述

格式化:带格式字符串<- ->内部对象 相互转换
这里写图片描述

使用支持格式化的转换器:
这里写图片描述

值得注解的是,标签内部默认创建的ConversionService实例就是一个FormattingConversionServiceFactoryBean,自动支持如下的格式化注解:
@NumberFormatter:用于数字类型对象的格式化。
@CurrencyFormatter:用于货币类型对象的格式化。
@PercentFormatter:用于百分数数字类型对象的格式化。

原创粉丝点击