Spring5框架之SpringMVC

目录

1.SpringMVC的入门案例

1.1 通过maven构建一个web项目

1.2 添加对应的依赖及Tomcat插件

1.3 创建SpringMVC的配置文件

1.4 在web.xml中注册DispatchServlet

1.5 创建自定义的Controller

1.6 在Springmvc配置文件中注册

原理分析:

2.SpringMVC基于注解的使用方式

2.1 SpringMVC配置文件修改

2.2 自定义控制器

2.3 测试

3.SpringMVC工作原理图解

4.SpringMVC中响应请求

4.1 响应返回字符串

4.2 不响应

4.3 直接返回一个ModelAndView对象

4.4 重定向跳转

4.5 视图解析器添加前后缀

4.6 通过HttpServletResponse响应

5.SpringMVC接收请求数据

5.1 基本数据类型

5.2 对象接收

5.3 通过数组接收

5.4 自定义转换器

6.响应数据

6.1 ModelAndView传递

6.2 通过Map对象传值

6.2 通过Model来接收

6.3 通过ModelMap响应数据

6.4 SpringMVC中的乱码问题

7.SpringMVC文件上传操作

7.1 依赖的引入

7.2 表单页面

7.3 控制处理

7.4 配置文件处理

8.SpringMVC中的文件下载

9.静态资源处理

10 SpringMVC服务端验证

分组验证

11.SpringMVC中的JSON数据处理

12.Restful风格

SpringMVC拦截器


1.SpringMVC的入门案例

1.1 通过maven构建一个web项目

1.2 添加对应的依赖及Tomcat插件

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.1.17.RELEASE</version>
    </dependency>
  </dependencies>
​
  <build>
    <finalName>gp_springmvc_01_hello</finalName>
    <plugins>
      <!-- tomcat插件 -->
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <!-- 端口号 -->
          <port>8082</port>
          <!-- /表示访问路径 省略项目名 -->
          <path>/</path>
          <!-- 设置编码方式 -->
          <uriEncoding>utf-8</uriEncoding>
        </configuration>
      </plugin>
    </plugins>

1.3 创建SpringMVC的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
​
    <!-- 处理器映射器 -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
​
    <!-- 处理器适配器 -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
​
</beans>

1.4 在web.xml中注册DispatchServlet

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
​
<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <!--  注册前端控制器-->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <!-- 关联配置文件 -->
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

1.5 创建自定义的Controller

package com.gupaoedu;
​
​
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
​
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
​

public class UserController implements Controller {
​
    /**
     * 处理请求的方法
     * @param httpServletRequest
     * @param httpServletResponse
     * @return
     * @throws Exception
     */
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest
            , HttpServletResponse httpServletResponse) throws Exception {
        System.out.println("controller 执行了....");
        ModelAndView view = new ModelAndView();
        view.setViewName("/index.jsp");
        return view;
    }
}

1.6 在Springmvc配置文件中注册

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
​
    <!-- 处理器映射器 -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
​
    <!-- 处理器适配器 -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
​
    <!-- 注册自定义的Controller name必须加 / 前缀-->
    <bean class="com.gupaoedu.UserController" name="/user"/>
</beans>

原理分析:

DispatchServlet

init:IoC容器的初始化操作

初始化SpringMVC的九大组件

protected void initStrategies(ApplicationContext context) {
    this.initMultipartResolver(context);
    this.initLocaleResolver(context);
    this.initThemeResolver(context);
    // 加载我们在配置文件中添加的处理器映射器
    this.initHandlerMappings(context);
    // 加载我们在配置文件中添加的处理器适配器
    this.initHandlerAdapters(context);
    this.initHandlerExceptionResolvers(context);
    this.initRequestToViewNameTranslator(context);
    this.initViewResolvers(context);
    this.initFlashMapManager(context);
}

2.SpringMVC基于注解的使用方式

2.1 SpringMVC配置文件修改

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
">
​
    <!-- 开启扫描 -->
    <context:component-scan base-package="com.gupaoedu.controller" />
    <!-- 开启SpringMVC注解的使用 -->
    <mvc:annotation-driven />
​
</beans>

2.2 自定义控制器

package com.gupaoedu.controller;
​
​
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
​
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
​

@Controller // 将UserController对象交给IoC容器管理
@RequestMapping("/user") // 类头部的可以省略
public class UserController  {
​
​
    /**
     * 具体处理请求的方法  【头部的mapping+方法的mapping】
     * http://localhost:8082/user/query
     * @return
     */
    @RequestMapping("/query")
    public String query(){
        System.out.println("query ..... ");
        return "/index.jsp";
    }
​
    @RequestMapping("/save")
    public String add(){
        System.out.println("save ..... ");
        return "/index.jsp";
    }
​
    @RequestMapping("/delete")
    public String delete(){
        System.out.println("delete ..... ");
        return "/index.jsp";
    }
​
    @RequestMapping("/update")
    public String update(){
        System.out.println("update ..... ");
        return "/index.jsp";
    }
}
​

2.3 测试

3.SpringMVC工作原理图解

4.SpringMVC中响应请求

4.1 响应返回字符串

我们可以在处理方法的最后返回一个要跳转的页面地址”/“不要漏了

@RequestMapping("/query")
public String query(){
    System.out.println("query ..... ");
    return "/index.jsp";
}

4.2 不响应

如果用户提交了请求后服务端不需要给客户端一个响应,那么我们可以指定返回类型为void同时在方法头部添加@ResponseBody注解即可

@RequestMapping("/save")
@ResponseBody
public void add(){
    System.out.println("save ..... ");
}

4.3 直接返回一个ModelAndView对象

我们也可以直接返回一个ModelAndView对象

@RequestMapping("/delete")
public ModelAndView delete(){
    System.out.println("delete ..... ");
    ModelAndView mm = new ModelAndView();
    mm.setViewName("/index.jsp");
    return mm;
}

4.4 重定向跳转

有些情况下重定向跳转也是我们开发中必须使用的形式

@RequestMapping("/update")
public String update(){
    System.out.println("update ..... ");
    return "redirect:/user/query";
}

4.5 视图解析器添加前后缀

<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
    <property name="suffix" value=".jsp"/>
    <property name="prefix" value="/" />
</bean>

那这样的话响应的页面就会自动添加对应的前后缀信息

@RequestMapping("/query")
public String query(){
    System.out.println("query ..... ");
    return "index";
}

4.6 通过HttpServletResponse响应

仅仅只需要在方法的形参中声明这两个变量即可~

@RequestMapping("/fun1")
public void fun1(HttpServletRequest request
                 ,HttpServletResponse response) throws Exception {
    // response.sendRedirect("/index.jsp");
    System.out.println("fun1 ...");
    request.getRequestDispatcher("/index.jsp").forward(request,response);
}

5.SpringMVC接收请求数据

5.1 基本数据类型

直接在形参中声明要接收的数据,默认情况下形参必须和传过来的数据参数名一致

@RequestMapping("/query")
public String query(@RequestParam(value = "ids",required = true,defaultValue = "123") Integer id, String name){
    System.out.println("query ..... " + id + ":" + name);
    return "/index.jsp";
}

5.2 对象接收

如果传递过来的数据比较多,那么我们可以通过一个自定义的对象来接收

@RequestMapping("/save")
public String add(User user){
    System.out.println("save ..... " + user);
    return "/index.jsp";
}

5.3 通过数组接收

如果有多个名称相同的数据提交,我们可以使用数组的方式来接收

@RequestMapping("/delete")
public String delete(String[] loves){
    System.out.println("delete ..... ");
    if(loves !=null){
        for(String l : loves){
            System.out.println(l);
        }
    }
    return "/index.jsp";
}

注意:在形参中我们不能够通过集合的方式来获取传递的参数

在自定义对象中可以使用集合获取数组的形式来接收请求的参数

5.4 自定义转换器

有时候客户端传递过来特殊类型的数据,SpringMVC中提供的默认的转换器不能支持该转换,此时我们就需要自定义转换器

package com.gupaoedu.convert;
​
import org.springframework.core.convert.converter.Converter;
​
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
​

public class DateConvert implements Converter<String,Date> {
    @Override
    public Date convert(String s) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return sdf.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}
​

配置文件中注册

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
">
​
    <!-- 开启扫描 -->
    <context:component-scan base-package="com.gupaoedu.controller" />
    <!-- 开启SpringMVC注解的使用 -->
    <mvc:annotation-driven conversion-service="formattingConversionServiceFactoryBean"/>
​
    <!-- 配置转换器 -->
    <bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean"
    id="formattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.gupaoedu.convert.DateConvert"/>
            </set>
        </property>
    </bean>
</beans>

6.响应数据

6.1 ModelAndView传递

@RequestMapping("/query")
public ModelAndView query(){
    System.out.println("query ..... ");
    ModelAndView mm = new ModelAndView();
    mm.setViewName("/user.jsp");
    mm.addObject("msg","msg.....");
    return mm;
}

然后在jsp页面中通过EL表达式获取传递的信息

<%--
  Created by IntelliJ IDEA.
  User: admin
  Date: 2020/8/26
  Time: 16:29
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
  hello<br>
  ${msg}
</body>
</html>

6.2 通过Map对象传值

ModelAndView使用起来稍微有点复杂,我们可以通过Map来简化操作

@RequestMapping("/save")
public String add(Map<String,Object> map){
    System.out.println("save ..... ");
    map.put("msg","map ...msg");
    return "/index.jsp";
}

6.2 通过Model来接收

@RequestMapping("/delete")
public String delete(Model model){
    System.out.println("delete ..... ");
    model.addAttribute("msg","model ...msg");
    return "/index.jsp";
}

6.3 通过ModelMap响应数据

@RequestMapping("/update")
public String update(ModelMap mm){
    System.out.println("update ..... ");
    mm.put("msg","ModelMap ... msg");
    return "/index.jsp";
}

前面介绍的多种方式的数据都是会被保存在request作用域中,如果我们同时需要将数据保存在Session对象中,我们只需要在类的头部添加一个@SessionAttributes注解即可

6.4 SpringMVC中的乱码问题

  <filter>
    <filter-name>encodeFiletr</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>
    <init-param>
      <param-name>forceRequestEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>forceResponseEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodeFiletr</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

7.SpringMVC文件上传操作

7.1 依赖的引入

 <!-- fileUpload 解析上传的文件用到的jar -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

7.2 表单页面

提交的方式必须是post 方式,提交的数据的类型必须是二进制文件

<html>
<body>
<h2>Hello World!</h2>
    <form action="/user/save" method="post" enctype="multipart/form-data">
        姓名:<input type="text" name="username"><br>
        头像:<input type="file" name="headImg"><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>
​

7.3 控制处理

提交的文件我们可以通过 MultipartFile 类型来接收

@RequestMapping("/save")
public String add(MultipartFile headImg,String username) throws IOException {
    System.out.println(username);
    System.out.println("文件名称:" + headImg.getOriginalFilename());
    headImg.transferTo(new File("d:/" + headImg.getOriginalFilename()));
    return "/index.jsp";
}

7.4 配置文件处理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
">
​
    <!-- 开启扫描 -->
    <context:component-scan base-package="com.gupaoedu.controller" />
    <!-- 开启SpringMVC注解的使用 -->
    <mvc:annotation-driven />
​
    <!--  文件上传的解析器-->
    <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
        <property name="maxUploadSize">
            <value>5242880</value>
        </property>
    </bean>
​
</beans>

8.SpringMVC中的文件下载

    @RequestMapping("/download")
    public void download(HttpServletRequest request,
                         HttpServletResponse response){
        File file = new File("d://1.png");
        // 设置响应的头和客户端保存文件名
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition","attchement;filename=" + file.getName());
​
        try {
            // 打开本地文件流
            InputStream in = new FileInputStream(file);
            // 激活下载的流
            ServletOutputStream out = response.getOutputStream();
            byte[] b = new byte[1024];
            int num = 0;
            while ((num = in.read(b)) != -1){
                out.write(b,0,num);
            }
            out.close();
            in.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
​

9.静态资源处理

默认的情况下在SpringMVC中只能访问jsp页面,其他的都会被DispatchServlet拦截,原因是DispatchServlet配置的时候用的/ 覆盖掉了defaultservlet所做的工作,所以我们只需要重新制定即可

  <filter-mapping>
    <filter-name>encodeFiletr</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.png</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>

第二种方式就是在SpringMVC中指定映射的规则

<mvc:resources mapping="/img/**" location="/img/"  />

10 SpringMVC服务端验证

最早的校验,就是服务端校验。早期的网站,用户输入一个邮箱地址,校验邮箱地址需要将地址发送到服务端,服务端进行校验,校验成功后,给前端一个响应。有了JavaScript,校验工作可以放在前端去执行。那么为什么还需要服务端校验呢? 因为前端传来的数据不可信。前端很容易获取都后端的数据接口,如果有人绕过页面,就会出现非法数据,所以服务端也要数据校验,总的来说: 1.前端校验要做,目的是为了提高用户体验 2.后端校验也要做,目的是为了数据安全

SpringMVC本身是没有提供校验框架的,我们需要使用Hibernate提供的校验框架

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.3.0.Alpha1</version>
</dependency>

在配置文件中注册对应的校验框架

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
">
​
    <!-- 开启扫描 -->
    <context:component-scan base-package="com.gupaoedu.controller" />
    <!-- 开启SpringMVC注解的使用 -->
    <mvc:annotation-driven validator="localValidatorFactoryBean" />
    <mvc:resources mapping="/img/**" location="/img/"  />
    <!--  文件上传的解析器-->
    <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
        <property name="maxUploadSize">
            <value>5242880</value>
        </property>
    </bean>
​
    <!-- 配置验证框架 -->
    <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" id="localValidatorFactoryBean">
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
        <property name="validationMessageSource" ref="messageSource" />
    </bean>
​
    <bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="messageSource">
        <property name="basename" value="classpath:volidata.properties"/>
        <property name="fileEncodings" value="utf-8"/>
        <property name="cacheSeconds" value="120"/>
    </bean>
​
</beans>

验证规则

注解说明
@Null被注解的元素必须为 null
@NotNull被注解的元素必须不为 null
@AssertTrue被注解的元素必须为 true
@AssertFalse被注解的元素必须为 false
@Min(value)被注解的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value)被注解的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value)被注解的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value)被注解的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=)被注解的元素的大小必须在指定的范围内
@Digits (integer, fraction)被注解的元素必须是一个数字,其值必须在可接受的范围内
@Past被注解的元素必须是一个过去的日期
@Future被注解的元素必须是一个将来的日期
@Pattern(regex=,flag=)被注解的元素必须符合指定的正则表达式
@NotBlank(message =)验证字符串非null,且长度必须大于0
@Email被注解的元素必须是电子邮箱地址
@Length(min=,max=)被注解的字符串的大小必须在指定的范围内
@NotEmpty被注解的字符串的必须非空
@Range(min=,max=,message=)被注解的元素必须在合适的范围内

在自定义的对象中指定验证规则

package com.gupaoedu.pojo;
​
import org.hibernate.validator.constraints.Length;
​
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;

public class User {
​
​
    private Integer id;
​
    @NotNull(message = "账号不能为空")
    @Length(message = "账号的长度必须在3~6位" ,max = 6,min = 3)
    private String userName;
​
    @Max(message = "age最大值是120",value = 120)
    @Min(message = "age必须大于0" ,value = 0)
    private Integer age;
​
    public Integer getId() {
        return id;
    }
​
    public void setId(Integer id) {
        this.id = id;
    }
​
    public String getUserName() {
        return userName;
    }
​
    public void setUserName(String userName) {
        this.userName = userName;
    }
​
    public Integer getAge() {
        return age;
    }
​
    public void setAge(Integer age) {
        this.age = age;
    }
}
​

在控制层中使用校验规则

@RequestMapping("/save")
public String add(@Validated User user, BindingResult br) throws IOException {
    System.out.println("save ....");
    List<ObjectError> allErrors = br.getAllErrors();
    for (ObjectError error:allErrors){
        System.out.println(error.getDefaultMessage());
    }
    return "/index.jsp";
}

分组验证

分组验证解决的是不同的同一个POJO对象在不同的场景用适用不同的验证规则

定义分组

验证规则和分组绑定

package com.gupaoedu.pojo;
​
import com.gupaoedu.group.GroupInterface1;
import com.gupaoedu.group.GroupInterface2;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
​
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
​

public class User {
​
​
    @NotBlank(message = "ID不能为空" ,groups = {GroupInterface1.class})
    private Integer id;
​
    @NotBlank(message = "{user.username.empty}" ,groups = {GroupInterface1.class,GroupInterface2.class})
    @Length(message = "账号的长度必须在3~6位" ,max = 6,min = 3,groups = {GroupInterface1.class,GroupInterface2.class})
    private String userName;
​
    @Max(message = "age最大值是120",value = 120,groups = {GroupInterface1.class,GroupInterface2.class})
    @Min(message = "age必须大于0" ,value = 0,groups = {GroupInterface1.class,GroupInterface2.class})
    private Integer age;
​
    public Integer getId() {
        return id;
    }
​
    public void setId(Integer id) {
        this.id = id;
    }
​
    public String getUserName() {
        return userName;
    }
​
    public void setUserName(String userName) {
        this.userName = userName;
    }
​
    public Integer getAge() {
        return age;
    }
​
    public void setAge(Integer age) {
        this.age = age;
    }
}
​

应用

@RequestMapping("/save")
public String add(@Validated({GroupInterface2.class}) User user, BindingResult br, Model model) throws IOException {
    System.out.println("save ....");
    List<ObjectError> allErrors = br.getAllErrors();
    for (ObjectError error:allErrors){
        System.out.println(error.getDefaultMessage());
    }
    return "/index.jsp";
}
​
@RequestMapping("/update")
public String update(@Validated({GroupInterface1.class}) User user, BindingResult br, Model model) throws IOException {
    System.out.println("update ....");
    List<ObjectError> allErrors = br.getAllErrors();
    for (ObjectError error:allErrors){
        System.out.println(error.getDefaultMessage());
    }
    return "/index.jsp";
}

11.SpringMVC中的JSON数据处理

Jackson依赖

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.9</version>
</dependency>
​
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.9</version>
</dependency>

响应数据为JSON格式的信息

@RequestMapping("/query")
@ResponseBody
public List<User> query(){
    System.out.println("query ..... ");
    return Arrays.asList(new User(1,"zhangsan1",18)
                         ,new User(2,"zhangsan2",19)
                         ,new User(3,"zhangsan3",12));
}

接受数据为JSON数据,提交的类型必须是post方式提交



<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    <script type="text/javascript" src="js/jquery.min.js"></script>
</head>
<body>
<input type="button" value="提交JSON数据" onclick="fun1();">
<script type="text/javascript">
    function fun1(){
        $.ajax({
            type: 'POST',
            url: "/user/save",
            contentType: "application/json",//如果想以json格式把数据提交到后台的话,这个必须有,否则只会当做表单提交
            data: JSON.stringify({"userName":"sam","age":"12"}),//JSON.stringify()必须有,否则只会当做表单的格式提交
            dataType: "json",//期待返回的数据类型
            success: function(data){
                alert("success:"+data);
            },
            error:function(data){
                alert("error"+data);
            }
        });
    }
</script>
</body>
</html>
​

12.Restful风格

Restful是一种设计风格,是一个规范,不是一个技术。

提交方式地址说明
GET(查)http://localhost:8080/book/1查询id为1的书
POST(增)http://localhost:8080/book/1添加一本书,书的id为1
DELETE(删)http://localhost:8080/book/1删除id为1的书
PUT(改)http://localhost:8080/book/1修改id为1的书

控制器处理

package com.gupaoedu.controller;
​
​
import com.gupaoedu.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
​
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
​

/*@Controller // 将UserController对象交给IoC容器管理
//@RequestMapping("/user") // 类头部的可以省略
@ResponseBody*/
@RestController
public class UserController  {
​
    /**
     * 具体处理请求的方法  【头部的mapping+方法的mapping】
     * http://localhost:8082/user/query
     * @return
     */
    @GetMapping("/user/{id}/{name}")
    public List<User> query(@PathVariable Integer id,@PathVariable String name){
        System.out.println("query ..... " + id + " " + name);
        return Arrays.asList(new User(1,"zhangsan1",18)
        ,new User(2,"zhangsan2",19)
        ,new User(3,"zhangsan3",12));
    }
​
    @PostMapping("/user")
    public String add(@RequestBody User user){
        System.out.println("save ..... " + user);
        return "/index.jsp";
    }
​
    @DeleteMapping("/user")
    public String delete(){
        System.out.println("delete ..... ");
        return "/index.jsp";
    }
​
    @PutMapping("/user")
    public String update(){
        System.out.println("update ..... ");
        return "/index.jsp";
    }
}
​

SpringMVC拦截器

定义自定义的拦截器

package com.gupaoedu.interceptor;
​
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
​
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {
​
    /**
     * 在自定义控制器执行之前执行
     * @param request
     * @param response
     * @param handler
     * @return
     *    false  拦截
     *    true 放过
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        System.out.println("preHandle....");
        return true;
    }
​
    /**
     * 自定义控制器执行后执行
     *      在返回ModelAndView之前执行
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     */
    @Override
    public void postHandle(HttpServletRequest request
            , HttpServletResponse response
            , Object handler, ModelAndView modelAndView) {
​
        System.out.println("postHandle ....");
    }
​
    /**
     * 自定义控制器执行后执行
     *     在返回ModelAndView之后执行
     * @param request
     * @param response
     * @param handler
     * @param ex
     */
    @Override
    public void afterCompletion(HttpServletRequest request
            , HttpServletResponse response
            , Object handler, Exception ex) {
        System.out.println("afterCompletion....");
    }
}
​

注册拦截器

<!-- 配置拦截器 -->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="com.gupaoedu.interceptor.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/949842.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android Audio基础(53)——PCM逻辑设备Write数据

1. 前言 本文,我们将以回放(Playback,播放音频)为例,讲解PCM Data是如何从用户空间到内核空间,最后传递到Codec。 在 ASoC音频框架简介中,我们给出了回放(Playback)PCM数据流示意图。: 对于Linux来说,由于分为 user space 和kernel space,而且两者之间数据不能随便…

【漫话机器学习系列】039.点积(dot product)

点积&#xff08;Dot Product&#xff09; 点积是线性代数中的一种基本运算&#xff0c;用于两个向量的操作。它是将两个向量按分量相乘并求和的结果&#xff0c;用于衡量两个向量在同一方向上的相似性。 点积的定义 给定两个相同维度的向量 和 &#xff0c;它们的点积定义为…

2024年大型语言模型(LLMs)的发展回顾

2024年对大型语言模型&#xff08;LLMs&#xff09;来说是充满变革的一年。以下是对过去一年中LLMs领域的关键进展和主题的总结。 GPT-4的壁垒被打破 去年&#xff0c;我们还在讨论如何构建超越GPT-4的模型。如今&#xff0c;已有18个组织拥有在Chatbot Arena排行榜上超越原…

Visual Studio 2022 C++ gRPC 环境搭建

文章目录 1、gRPC 安装2、创建项目2.1、创建 “空的解决方案”2.2、新建 gRPCServer 和 gRPCClient 项目2.3、创建 proto 文件 2、为 gRPC 服务端和客服端项目配置 protobuf 编译2.1、protobuf 配置2.2、gRPCServer 项目配置2.3、gRPCClient 项目配置 3、测试3.1、启动服务端程…

Wasm是什么

WebAssembly 是什么&#xff1f; 1.1 WebAssembly 的定义 WebAssembly&#xff08;简称 Wasm&#xff09;是一种二进制指令格式&#xff0c;设计用于在现代 Web 浏览器中高效运行程序。它可以被认为是一种低级的、接近硬件的编程语言&#xff0c;是一种介于字节码和机器码之间…

使用深度学习来实现图像超分辨率 综述!

今天给大家介绍一篇图像超分辨率邻域的综述&#xff0c;这篇综述总结了图像超分辨率领域的几方面&#xff1a;problem settings、数据集、performance metrics、SR方法、特定领域应用以结构组件形式&#xff0c;同时&#xff0c;总结超分方法的优点与限制。讨论了存在的问题和挑…

直播预告|StarRocks 3.4,打造 AI 时代的智能数据基座,应用场景全面扩展

随着新年的到来&#xff0c;StarRocks 3.4 即将上线&#xff0c;为 AI Workload 和更多应用场景提供强大支持&#xff01;此次升级聚焦于提升 AI 场景支持&#xff0c;并扩展更多应用场景&#xff0c;全方位提升数据分析体验。 更强的 AI 场景支持&#xff1a; 引入 Vector In…

【GOOD】A Survey of Deep Graph Learning under Distribution Shifts

深度图学习在分布偏移下的综述&#xff1a;从图的分布外泛化到自适应 Northwestern University, USA Repository Abstract 图上的分布变化——训练和使用图机器学习模型之间的数据分布差异——在现实世界中普遍存在&#xff0c;并且通常不可避免。这些变化可能会严重恶化模…

【微服务】5、服务保护 Sentinel

Sentinel学习内容概述 Sentinel简介与结构 Sentinel是Spring Cloud Alibaba的组件&#xff0c;由阿里巴巴开源&#xff0c;用于服务流量控制和保护。其内部核心库&#xff08;客户端&#xff09;包含限流、熔断等功能&#xff0c;微服务引入该库后只需配置规则。规则配置方式有…

神经网络的进展与挫折

神经网络的概念可追溯到上世纪40年代,当时被认为是一种模拟大脑神经元网络的计算系统。 1940年代,麦卡洛克(McCulloch)和沃尔特皮茨(Walter Pitts)率先提出了受人类大脑和生物神经网络启发的人工神经网络。 1951年,马文明斯基(Marvin Minsky)的SNARC系统标志着第一个…

搭建企业AI助理的创新应用与案例分析

在大健康零售行业&#xff0c;企业面临着日益增长的市场需求和复杂的供应链管理挑战。AI助理的应用不仅能够提升客户服务效率&#xff0c;还能优化供应链管理&#xff0c;降低运营成本。 一、AI助理在大健康零售行业的创新应用 个性化健康咨询 AI助理可以通过分析客户的健康…

一文读懂「LoRA」:大型语言模型的低秩适应

LoRA: Low-Rank Adaptation of Large Language Models 前言 LoRA作为大模型的微调框架十分实用&#xff0c;在LoRA出现以前本人都是通过手动修改参数、优化器或者层数来“炼丹”的&#xff0c;具有极大的盲目性&#xff0c;但是LoRA技术能够快速微调参数&#xff0c;如果LoRA…

接口项目操作图-thinkphp6-rabbitmq

一、用户开户流程 用户首次需要联系商务开通账户&#xff0c;需要提供手机号及来访问的IP。开好户之后&#xff0c;平台方将提供用户访问的key值及header头部参数的公钥加密文件、body访问参数以及返回数据的公私钥加解密文件。 二、用户请求流程 用户将拿到的key值进行rsa公钥…

程序环境及预处理

一.程序的翻译环境和执行环境 在ANSI C&#xff08;标准c&#xff09;的任何一种实现中&#xff0c;存在两个不同的环境。 计算机是能够执行二进制指令的&#xff0c;但是我们写出的c语言代码是文本信息&#xff0c;计算机不能直接理解 第1种是翻译环境&#xff0c;在这个环境…

回顾 Tableau 2024 亮点功能,助力 2025 数据分析新突破

2024 年&#xff0c;Tableau 用更智能、更高效的工具&#xff0c;重新定义了数据分析的可能性。 回顾 2024 年&#xff0c;Tableau 凭借一系列创新功能&#xff0c;在数据可视化与分析领域再次引领潮流。无论是深度整合 AI 技术&#xff0c;还是优化用户体验的细节&#xff0c;…

【姿态估计实战】使用OpenCV和Mediapipe构建锻炼跟踪器【附完整源码与详细说明】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

快速上手Python,制作趣味猜数字游戏

在编程学习的旅程中&#xff0c;游戏是一个极佳的切入点。今天&#xff0c;我们将一起创建一个简单而有趣的猜数字游戏&#xff0c;借此机会深入学习Python编程的基础知识和一些实用的编程技巧。无论你是初学者还是有一定基础的开发者&#xff0c;相信你都能从中获得乐趣和收获…

AI驱动的可演化架构与前端开发效率

1. 引言 在当今快节奏的数字时代&#xff0c;软件系统需要具备强大的适应能力才能在瞬息万变的市场需求中保持竞争力。软件可演化架构的重要性日益凸显&#xff0c;它能够让软件系统在面对需求变更、技术升级以及市场波动时&#xff0c;能够快速、高效地进行调整和升级&#x…

用豆包MarsCode IDE打造精美数据大屏:从零开始的指南

原标题&#xff1a;用豆包MarsCode IDE&#xff0c;从0到1画出精美数据大屏&#xff01; 豆包MarsCode IDE 是一个云端 AI IDE 平台&#xff0c;通过内置的 AI 编程助手&#xff0c;开箱即用的开发环境&#xff0c;可以帮助开发者更专注于各类项目的开发。 作为一名前端开发工…

基于RK3568/RK3588大车360度环视影像主动安全行车辅助系统解决方案,支持ADAS/DMS

产品设计初衷 HS-P2-2D是一款针对大车盲区开发的360度全景影像 安全行车辅助系统&#xff0c;通过车身四周安装的超广角像机&#xff0c;经算法合成全景鸟瞰图&#xff0c;通过鸟瞰图&#xff0c;司机非常清楚的看清楚车辆四周情况&#xff0c;大大降低盲区引发的交通事故。 产…