Spring MVC数据处理

类型转换器






    
        
            
        
    
package com.demo.converters;

import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 定义类型转换器 需要明确 源类型 和 目标类型
 * 在convert方法自定义类型转换的实现
 * 在spring配置文件中配置自定义类型转换器
 */
public class MyStringToDateConverter implements Converter {

    @Override
    public Date convert(String source) {
        try {
            if (!StringUtils.isEmpty(source)) {
                if (source.split("-").length == 3) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    return sdf.parse(source);
                } else if(source.split("/").length == 3) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
                    return sdf.parse(source);
                } else {
                    throw new RuntimeException("日期转换错误:" + source);
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}

数据格式化

<%--spring标签库--%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
...

<%--spring:eval 用来显示格式化后的数据--%>
salary: 
package com.demo.controllers.entity;

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

import java.util.Date;

@Data
public class User {
    private Integer id;
    private String username;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday; // 2023-03-03
    @NumberFormat(style = NumberFormat.Style.CURRENCY)
    private Double balance; //  1000
    private String[] hobbies;
    @NumberFormat(pattern = "#,###.##")
    private Double salary; // 1,000.01
    @NumberFormat(style = NumberFormat.Style.PERCENT)
    private Double taskCount; // 96%
}

数据校验

Hibernate Validator实现了JSR349验证注解规范的技术,在javaBean属性上标注

package com.demo.controllers.entity;

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.Data;

@Data
public class User {
    @NotNull
    @Min(1)
    private Integer id;
}
package com.demo.controllers;

import com.demo.controllers.entity.User;
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 在需要验证的javaBean的属性上面加入对应的验证注解
 * 在需要验证的处理方法的对应javaBean参数上加上@Valid
 * 在需要验证的处理方法参数中加入BindingResult,代表自己处理错误,这样就不会显示错误页面了
 * 将错误信息循环通过map存入到request域中
 * 在jsp通过${errors.id}获取对应的错误信息
 */
@Controller
public class UserController {

    @PostMapping("/user")
    public String add(@Valid User user, BindingResult result, Model model) {

        // 将错误信息取出来,输出到jsp页面
        // 判断当前是否出现了错误
        if(result.hasErrors()) {
            // 存放错误信息,有利于在jsp中分别取出错误信息
            Map errors = new HashMap<>(); // key: 错误信息的属性名,value: 错误信息

            // 获取所有的错误信息 包含 错误的属性,错误信息
            List fieldErrors = result.getFieldErrors();

            for (FieldError fieldError : fieldErrors) {
                errors.put(fieldError.getField(), fieldError.getDefaultMessage());
            }

            model.addAttribute("errors", errors);

            //如果验证失败将请求转发到添加页面
            return "user/add";
        }
        System.out.println(user);
        return "show";
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>


    添加用户


    

添加用户

<%-- Spring的form标签库method是支持put和delete--%>
/**
 * 多文件文件上传
 */
@PostMapping("/upload")
public String upload(String desc, MultipartFile[] multipartFiles) throws IOException {

    for (MultipartFile myfile : multipartFiles) {
        String path = "D:/" + myfile.getOriginalFilename();
        File file = new File(path);

        myfile.transferTo(file);
    }

    return "success";
}
/**
 * 多线程文件上传
 */
@PostMapping("/upload")
public String upload(String desc, MultipartFile[] multipartFiles) throws InterruptedException {

    for (MultipartFile myfile : multipartFiles) {
        Thread thread = new Thread(() -> {
            String path = "D:/" + myfile.getOriginalFilename();
            File file = new File(path);
            try {
                myfile.transferTo(file);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        thread.start();
        thread.join(); // 让子线程执行完在执行主线程
    }

    return "success";
} 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    <%--磁盘路径--%>
    

/**
 * 文件上传到三个路径
 *     1. 项目路径(适合项目小,上传使用率低
 *     2. 磁盘路径,这种方式通过虚拟目录的映射
 *     3. 静态资源服务器(CDN)
 */
@PostMapping("/upload")
public String upload(String desc, MultipartFile myfile, Model model) throws IOException {


    String path = "D:/" + myfile.getOriginalFilename();
    File file = new File(path);

    myfile.transferTo(file);

    model.addAttribute("filename", myfile.getOriginalFilename());

    return "success";
}

Spring MVC拦截器

拦截器:采用AOP的设计思想,类似Servlet过滤器,用来拦截处理方法

如:权限验证、日志、异常记录、记录方法执行时间


    
package com.demo.interceptors;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;

public class MyInterceptor implements HandlerInterceptor {

    /**
     * 在处理方法之前执行
     * @param request   在方法请求进来之前更改request中的的属性值
     * @param response
     * @param handler   封装了当前处理方法的信息
     * @return true: 后续调用链是否执行  false:中断后续执行
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handler1 = (HandlerMethod) handler;
        }

        System.out.println("-------类:["+ handler1.getBean().getClass() +"] 方法:["+ handler1.getMethod().getName() +"] 参数:["+ Arrays.toString(handler1.getMethod().getParameters()) +"] 前执行---------preHandle--------------------------------");
        return true;
    }

    /**
     * 在请求执行后执行,在视图渲染之前执行
     * 当处理方法出现了异常则不会执行方法
     * @param request
     * @param response 在方法执行后更改response中的信息
     * @param handler  封装了当前处理方法的信息
     * @param modelAndView  封装了model和view,请求结束后可以修改model中的数据或新增model数据,也可修改view的跳转
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("------方法后执行,在视图渲染之前----------postHandle--------------------------------");
    }

    /**
     * 在视图渲染之后执行,出现异常也会执行该方法
     * @param request
     * @param response
     * @param handler
     * @param ex 可以记录异常日志的功能,或者清除资源
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("-----------在视图渲染之后--------afterHandle----------");
    }
}






    
    

    
    
        
        
        
        
        
        
    
package com.demo.interceptors;

import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * 验证用户是否登录的拦截器
 */
public class CheckLoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        HttpSession session = request.getSession();

        // 如果没有登录
        if (StringUtils.isEmpty(session.getAttribute("username"))) {
            response.sendRedirect(request.getContextPath() + "/login");
            return false;
        } else {
            return true;
        }

    }
}

Spring MVC 国际化



    
        
            i18n/login
            i18n/index
        
    
package com.demo.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 基于浏览器设置的语言切换国际化
 *      1. 新建jsp对应的国际化属性资源文
 *          login_en_US.properties
 *          login_zh_CN.properties
 *      2. 配置sping_mvc.xml 将国际化支持和资源文件都注入到springmvc中
 *      3. 在jsp页面调用对应的属性资源内容:

》》》方式一


package com.demo.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

/**
 * 基于浏览器设置的语言切换国际化
 *      1. 新建jsp对应的国际化属性资源文
 *          login_en_US.properties
 *          login_zh_CN.properties
 *      2. 配置sping_mvc.xml 将国际化支持和资源文件都注入到springmvc中
 *      3. 在jsp页面调用对应的属性资源内容:

》》》方式二






    
    
  • Spring MVC基于注解的国际化

Spring MVC 异常处理

  • @ExceptionHandler

通过@ExceptionHandler可以在方法中记录日志

  • @ControllerAdvice是对Controller的增强

全局异常处理

全局数据绑定

全局数据预处理

》》》优先级:处理器异常 > 全局异常中具体异常 > 全局异常

页面更新:2024-05-11

标签:数据处理   视图   转换器   属性   异常   错误   参数   类型   方法   数据   资源

1 2 3 4 5

上滑加载更多 ↓
Top