SpringMVC的高级特性(03)

Posted Lqc_javaEngineer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC的高级特性(03)相关的知识,希望对你有一定的参考价值。

一、数据转换:

        例如从前台jsp页面传递过来的日期是字符串形式,如何将字符串转换为Date类型。

        方式一:Spring支持的转换器:Convert<S,T>接口,具体实现方式已经在上一篇博客中体现。这种方式可以实现任意类型的数据转换。

        方式二:Fomatter<T>接口,只能实现String与任意对象之间的转换。

       方式三:注解格式化工厂,使用AnnotationFormatterFactory<A extends Annotion>格式化数据。其中包括两个重要注解:@DateTimeFormat:日期时间格式。@NumberFormat:数字类型包括:货币,正常数字,百分数类型。注解作用于pojo的属性。将页面传递的String转换成对应的格式化数据。注:开发中强烈建议使用这种方式

package com.gxzj.mobile.vo.json.productinfo;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;

import java.io.Serializable;
import java.util.Date;


/**
 * @author Liqingchao
 * @version $Rev$
 * @time 2018/4/11 0011 11:12
 * @desc 使用注解格式化工厂的方式将页面传递的String转换成对应的格式化数据。
 * @updateAuthor $Author$
 * @updateData $Date$
 * @updateDesc $TODO
 */
public class User implements Serializable 

    //日期类型
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;
    //正常数字类型
    @NumberFormat(style = NumberFormat.Style.NUMBER,pattern = "#,###")
    private int total;
    //百分数类型
    @NumberFormat(style = NumberFormat.Style.PERCENT)
    private double discount;
    //货币类型
    @NumberFormat(style = NumberFormat.Style.CURRENCY)
    private double money;

二、数据校验:

        输入校验分为客户端校验和服务端校验,客户端校验主要是过滤正常用户误操作,通常通过JS完成。服务端校验是整个应用阻止非法数据的最后防线,主要通过在应用中编程实现。对于用户的恶意行为客户端校验将无能为力,必须通过服务端校验,客户端校验能把用户误操作的非法输入阻止在客户端,减少服务器的负载压力。因此必须客户端和服务端同时进行校验。

        SpringMVC提供了两种校验方式:1.Spring自带的Validation校验框架。2、JSR303校验。

      (1)、Spring自带的Validation校验框架由于硬编码,所以实际开发中显得比较麻烦,因此现在开发更加推荐使用JSR303

      (2)、JSR303校验:更加推荐这种方式。

package com.gxzj.mobile.service.impl.biz.shopping;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.util.Date;

import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;

/**
 * @author Liqingchao
 * @version $Rev$
 * @time 2018/4/11 0011 14:22
 * @desc 使用JSR303校验数据合法性
 * @updateAuthor $Author$
 * @updateData $Date$
 * @updateDesc $TODO
 */
public class User implements Serializable 

    @NotBlank(message = "登录名不能为空")
    private String loginname;

    @NotBlank(message = "密码不能为空")
    @Length(min = 6,max = 8,message = "密码长度必须在68位之间")
    private String password;

    @NotBlank(message = "用户名不能为空")
    private String username;

    @Range(min = 15,max = 60,message = "年龄必须在1560岁之间")
    private int age;

    @Email(message = "必须是合法的邮箱地址")
    private String email;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @Past(message = "生日必须是过去的一个日期")
    private Date birthday;

    @Pattern(regexp = "[1][3,8][3,6,9][0-9]8",message = "无效的电话号码")
    private String phone;

三、文件上传与下载

        1、文件上传:图片上传:MultipartFile file 类。可以在Springmvc核心配置文件中对上传图片的大小做限制。

        2、文件下载:通知浏览器以attachment(下载方式)打开图片。

四、拦截器(进行用户权限认证)

public class Interceptor1 implements HandlerInterceptor
    //执行时机:controller已经执行,modelAndview已经返回
    //使用场景: 记录操作日志,记录登录用户的ip,时间等.
    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception
        System.out.println("======Interceptor1=======afterCompletion========");
    
    //执行时机:Controller方法已经执行,ModelAndView没有返回
    //使用场景: 可以在此方法中设置全局的数据处理业务
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
            throws Exception
        System.out.println("======Interceptor1=======postHandle========");

    
    //返回布尔值:如果返回true放行,返回false则被拦截住
    //执行时机:controller方法没有被执行,ModelAndView没有被返回
    //使用场景: 权限验证
    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception
        System.out.println("======Interceptor1=======preHandle========");
        return true;
    

登录的权限认证:

public class LoginInterceptor implements HandlerInterceptor
    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception
        // TODO Auto-generated method stub

    
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
            throws Exception
        // TODO Auto-generated method stub

    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception
        //判断当前访问路径是否为登录的路径,如果是则放行
        if(request.getRequestURI().indexOf("/login") > 0)
            return true;
        
        //判断session中是否有登录信息,如果没有则跳转到登录页面,如果有则放行
        HttpSession session = request.getSession();
        if(session.getAttribute("username") != null)
            return true;
         
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
        return false;
    

在Springmvc核心配置文件中配置拦截器:

<!-- 配置拦截器 -->
    <mvc:interceptors>
        <!-- 多个拦截器的执行顺序等于springMvc.xml中的配置顺序 -->
<!--         <mvc:interceptor> -->
            <!-- 拦截请求的路径    要拦截所有必需配置成/** -->
<!--             <mvc:mapping path="/**"/> -->
            <!-- 指定拦截器的位置 -->
<!--             <bean class="cn.itheima.interceptor.Interceptor1"></bean> -->
<!--         </mvc:interceptor> -->
        
<!--         <mvc:interceptor> -->
            <!-- 拦截请求的路径    要拦截所有必需配置成/** -->
<!--             <mvc:mapping path="/**"/> -->
            <!-- 指定拦截器的位置 -->
<!--             <bean class="cn.itheima.interceptor.Interceptor2"></bean> -->
<!--         </mvc:interceptor> -->
        
        <mvc:interceptor>
            <!-- 拦截请求的路径    要拦截所有必需配置成/** -->
            <mvc:mapping path="/**"/>
            <!-- 指定拦截器的位置 -->
            <bean class="cn.itheima.interceptor.LoginInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

五、全局异常处理器

//自定义全局异常处理
public class CustomGlobalExceptionResolver implements HandlerExceptionResolver

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
            Object arg2, Exception exc)
        //保存异常信息
        String msg = "";
        
        //判断异常类型
        if(exc instanceof CustomException)
            //处理业务级别异常
            msg = ((CustomException)exc).getMessage();
         else
            //处理运行时异常
            msg = "系统异常, 亲,对不起, 请及时联系管理员哦!";
        
        
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg", msg);
        modelAndView.setViewName("error");
        return modelAndView;
    


在Springmvc核心配置文件中配置全局异常处理器

<!-- 配置全局异常处理器 -->

 <bean class="cn.itheima.exception.CustomGlobalExceptionResolver"></bean>

六、解决POST请求乱码问题:

        在web.xml文件中配置如下:

<!-- 配置Post请求乱码 -->
  <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


以上是关于SpringMVC的高级特性(03)的主要内容,如果未能解决你的问题,请参考以下文章

Springmvc拦截器三个方法的执行时机

(VIP-朝夕教育)2021-05-24 .NET高级班 03-特性

03. Redis 高级特性

03. Redis 高级特性

虚拟机类加载机制——类加载时机

Python入门-03 高级特性