SpringMVC_IDEA进阶

本文介绍Spring MVC中如何处理HTTP请求参数,包括基本类型、自定义类型的参数接收及数据校验方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方法的参数

JavaEE组件

HttpServletRequest
HttpServletResponse
HttpSession

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import sun.management.Agent;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.Map;

/**
 * @ClassName ParamController
 * @Description TODO
 * @Author Matthew
 * @Date 2019/3/27 10:57
 * @Version 1.0
 **/
@Controller
@RequestMapping("/param")
public class ParamController {

    @RequestMapping("/test1")
    //按照我们之前所学返回值为void我们应该跳转到test1.jsp页面
    //但我们接受HttpServletResponse那么spring就不会帮我们直接跳转到test1页面而是交给我们完成
    public void test1(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
        System.out.println("ParamController.test1," + request + " , " + response + " , " + session);

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

        session.setAttribute("username", username);

        ServletContext application = session.getServletContext();

        PrintWriter out = response.getWriter();
        out.print("<h1>" + username + "</h1>");
        out.flush();
        out.close();
    }
}

ParamController.test1,org.apache.catalina.connector.RequestFacade@1e02de28 , org.apache.catalina.connector.ResponseFacade@7c61acbd , org.apache.catalina.session.StandardSessionFacade@60ab2b0c
在这里插入图片描述

IO流

InputStream/OutputStream
Reader/Writer

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

    @RequestMapping("/test3")
    public void test3(Reader reader, Writer writer) {
//        Reader reader = req.getReader();
//        Writer writer = req.getWriter();
        System.out.println("ParamController.test3" + reader + " , " + writer);
    }
   

test2
ParamController.test2org.apache.catalina.connector.CoyoteInputStream@4b6eef19 , org.apache.catalina.connector.CoyoteOutputStream@3a6bfe52
test3
ParamController.test3org.apache.catalina.connector.CoyoteReader@48d05011 , org.apache.catalina.connector.CoyoteWriter@61ff6d57

向界面传递数据

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", "man");
        modelMap.put("address", "beijing");
        return "result";
    }
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: Matthew
  Date: 2019/3/27
  Time: 11:20
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    name:${requestScope.name} <br>
    age:${requestScope.age} <br>
    sex:${requestScope.sex} <br>
    address:${requestScope.address} <br>
</body>
</html>

在这里插入图片描述

String和基本类型

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

 @RequestMapping("/test5")
    public String test5(@RequestParam(name = "name") String username, int age, @RequestParam(required = false, defaultValue = "180") Double height) {
        System.out.println("ParamController.test5, username:" + username + " , age" + age + " , height" + height);
        return "result";
    }

ParamController.test5, username:alice , age12 , height180.0
在这里插入图片描述

@PathVariable 表示参数来源于URL

   @RequestMapping("/test6/{id}")
    public String test6(@PathVariable("id") int userid, String name) {
        System.out.println("ParamController.test6, userid = " + userid + ", name = " + name);
        return "result";
    }

ParamController.test6, userid = 2, name = alice
在这里插入图片描述
@RequestHeader 表示参数来源于请求头

  @RequestMapping("/test7")
    public String test7(@RequestHeader("User-Agent") String userAgent,@RequestHeader("Cookie") String cookie){
        System.out.println("ParamController.test7, userAgent = " + userAgent + ", Cookie = " + cookie);
        return "result";
    }

ParamController.test7, userAgent = Apache-HttpClient/4.5.6 (Java/1.8.0_152-release), Cookie = JSESSIONID=69E0EC8DC29DF51B2C35273C73579CFF

在这里插入图片描述

@CookieValue 表示参数来源于Cookie

  @RequestMapping("/setCookie")
    public String setCookie(HttpServletResponse response){
        Cookie cookie = new Cookie("username", "admin");
        cookie.setMaxAge(7*24*60*60);//7天
        response.addCookie(cookie);
        return "result";
    }

    @RequestMapping("/test8")
    public String test8(@CookieValue("username") String username,@CookieValue("JSESSIONID") String sessionId){
        System.out.println("ParamController.test5, username:" + username + ", sessionID = " + sessionId);
        return "result";
    }

限制性setCooike然后运行test8,username的值位admin
ParamController.test5, username:admin, sessionID = 94A072A8342F60219C68A85278F077FB

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

    @RequestMapping("/test9")
    public String test9( String requestBody) {
        System.out.println("RequestBody = " + requestBody);
        return "result";
    }

RequestBody = username=qwe&password=qwe
在这里插入图片描述

自定义类型

@ModelAttribute 将请求数据转换为对象
条件:对象的属性名必须与表单元素的名称相同
@ModelAttribute注解有两种用法:

  1. 在方法参数的前面添加该注解
    作用:将请求参数转换为对象
package vo;

import entity.Address;
import jdk.nashorn.internal.objects.annotations.Property;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
import org.hibernate.validator.constraints.Range;
import org.springframework.web.bind.annotation.ModelAttribute;

import javax.validation.constraints.Pattern;
import java.io.InputStream;

/**
 * @Description TODO
 * @Author Matthew
 * @Date 2019/3/28 20:27
 * @Version 1.0
 */

public class UserVo {
    private String username;
    private String password;
    private String phone;
    private String email;
    private Integer age;
    private Address address;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "UserVo{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", phone='" + phone + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }
}

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import vo.UserVo;

import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;

/**
 * @Description TODO
 * @Author Matthew
 * @Date 2019/3/28 20:24
 * @Version 1.0
 */
@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/regist")//ModelAttribute可加可不加
    public String regist(@Valid UserVo userVo, Errors errors){
        System.out.println(userVo);
        return "success";
    }

    @ModelAttribute("types")
    public List<String> getTypes(){
        System.out.println("UserCOntroller.getTypes");
        List<String> types = Arrays.asList("服装", "数码", "食品");
        return types;
    }

    @RequestMapping("/test")
    public String test(UserVo userVo){
        return "result";
    }

}

regist页面跳转regist

UserCOntroller.getTypes
UserVo{username=‘wqe’, password=‘12312’, phone=‘13111111111’, email=‘941076795@qq.com’, age=12, address=Address{city=‘辽宁’, province=‘沈阳’}}

在这里插入图片描述

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

    regist页面跳转test

UserController.getTypes
UserVo{username=‘wqe’, password=‘1233’, phone=‘13111111111’, email=‘941076795@qq.com’, age=12, address=Address{city=‘辽宁’, province=‘沈阳’}}

在这里插入图片描述

错误参数

Errors、BindingResult
用来接受错误信息,实现服务端的数据校验
实际开发中,既要做客户端表单校验,又要做服务端数据校验

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

UserController.getTypes
org.springframework.validation.BeanPropertyBindingResult: 1 errors
Error in object ‘userVo’: codes [年龄有误,年龄只能在0-120之间.userVo,年龄有误,年龄只能在0-120之间]; arguments []; default message [null]
在这里插入图片描述

服务端数据校验

简介

JSR303校验

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

Hibernate Validator

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

用法

添加jar包

<!-- hibernate-validator -->
      <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
      <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>${hibernate-validator.version}</version>
      </dependency>

      <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator-annotation-processor</artifactId>
        <version>${hibernate-validator.version}</version>
      </dependency>
    </dependencies>

为参数对象添加注解

 public String regist(@Valid UserVo userVo, Errors errors){

为属性添加校验注解

	@NotEmpty(message = "用户名不能为空")
    @Pattern(regexp = "\\w{2,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;
    @Property
    private Address address;

类型转换

简介

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

两种解决方式:
方式1:使用PropertyEditor
方式2:使用Converter(推荐)
2. 使用PropertyEditor
步骤:

  1. 定义属性编辑器
  2. 注册属性编辑器
    @InitBinder
注册属性编辑器
   @InitBinder
   public void initBinder(DataBinder binder) {
       binder.registerCustomEditor(Address.class,new AddressEditor());
    }

缺点:
代码嵌套在Controller层中只能从字符串转换

  1. 使用Converter
    步骤:
    1. 定义转换器,实现Converter接口
    2. 管理自定义转换器
   <!--管理自定义转换器-->
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="converter.String2AddressConverter"/>
                <bean class="converter.Address2StringConverter"/>
            </set>
        </property>
    </bean>
  1. 加载应用自定义管理器
    将实体类Uservo中的实体类参数Address和字符串之间进行转换
package converter;


import entity.Address;
import org.springframework.core.convert.converter.Converter;

/**
 * @Description TODO
 * @Author Matthew
 * @Date 2019/3/29 18:57
 * @Version 1.0
 */

public class Address2StringConverter implements Converter<Address,String> {
    @Override
    public String convert(Address address) {
        return "[" + address.getCity() + "-" + address.getProvince() + "]";
    }
}

package converter;

import entity.Address;
import org.springframework.core.convert.converter.Converter;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description TODO
 * @Author Matthew
 * @Date 2019/3/29 18:50
 * @Version 1.0
 */

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("地址转换失败");
        }
    }
}

@SessionAttributes

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

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.bind.annotation.SessionAttributes;
import vo.UserVo;

import javax.servlet.http.HttpSession;

/**
 * @Description TODO
 * @Author Matthew
 * @Date 2019/3/29 19:06
 * @Version 1.0
 */
@Controller
@RequestMapping("/session")
@SessionAttributes("userVo")
public class SessionController {

    @RequestMapping("/step1")
    public String step1(){
        return "step1";
    }

    @RequestMapping("/step2")
    public String step2(UserVo userVo){
        System.out.println("step2" + userVo);
        return "step2";
    }

    @RequestMapping("/step3")
    public String step3(UserVo userVo){
        System.out.println("step3" + userVo);
        return "step3";
    }

    @RequestMapping("/regist")
    public String regist(UserVo userVo, HttpSession session){
        System.out.println(session.getAttribute("userVo"));
        System.out.println("regist" + userVo);
        return "success";
    }
}

在这里插入图片描述
step2UserVo{username=‘admin’, password=‘qwe’, phone=‘null’, email=‘null’, age=null, address=null}
在这里插入图片描述
step3UserVo{username=‘admin’, password=‘qwe’, phone=‘13111111111’, email=‘941076795@qq.com’, age=null, address=null}
在这里插入图片描述
UserVo{username=‘admin’, password=‘qwe’, phone=‘13111111111’, email=‘941076795@qq.com’, age=23, address=Address{city=‘辽宁’, province=‘沈阳’}}
在这里插入图片描述
registUserVo{username=‘admin’, password=‘qwe’, phone=‘13111111111’, email=‘941076795@qq.com’, age=23, address=Address{city=‘辽宁’, province=‘沈阳’}}

统一异常处理

  1. 简介
    对异常进行统一处理
    两种方式:
    使用web技术提供的统一异常处理
    使用SpringMVC提供的统一异常处理
  2. 使用web技术的异常处理
 <!--404异常处理-->
  <error-page>
    <error-code>404</error-code>
    <location>/404.jsp</location>
  </error-page>

  <!--500异常-->
  <error-page>
    <error-code>500</error-code>
    <location>/500.jsp</location>
  </error-page>
<body>
    404 Page Not Found <br>
    页面让狗狗叼走了。。。。。。
</body>
<body>
    500 System Error<br>
    系统出现问题,程序员正在修改中,请稍后再试。
</body>
  1. 使用SpringMVC的异常处理
    步骤:
    定义一个异常处理类(通知),添加@ControllerAdvice
    定义异常处理方法,添加@ExceptionHandler
package controller;

import org.apache.ibatis.jdbc.Null;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
 * @Description TODO
 * @Author Matthew
 * @Date 2019/3/29 19:42
 * @Version 1.0
 */
@ControllerAdvice
public class ExceptionAdvice {

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值