15.3 控制层(Controller)的注解驱动

来源:互联网 发布:淘宝评价采集工具 编辑:程序博客网 时间:2024/06/05 09:22

像15.2节案例的注解
@RequestMapping(“/user”)
注解可以包含的信息有:请求URL、请求参数、请求方法、请求头这4种信息。

好的习惯:对于Controller类,在整个类前加一个注解@RequestMapping,然后它的内部方法有需要再各自在方法前加上@RequestMapping,因为一般同一个类的多个方法是负责相同模块的不同操作。

@RequestMapping支持URL的风格:

这里写图片描述
这里写图片描述

既然URL可以带占位符,那么可以通过@PathVariable将占位符参数绑定到控制器(Controller)方法的参数中。
例:
这里写图片描述

HTTP请求方法有:GET POST DELETE HEAD OPTIONS PUT TRACE,但目前大多数浏览器只支持GET和POST

@RequestMapping完整注释例子:

这里写图片描述

几种典型的处理方法写法:

这里写图片描述

使用Servlet API对象作为入参:

这里写图片描述

spring MVC定义了若干可代理Servlet原生API的类的类,例如WebRequest和NativeWebRequest

IO对象:

这里写图片描述

使用HttpMessageConverter< T > :

作用:将外部数据传递到方法的参数中
spring MVC提供的途径:
这里写图片描述

例1:@RequestBody和@ResponseBody
两者啥区别?
仅仅是方法的参数需要的数据,用@RequestBody标注参数即可,例如下面的handle41方法;
如果整个方法都需要这个数据,就在方法体的外面标注@ResponseBody,例如下面的handle42方法。

在UserController.java中:    @RequestMapping(value = "/handle41")    // 将请求报文体转换为字符串绑定到RequestBody入参中    public String handle41(@RequestBody String body) {        System.out.println(body);        return "success";    }    @ResponseBody    @RequestMapping(value = "/handle42/{imageId}")    // 读取一张图片,并将图片输出到响应流中,客户端将相应这张图片    public byte[] handle42(@PathVariable("imageId") String imageId) throws IOException{        System.out.println("load image of " + imageId);        // 此处只是做个示范,没有用真的imageId的图片        Resource res = new ClassPathResource("/image.jpg");        byte[] fileData = FileCopyUtils.copyToByteArray(res.getInputStream());        return fileData;    }测试:UserControllerTest.java    @Test    public void testhandle41(){        RestTemplate restTemplate = new RestTemplate();        MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();        form.add("username", "tom");        form.add("password", "123456");        form.add("age", "33");        restTemplate.postForLocation("http://localhost:8080/easy_springmvc_test/user/handle41.html", form);    }    @Test    public void testhandle42() throws IOException{        RestTemplate restTemplate = new RestTemplate();        // 4个参数依次为:url、报文体参数类型、该方法的返回类型、url占位符参数的值        byte[] response = restTemplate.postForObject("http://localhost:8080/easy_springmvc_test/user/handle42/{imageId}.html", null, byte[].class,"1233");        Resource outFile = new FileSystemResource("/snap1.jpg");        FileCopyUtils.copy(response,outFile.getFile());    }测试结果:输出username=tom&password=123456&age=33load image of 1233分析:testhandle41把MultiValueMap类型的数据传递到handle41方法中,而handle41中的参数因为@RequestBody自动将MultiValueMap转化为String型。testhandle42将String型的imageId传递到handle42中,handle42返回byte[]的数据,该数据又会返回给testhandle42中的数据byte[] response,从而测试客户端会展示出图片。

例2:使用HttpEntity< T>/ ResponseEntity< T>

这里写图片描述

这里写图片描述

处理XML和JSON

这里写图片描述
这里写图片描述

步骤:
1、在负责Controller类的配置文件baobaotao-servlet.xml里加上与处理XML和JSON相关的信息:

<!-- 用于处理 XML和JSON数据  -->    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"    p:messageConverters-ref="messageConverters"></bean>    <!-- 消息转换器  -->    <util:list id="messageConverters">        <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>        <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>        <bean class="org.springframework.http.converter.StringHttpMessageConverter" />        <!-- 负责xml的两个bean -->        <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter" />        <bean            class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"            p:marshaller-ref="xmlMarshaller" p:unmarshaller-ref="xmlMarshaller">        </bean>        <!-- 负责json的bean -->        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />    </util:list>    <!--  声明 xmlMarshaller即xml装配器 ,使用XStream技术-->       <bean id="xmlMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">        <property name="streamDriver">            <!-- 使用STAX对XML消息进行处理  -->            <bean class="com.thoughtworks.xstream.io.xml.StaxDriver" />        </property>        <property name="annotatedClasses">            <list>                <!-- 使用XStream注解的所有的类在此声明 -->                <value>com.domain.User</value>            </list>        </property>    </bean>

2、UserController类里的方法

    // 该方法作用是把传来的数据user改掉名字    @RequestMapping(value = "/handle51")    public ResponseEntity<User> handle51(HttpEntity<User> requestEntity){        User user = requestEntity.getBody();        user.setUserName("zhaosi");        return new ResponseEntity<User>(user,HttpStatus.OK);    }

3、测试类UserControllerTest里添加方法:

    // 创建RestTemplate实例    private RestTemplate buildRestTemplate(){        RestTemplate restTemplate = new RestTemplate();        // 使用XStream配置器,加载XStream注解的类User        XStreamMarshaller xmlMarshaller = new XStreamMarshaller();        xmlMarshaller.setStreamDriver(new StaxDriver());        xmlMarshaller.setAnnotatedClasses(new Class[]{User.class});        // 创建处理XML报文的HttpMessageConverter,将其组装到restTemplate        MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter();        xmlConverter.setMarshaller(xmlMarshaller);        xmlConverter.setUnmarshaller(xmlMarshaller);        restTemplate.getMessageConverters().add(xmlConverter);        // 创建处理JSON报文的HttpMessageConverter,将其组装到restTemplate        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();        restTemplate.getMessageConverters().add(jsonConverter);        return restTemplate;    }    @Test    public void testhandle51(){        RestTemplate restTemplate = buildRestTemplate();        User user = new User();        user.setUserName("tom");        user.setPassword("123456");        // 请求报文的报文头信息        HttpHeaders entityHeaders =new HttpHeaders();        //  如果是处理XML,就是下面用XML;如果是处理JSON,就把换成json,如下面注释掉的部分。         entityHeaders.setContentType(MediaType.valueOf("application/xml;UTF-8"));        entityHeaders.setAccept(java.util.Collections.singletonList(MediaType.APPLICATION_XML));        //entityHeaders.setContentType(MediaType.valueOf("application/json;UTF-8"));        //entityHeaders.setAccept(java.util.Collections.singletonList(MediaType.APPLICATION_JSON));        // 将User转化为XML放在报文中        HttpEntity<User> requestEntity = new HttpEntity<User>(user,entityHeaders);        ResponseEntity<User> responseEntity = restTemplate.exchange(            "http://localhost:8080/easy_springmvc_test/user/handle51.html", HttpMethod.POST,requestEntity,User.class);        User responseUser = responseEntity.getBody();        Assert.assertNotNull(responseUser);        Assert.assertEquals("zhaosi", responseUser.getUserName());        System.out.println(responseUser.getUserName());    }

4、分析:
测试类里原来的数据user的名为tom,当把它封装在报文中传递给控制类的handle51方法时,该方法把它数据修改为zhaosi,且该方法返回的ResponseEntity< User>会传递到测试方法的responseEntity,通过打印responseUser.getUserName()知道确实成功地修改了用户名。

处理模型数据

如何将模型数据暴露给视图,spring MVC提供了多种途径输出模型数据。

ModelAndView @ModelAttribute ModelMap @SessionAttributes
具体见开发实战P532

0 0