PinkGuy / SpringMVC学习
Created 2019-12-29 Modifyd 2019-12-29

3425 Words

[TOC]

第一个SpringMVC框架

代码实现

  • 创建Maven-webapp工程,pom.xml;

    <dependencies>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.2.RELEASE</version>
    </dependency>
    
    </dependencies>
    
  • web.xml 添加拦截器

    <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    
    </servlet>
      
        
    <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
    </servlet-mapping>
    
  • 创建springmvc.xml (自动扫描不知道在哪个个包所以导入了全部)

    <?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"
       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">
    
    <!--    自动扫描-->
    <context:component-scan base-package="com.*"></context:component-scan>
    
    <!--    视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
    
    </beans>
    
  • 创建controller

    package com.mvc.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class HelloHandler {
    
    @RequestMapping("/index")
    public String index(){
        System.out.println("进入了//");
        return "index";
    }
    
    }
    

Spring MVC注解

@RequestMapping

Sprng MVC 通过 @RequestMapping 注解将 URL 请求与业务方法进行映射,在Handler 的类定义处和方法处都可以添加 RequestMapping , 在类定义处添加,相当于客户端多了一层访问路径。

@Controller

@Controller 在类处定义添加,将该类交给 IoC 容器进行管理(结合 springmvc.xml 的自动扫描食用),同时将它成为一个控制器,可以接收客户端请求

package com.mvc.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloHandler {

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

}

@RequestMapping 的相关参数

value : 指定 URL 请求的实际地址, 是 @RequestMapping 的默认值。

@RequestMapping(value = "/index")
public String index(){
    System.out.println("进入了//");
    return "index";
}

method:指定请求的类型,GET,POST,PUT,DELET;

@RequestMapping(value = "/test",method = RequestMethod.GET)
public String test(){
    System.out.println("进入了//");
    return "index";
}

上述代码只能接收GET请求;

params: 指定请求必须包含某些参数,否则无法调用该方法;

@RequestMapping(value = "/test",method = RequestMethod.GET,params = {"name","id=10"})
public String test(String name,int id){
    System.out.println(name);
    System.out.println(id);
    System.out.println("进入了//");
    return "index";
}

以上表示 接收请求必须包含 name,id值,且id值必须等于10;

@PathVariable: 传入的参数与实参不一致时,使用该方法绑定

@RequestMapping(value = "/test",method = RequestMethod.GET,params = {"name","id=10"})
public String test(@PathVariable("name") String qwq,@PathVariable("id") int qvq){
    System.out.println(qwq);
    System.out.println(qvq);
    System.out.println("进入了//");
    return "index";
}

Spring MVC 使用RESTful 风格的 URL;

传统类型: http://localhost:8080/aispringmvc_war/test?name=zhansan&id=10

REST : http://localhost:8080/aispringmvc_war/hello/test/ningling/15

@RequestMapping(value = "/test/{name}/{id}")
public String test(@PathVariable("name") String qwq,@PathVariable("id") int qvq){
    System.out.println(qwq);
    System.out.println(qvq);
    System.out.println("进入了//");
    return "index";
}

Spring MVC 数据绑定

数据绑定:在后端的业务方法中直接通过获取客户端HTTP请求中的参数,将请求参数映射到业务方法当中去,Spring MVC 中数据绑定的工作是由 HandlerAdpter 来完成的。

基本数据类型
@ResponseBody
@RequestMapping("/test")
public String test(int id){
    System.out.println("进入test");
    return ""+id;
}

发送请求 http://localhost:8080/aispringmvc_war/Date/test?id=18

当id值为null时会报错

包装类 Integer
@ResponseBody
@RequestMapping("/test")
public String test(Interg id){
    System.out.println("进入test");
    return ""+id;
}

发送请求 http://localhost:8080/aispringmvc_war/Date/test1?id=18

当id值为null时,返回页面显示null;

  • @RequestParam

value = “num”:将HTTP 请求中名为 num 的参数赋给形参。

requried:设置 num 是否必须填写,true 表示必填,false 表示非必填,可省略。

defaultValue = “0”:如果HTTP 请求中没有 num 参数,默认值为0。

@ResponseBody
@RequestMapping("/test2")
public String test2(@RequestParam(value = "num",required = true,defaultValue = "10") Integer id){
    System.out.println("进入test1");
    return ""+id;
}

数据绑定 List

Spring MVC 不支持 LIst 类型的直接转换,需要对List 集合进行封装。

代码演示

  • 集合封装类

    package com.mvc.entity;
    
    import java.util.List;
    
    public class UserList {
    
    private List<User> UserList;
    }
    
  • jsp页面

    <form action="date/list" method="post">
    <input type="text" name="UserList[0].id"><br>
    <input type="text" name="UserList[0].name"><br>
    <input type="text" name="UserList[1].id"><br>
    <input type="text" name="UserList[1].name"><br>
    <input type="text" name="UserList[2].id"><br>
    <input type="text" name="UserList[2].name"><br>
    <input type="submit" value="提交">
    </form>
    
  • controller 业务方法

    @ResponseBody
    @RequestMapping(value = "/list",method = RequestMethod.POST)
    public String list(UserList list){
    
    StringBuffer sb = new StringBuffer();
    for (User u : list.getUserList())
        sb.append(u.toString());
    
    return sb.toString();
    }
    
    
*绑定json对象
  • jsp页面引入 js,发送 json 请求

    <script src="js/jquery-3.1.1.js"></script>
    <script>
    
    $(function () {
        alert("123");
    
        var user = {
            "id":"1",
            "name":"张三"
        };
    
        $.ajax({
            url:"date/json",
            data:JSON.stringify(user),
            type:"POST",
            contentType:"applicaton/json;charset=UTF-8",
            dataType:"JSON",
            success:function (data) {
                alert(data.id+"-----"+data.name);
            }
        })
    
    
    })
    
    </script>
    
  • 设置web.xml 过滤器,不拦截 js 请求

    <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
    </servlet-mapping>
    
  • 添加 fastjson 依赖

    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.32</version>
    </dependency>
    
  • springmvc.xml 配置fastjson

    
    <mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
        <!--    消息转换器,解决@ResponseBoyd 中文乱码-->
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <property name="supportedMediaTypes" value="text/html;charset=UTF-8"/>
        </bean>
    
        <!-- 配置fastjosn-->
        <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4"/>
    </mvc:message-converters>
    </mvc:annotation-driven>
    
    
  • controller

    @ResponseBody
    @RequestMapping("/json")
    public User json(User user){
    System.out.println(user.toString());
    user.setId(4);
    user.setName("狗子");
    
    return user;
    }
    

Spring MVC 模型数据解析

JSP 四大作用域对象:爬个Content,request,session,application。

模型数据的绑定 是由 ViewResolver 完成的,实际开发中,需要先添加模型数据,再交个给 ViewResolver 来绑定。

Spring MVC 提供了以下几种方式添加模型数据:

  • Map
  • Model
  • ModelAndView
  • @ModolAttribute
  • @SessionAttribute

代码演示

将模型数据存到 request中

1,Map

  • jsp 页面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ page isELIgnored="false" %>
    <html>
    <head>
    <title>view</title>
    </head>
    <body>
    ${requestScope.user}
    </body>
    </html>
    
  • Controller

    @RequestMapping("/map")
    public String map(Map map){
    User user = new User(1,"张三",null);
    map.put("user",user);
    return "view";
    }
    

2,Model

@RequestMapping("/model")
public String model(Model model){
    User user = new User(1,"张三",null);
    model.addAttribute("user",user);
    return "view";
}

3,ModelAndView

@RequestMapping("/modelAttribute1")
public ModelAndView modelAttribute1(){
    User user = new User(1,"张三",null);
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("user",user);
    modelAndView.setViewName("view");
    return  modelAndView;
}

@RequestMapping("/modelAttribute2")
public ModelAndView modelAttribute2(){
    User user = new User(1,"张三",null);
    ModelAndView modelAndView = new ModelAndView();
    View view = new InternalResourceView("/view.jps");
    modelAndView.addObject("user",user);
    modelAndView.setView(view);
    return  modelAndView;
}

4,@ModelAttribute

@ModelAttribute
public User getUser(){
    User user = new User(1,"张三",null);
    return user;
}

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

5, 原生方式 HttpServletRequest

@RequestMapping("/request")
public String request(HttpServletRequest request){
    User user = new User(1,"张三",null);
    request.setAttribute("user",user);
    return "view";
}
将模型数据存入到 session 中

1,原生方式 HttpSession

@RequestMapping("/session")
public String session(HttpSession session){
    User user = new User(1,"张三",null);
    session.setAttribute("user",user);
    return "view";
}

2,@SessionAttributes

  • 当该类request 存入 “user” 时 自动存入 session 中

    @SessionAttributes(value = "user")
    public class ConverterHandler {
    	
    }
    
  • 当该类 request 有 User 类时, 自动存入 session 中

    @SessionAttributes(types = User.class)
    public class ConverterHandler {
    }
    

Spring MVC 自定义类型转换器

数据类型转换器是指客户端 HTTP 请求中的转换为业务方法中定义的行参。

自定义表示开发者可以自主设计转换的方式,HandlerApdter 已经提供了通用的转换(String转int,,String 转 double,表单的数据封装..)

但是在特殊的业务场景中,HandlerApdter无法进行转换,就需要开发者自行定义。

代码演示

  • 创建Converter类实现Converter泛型接口

    public class DateConverter implements Converter<String, Date> {
    
    private String pattern;
    
    public DateConverter(String pattern) {
        this.pattern = pattern;
    }
    
    @Override
    public Date convert(String source) {
    
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(this.pattern);
        Date date = null;
        try {
            date = simpleDateFormat.parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
     
        return date;
    }
    }
    
  • 配置 springmvc.xml 添加转换器配置

    <!--配置自定义转换器-->
    <bean id="conversinService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <list>
            <bean class="com.mvc.converter.DateConverter">
                <constructor-arg type="java.lang.String" value="yyyy-MM-dd"/>
            </bean>
        </list>
    </property>
    </bean>
    
    
    <mvc:annotation-driven conversion-service="conversinService">
    <mvc:message-converters register-defaults="true">
        <!--    消息转换器,解决@ResponseBoyd 中文乱码-->
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <property name="supportedMediaTypes" value="text/html;charset=UTF-8"/>
        </bean>
    
        <!-- 配置fastjosn-->
        <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4"/>
    </mvc:message-converters>
    </mvc:annotation-driven>
    
  • controller 层

    @Controller
    @RequestMapping("/converter")
    public class ConverterHandler {
    
    @RequestMapping("/date")
    @ResponseBody
    public String Date(Date date){
        return date.toString();
    }
    
    }
    
  • jsp 发送请求

    <body>
    <form action="converter/date" method="post">
        <input type="text" name="date">yyyy-MM-dd<br/>
        <input type="submit" value="提交">
    </form>
    </body>
    

Spring MVC REST

REST:Representational State Transfer,资源表现层状态转换,目前主流的一种互联网软件架构,它结构清晰,标准规范,易于理解,便于扩展。

  • 资源(Resource)

网络上的一个实体,或者说网络中存在的一个具体信息,一段文本,一张图片,一首歌曲,一段视频等,总之就是一个具体的存在。可以用 URI (统一资源定位符)指向它,每个资源都有对应的一个特定的 URI,要获取该资源时,只需访问对应的 URI 即可。

  • 表现层(Representation)

资源具体呈现出来的形式,比如文本可以用 txt 格式表示,也可以用 HTML,JSON 等格式来表示。

  • 状态转换(State Transfer)

客户端如果希望操作服务器中的某一个资源,就需要通过某种方式让服务端发生状态转换,而这种转换是建立再表现层之上的,所以叫做“表现层状态转换”。

特点

  • URL 更加简洁

  • 有利于不同系统之间的资源共享,只需遵守REST的规范,不需要进行其他配置即可实现资源共享。

如何使用

REST 具体操作就是HTTP 协议中四个表示操作方式的动词分别对应 CRUD 基本操作。

GET 用来获取资源。

POST 用来表示 新建资源。

PUT 用来修改资源。

DELETE 用来表示删除资源。

Spring MVC 文件上传下载

单文件上传

底层是通过 Apache fileupload 组件完成上传,Spring MVC 对这种方式进行了封装。

  • pom.xml

    <!-- 文件上传依赖 -->
    <dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
    </dependency>
    
    <dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
    </dependency>
    
  • controller

    
    @RequestMapping("/file")
    @Controller
    public class UploadHandler {
    
    @RequestMapping("/upload")
    public String upload(MultipartFile img,HttpServletRequest request){
        if (img.getSize() > 0){
            //获取文件上传的路径
            String path = request.getServletContext().getRealPath("file");
            //获取上传的文件名
            String name = img.getOriginalFilename();
            File file = new File(path,name);
            try {
                img.transferTo(file); //上传
            } catch (IOException e) {
                e.printStackTrace();
            }
            request.setAttribute("path",name); //存到 request
        }
    
        return "upload";
    }
    }
    
  • jsp

    <body>
    
    
    <form action="file/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="img"><br/>
    <input type="submit" name="提交">
    </form>
    
    <img src="${path}">
    
    </body>
    
多文件下载
  • controller

    @RequestMapping("/uploads")
    public String uploads(MultipartFile[] imgs,HttpServletRequest request){
    
    List list = new ArrayList();
    
    for (MultipartFile img:imgs) {
        if (img.getSize() > 0){
            //获取文件上传的路径
            String path = request.getServletContext().getRealPath("file");
            //获取上传的文件名
            String name = img.getOriginalFilename();
            File file = new File(path,name);
            try {
                img.transferTo(file); //上传
                list.add(name); //保存后的文件路径
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    }
    request.setAttribute("fileList",list); //存到 request
    return "upload";
    }
    
  • jsp (再用jstl 遍历list)

    <form action="file/uploads" method="post" enctype="multipart/form-data">
    <input type="file" name="imgs"><br/>
    <input type="file" name="imgs"><br/>
    <input type="file" name="imgs"><br/>
    <input type="submit" name="提交">
    </form>
    
下载