SpringMVC(二) REST 以及SpringMVC的高级用法

在springmvc(一)中主要介绍了一些基本的用法在这里对其进行细化一下:

SpringMVC中的REST:

即 Representational State Transfer。(资源)表现层状态转化。是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用.

@RequestHeader 绑定请求报头的属性值

@CookieValue 绑定请求中的 Cookie 值

Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。如:dept.deptId、dept.address.tel 等,若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个 @SessionAttributes, Spring MVC将在模型中对应的属性暂存到 HttpSession 中。

@SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中

– @SessionAttributes(types=User.class) 会将隐含模型中所有类型为 User.class 的属性添加到会话中。

– @SessionAttributes(value={“user1”, “user2”})

– @SessionAttributes(types={User.class, Dept.class})

– @SessionAttributes(value={“user1”, “user2”},types={Dept.class})

 

1. 使用注解@RequestMapping("item/{id}")声明请求的url{xxx}叫做占位符,请求的URL可以是“item /1”或“item/2”
​
2. 使用(@PathVariable() Integer id)获取url上的数据  
​

/**
* 使用RESTful风格开发接口,实现根据id查询商品
* 如果不一致,例如"item/{ItemId}"则需要指定名称@PathVariable("itemId")。
* @param id
* @return
*/
@RequestMapping("item/{id}")
@ResponseBody
public Item queryItemById(@PathVariable() Integer id) {
Item item = this.itemService.queryItemById(id);
return item;
}
1. @ PathVariable 是 获取 url 上数据 的。 @RequestParam获取请求参数的(包括post表单提交)
​
2. 如果加上@ResponseBody注解,就不会走视图解析器,不会返回页面,目前返回的json数据。如果不加,就走视图解析器,返回页面

springMVC数据格式化:

FormattingConversionServiceFactroyBean 内部已经注册了 :

NumberFormatAnnotationFormatterFactroy:支持对数字类型的属性

使用 @NumberFormat 注解

– JodaDateTimeFormatAnnotationFormatterFactroy:支持对日期类的属性使用 @DateTimeFormat 注解 ;可以对pattern 属性:类型为字符串。指定解析/格式化字段数据的模式, 如:”yyyy-MM-dd hh:mm:ss”等其他的 ​ mvc:annotation-driven/ 默认创建的

ConversionService 实例即为 FormattingConversionServiceFactroyBean

springmvc处理json数据:

1.加入jar包:jackson-annotations(core,databind)-2.2.2.jar;

2.编写目标方法使其返回json:

3.在方法上添加 @ResponseBody注解使用的是HttpMessageConverter<T>;

HttpMessageConverter<T>接口定义的方法: – Boolean canRead(Class<?> clazz,MediaType mediaType): 指定转换器可以读取的对象类型,即转换器是否可将请求信息转换为 clazz 类型的对象,同时指定支持 MIME 类型(text/html,applaiction/json等)

Boolean canWrite(Class<?> clazz,MediaType mediaType):指定转换器是否可将 clazz 类型的对象写到响应流中,响应流支持的媒体类型在MediaType 中定义。

LIst<MediaType> getSupportMediaTypes():该转换器支持的媒体类型。

T read(Class<? extends T> clazz,HttpInputMessage inputMessage):将请求信息流转换为 T 类型的对象。

– void write(T t,MediaType contnetType,HttpOutputMessgae outputMessage):将T类型的对象写到响应流中,同时指定相应的媒体类型为 contentType。使用 HttpMessageConverter<T> 将请求信息转化并绑定到处理方法的入参中或将响应结果转为对应类型的响应信息,

Spring 提供了两种途径:

使用 @RequestBody / @ResponseBody 对处理方法进行标注

使用 HttpEntity<T> / ResponseEntity<T> 作为处理方法的入参或返回值 当控制器处理方法使用到 @RequestBody/ @ResponseBody 或HttpEntity<T>/ResponseEntity<T> 时, Spring 首先根据请求头或响应头的Accept 属性选择匹配的 HttpMessageConverter, 进而根据参数类型或泛型类型的过滤得到匹配的 HttpMessageConverter, 若找不到可用的 HttpMessageConverter 将报错

@RequestBody 和 @ResponseBody 不需要成对出现

@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容(json数据)转换为java对象并绑定到Controller方法的参数上。

​@ResponseBody注解用于将Controller的方法返回的对象,通过springmvc提供的HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端

这里都要配置注解驱动。<mvc:annotation-driven/>

springmvc文件上传:

Spring MVC 为文件上传提供了直接的支持,这种支持是通过即插即用的 MultipartResolver 实现的。Spring 用Jakarta Commons FileUpload 技术实现了一个MultipartResolver 实现类:CommonsMultipartResovler

Spring MVC 上下文中默认没有装配 MultipartResovler,因此默认情况下不能处理文件的上传工作,如果想使用 Spring的文件上传功能,需现在上下文中配置 MultipartResolver

​defaultEncoding: 必须和用户 JSP 的 pageEncoding 属性一致,以便正确解析表单的内容``​为了让 CommonsMultipartResovler 正确工作,必须先将 Jakarta Commons FileUpload 及 Jakarta Commons io的类包添加到类路径下。

<bean id="multipartResolver" class="org.springframework.web.multipart.commoms.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<property name="maxUploadSize" value="5242880"/>
</bean>

代码如下:

public Map<String, Object> add(User user, @RequestParam(name = "file") MultipartFile file, HttpServletRequest request
                               , HttpServletResponse response) {
    System.out.println(file);
    Map<String, Object> map = new HashMap<>();
    if (user.getUsername() != null && user.getPassword() != null) {
        if (file.isEmpty()) {
            map.put("code", "1");
            map.put("msg", "文件为空");
            map.put("data", null);
            return map;
        } else {
            //获取文件的原名
            String fileName = file.getOriginalFilename();
            System.out.println(fileName);
            //转换后的文件名
            String fileNewName = UUID.randomUUID().toString() + fileName;
            String path = "D:/hotel/upload/user/img/";
            File dest = new File(path + fileNewName);
            System.out.println(dest.exists());
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
                try {
                    dest.createNewFile();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            try {
                file.transferTo(dest);
                String filepath = path + fileNewName;
                user.setHeadshot(filepath);
                System.out.println("filepath:" + path + fileNewName);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return userService.addUser(user);
    } else {
        map.put("code", "1");
        map.put("msg", "信息不全");
        map.put("data", null);
        return map;
    }
}

SpringMVC的自定义拦截器:

Spring MVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器必须实现HandlerInterceptor接口

preHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求 request 进行处理。如果程序员决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回true;如果程序员决定不需要再调用其他的组件去处理请求,则返回false。

postHandle():这个方法在业务处理器处理完请求后,但是DispatcherServlet 向客户端返回响应前被调用,在该方法中对用户请求request进行处理。

afterCompletion():这个方法在 DispatcherServlet 完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。

 

public class HandlerInterceptor1 implements HandlerInterceptor {
    // controller执行后且视图返回后调用此方法
    // 这里可得到执行controller时的异常信息
    // 这里可记录操作日志
    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        System.out.println("HandlerInterceptor1....afterCompletion");
    }
​
    // controller执行后但未返回视图前调用此方法
    // 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
            throws Exception {
        System.out.println("HandlerInterceptor1....postHandle");
    }
​
    // Controller执行前调用此方法
    // 返回true表示继续执行,返回false中止执行
    // 这里可以加入登录校验、权限拦截等
    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
        System.out.println("HandlerInterceptor1....preHandle");
        // 设置为true,测试使用
        return true;
    }
}
配置文件:
​
需要在springMvc中的springmvc.xml中配置相应的拦截器规则:
<!-- 配置拦截器 -->
<mvc:interceptors>
    <mvc:interceptor>
        <!-- 所有的请求都进入拦截器 -->
        <mvc:mapping path="/**" />
        <!-- 配置具体的拦截器 -->
        <bean class="cn.itcast.ssm.interceptor.HandlerInterceptor1" />
    </mvc:interceptor>
    <mvc:interceptor>
        <!-- 所有的请求都进入拦截器 -->
        <mvc:mapping path="/**" />
        <!-- 配置具体的拦截器 -->
        <bean class="cn.itcast.ssm.interceptor.HandlerInterceptor2" />
    </mvc:interceptor>
</mvc:interceptors>    
        

springMVC的异常处理:

Spring MVC 通过 HandlerExceptionResolver 处理程序的异常,包括 Handler 映射、数据绑定以及目标方法执行时发生的异常。SpringMVC 提供的 HandlerExceptionResolver 的实现类

SpringMVC对比Struts2:

①. Spring MVC 的入口是 Servlet, 而 Struts2 是 Filter

②. Spring MVC 会稍微比 Struts2 快些. Spring MVC 是基于方法设计, 而 Sturts2 是基于类, 每次发一次请求都会实例一个 Action.

③. Spring MVC 使用更加简洁, 开发效率Spring MVC确实比 struts2 高: 支持 JSR303, 处理 ajax 的请求更方便

④. Struts2 的 OGNL 表达式使页面的开发效率相比Spring MVC 更高些.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kay三石

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值