SpringMVC 进阶

SpringMVC 进阶

一、方法的参数

1、JavaEE组件

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
@Controller
@RequestMapping("/param")
public class ParamController {

    @RequestMapping("/test1")
    public void test1(HttpServletRequest req, HttpServletResponse resp, HttpSession session) throws IOException {
        System.out.println("ParamController.test1"+ req + "," + resp + "," +session);

        String username = req.getParameter("username");

        session.setAttribute("username",username);

        //输出流
        PrintWriter out = resp.getWriter();
        out.print("

" + username + "

"
); out.flush(); out.close(); }

2.IO流

  • InputStream/OutputStream
  • Reader/Writer
//字节流
@RequestMapping("/test2")
public void test2(InputStream is, OutputStream os){
    //相当于如下代码
    //        ServletInputStream inputStream = req.getInputStream();
    //        ServletOutputStream outputStream = resp.getOutputStream();
    System.out.println("ParamController.test2"+is + ","+os);
}

//字符流
@RequestMapping("/test3")
public void test3(Reader reader , Writer writer){
    //相当于如下代码
    //        Reader reader = req.getReader();
    //        Writer writer = resp.getWriter();
    System.out.println("ParamController.test3"+reader+","+writer );
}

3.向界面传递数据

Model、Map、ModelMap

将数据存储到Request作用域中

@RequestMapping("/test4")
public String  test4(Model model, Map map, ModelMap modelMap){
    model.addAttribute("name","tom");
    map.put("age",20);
    modelMap.addAttribute("sex","male");
    modelMap.put("address","zhongguo");
    return "result";
}

result.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Titletitle>
head>
<body>
    name:${requestScope.name}<br>
    age:${age}<br>
    sex:${sex}<br>
    address:${address}<br>
body>
html>

4.String和基本类型

​ @RequestParam 表示参数来源,默认所有参数都添加该注解,参数值来源于同名的请求参数

​ @PathVariable 表示参数来源于URL

​ @RequestHeader 表示参数来源于请求头

​ @CookieValue 表示参数来源于Cookie

​ @RequestBody 表示参数来源于请求体(只有post请求才会有请求体)不常用

5.自定义类型

​ @ModelAttribute 将请求参数转换成对象

​ 条件:对象的属性名必须与表单元素的名称相同

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/regist")
    public String regist(@ModelAttribute UserVo userVo){//@ModelAttribute默认添加可以省略
        System.out.println("UserController.regist,userVo:"+userVo);
        return "view/success";
    }

​ @ModelAttribute注解有两种用法:

  • 在方法参数的前面添加该注解(默认添加,可以不写)

    作用:将请求参数转换成对象

  • 在方法的上面添加该注解

    作用:在调用所有目标方法前都会调用添加@ModelAttribute注解的方法,并向模型中添加数据

UserController

@ModelAttribute("types")//模型属性
public List<String > getTypes(){//在调用所有目标方法前都会调用添加@ModelAttribute注解的方法,并向模型中添加数据
    System.out.println("UserController.getTypes");
    List<String> list = Arrays.asList("清蒸", "爆炒", "油焖");
    return list;
}
@RequestMapping("/test")
public String test(){
    System.out.println("UserController.test");
    return "result";
}

result.jsp

制作方式:

效果:

SpringMVC 进阶_第1张图片

6.错误参数

​ Errors、BindingResult

​ 用来接收错误信息,实现服务端的数据校验

@RequestMapping("/regist")
public String regist(@ModelAttribute UserVo userVo, Errors errors){//@ModelAttribute默认添加可以省略
    //手动进行服务端数据校验
    if (userVo.getAge()<0 ||userVo.getAge()>120){
        errors.reject("年龄只能在0-120之间");//手动添加错误消息
    }
    //判断受否有错误
    if (errors.hasErrors()){
        System.out.println(errors);//服务端校验的错误信息一般在后台处理
        return "view/regist";
    }

    System.out.println("UserController.regist,userVo:"+userVo);
    return "view/success";
}

​ 实际开发中、既要做客户端表单校验(js)、又要做服务端表单校验

​ 客户端表单校验可以被跳过

二、服务器校验框架

1.简介

1.1JSR303

​ JSR303是一个数据验证的标准规范,用于对Java Bean中的属性进行校验,称为Bean Validation

​ 提供了常用的校验注释

1.2 Hibernate Validator

​ 是JSR303的一个参考实现,并提供了扩展注释

2.用法

2.1 添加jar包

<dependency>
    <groupId>org.hibernategroupId>
    <artifactId>hibernate-validatorartifactId>
    <version>5.4.1.Finalversion>
dependency>

<dependency>
    <groupId>org.hibernategroupId>
    <artifactId>hibernate-validator-annotation-processorartifactId>
    <version>5.4.1.Finalversion>
dependency>
2.2 为参数对象添加注释

在需要校验的参数对象前面加@Valid注解

public String regist(@Valid UserVo userVo, Errors errors){
}
2.3为属性添加校验注释
public class UserVo {

    @NotEmpty(message = "用户名不能为空")
    @Pattern(regexp = "\\w{6,10}",message = "用户名只能包含数字、字母、下划线,且长度为6-10位")
    private String username;

    @Length(min = 4,max = 10,message = "密码必须为4-10位")
    private String password;

    @Pattern(regexp = "(139|133|131)\\d{8}",message = "手机号码格式不正确")
    private String phone;

    @Email(message = "邮箱格式不正确")
    private String email;

    @Range(min = 1,max = 120,message = "年龄必须在1-120之间")
    private Integer age;
}

三、类型转换

1.简介

​ 数据绑定流程:获取值——>查找转换器——>转换——> 后台校验——>数据绑定

​ 两种解决方式

  • 方式1:使用PropertyEditor
  • 方式2:使用Converter(推荐)

<filter>
    <filter-name>encodingFilterfilter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
    <init-param>
        <param-name>encodingparam-name>
        <param-value>utf-8param-value>
    init-param>
filter>
<filter-mapping>
    <filter-name>encodingFilterfilter-name>
    <url-pattern>/*url-pattern>
filter-mapping>

2.使用PropertyEditor(不推荐)

​ 步骤:

​ 1.定义属性编辑器

​ 2.注册属性编辑器

​ @InitBinder

​ 缺点:

  • 代码嵌套再Controller层中
  • 只能从字符串转换

3.使用Converter(推荐使用)

​ 步骤:

​ 1.定义转换器,实现Converter接口

在这里插入图片描述

/**
 * 把字符串变成地址
 * 取出例如:广东-广州  中的城市和省份
 * 类似于于字符串分割技术
 */
public class String2AddressConverter implements Converter<String, Address> {
    @Override
    public Address convert(String source) {
        Pattern pattern = Pattern.compile("\\[(.*)-(.*)\\]");
        Matcher matcher = pattern.matcher(source);
        if (matcher.matches()){
            String city = matcher.group(1);
            String province = matcher.group(2);
            Address address = new Address();
            address.setCity(city);
            address.setProvince(province);
            return address;
        }else {
            throw new RuntimeException("地址转换失败");
        }
    }
}
/**
 * 把Address对象变成字符串
 */
public class Address2StringConverter implements Converter<Address,String > {
    @Override
    public String convert(Address address) {
        return "["+address.getCity()+"-"+address.getProvince()+"]";
    }
}

2.管理自定义转换器

<!--    管理自定义转换器        -->
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
        <set>
        <bean class="converter.String2AddressConverter"/>
            <bean class="converter.Address2StringConverter"/>
                </set>
                </property>
                </bean>

3,加载应用自定义转换器


<mvc:annotation-driven conversion-service="conversionService"/>

四、@SessionAttributes

​ 作用:将模型中指定名称的数据存储到session中

五、统一异常处理

1、简介

​ 对异常进行统一处理

​ 两种方式。

  • 使用web技术提供的统一异常处理
  • 使用SpringMVC提供的统一异常处理

2.使用web技术的异常处理


<error-page>
    <error-code>404error-code>
    <location>/404.jsplocation>
error-page>


<error-page>
    <error-code>500error-code>
    <location>/500.jsplocation>
error-page>

3.使用SpringMVC处理异常

步骤:

​ 1.定义一个异常处理类(通知),添加@ControllerAdvice

​ 2.定义异常处理方法,添加@ExceptionHandler

@ControllerAdvice//异常处理通知
public class ExceptionAdvice {
    
    @ExceptionHandler(ArithmeticException.class)
    public String arithmetic(Exception e){//算数异常
        System.out.println("警报,程序出现异常:"+e+","+e.getMessage());
        return "error/arithmetic";
    }

    @ExceptionHandler(NullPointerException.class)
    public String nullpoint(Exception e){
        System.out.println("警报,程序出现异常:"+e+","+e.getMessage());
        return "error/nullpoint";
    }

    @ExceptionHandler(Exception.class)
    public String exception(Exception e){
        System.out.println("警报,程序出现异常:"+e+","+e.getMessage());
        return "error/exception";
    }
}

CSDN程序员学院SpringMVC入门课程学习

你可能感兴趣的:(SpringMVC,springmvc,java)