SpringMVC习记录

1.MVC与三层架构

  • MVC即是一种开发模式(看了图一目了然)
    在这里插入图片描述
  • 三层架构
    表现层:用于展示数据
    业务层:是处理业务需求
    持久层:和数据库交互
    在这里插入图片描述

2.SpringMVC概述

*概述: SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于 Spring FrameWork 的后续产品,已经融合在 Spring Web Flow 里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。

  • SpringMVC在三层架构中的位置
    在这里插入图片描述

3.SpringMVC与Struts2的区别

  • 共同点:
    1.它们都是表现层框架,都是基于 MVC 模型编写的。
    2.它们的底层都离不开原始 ServletAPI。
    3.它们处理请求的机制都是一个核心控制器。
  • 区别:
    1.Spring MVC 的入口是 Servlet, 而 Struts2 是 Filter
    2.Spring MVC 是基于方法设计的,而 Struts2 是基于类,Struts2 每次执行都会创建一个动作类。所以 Spring MVC 会稍微比 Struts2 快些。
    3.Spring MVC 使用更加简洁,同时还支持 JSR303, 处理 ajax 的请求更方便(JSR303 是一套 JavaBean 参数校验的标准,它定义了很多常用的校验注解,我们可以直接将这些注解加在我们 JavaBean 的属性上面,就可以在需要校验的时候进行校验了。)
    4.Struts2 的 OGNL 表达式使页面的开发效率相比 Spring MVC 更高些,但执行效率并没有比 JSTL 提升,尤其是 struts2 的表单标签,远没有 html 执行效率高。

4.SpringMVC中的组件

SpringMVC框架是基于组件方式执行的:

  • 前台控制器
  • 处理器映射器
  • 处理器适配器
  • 试图解析器
    在这里插入图片描述

5.@RequestMapping注解

1.作用:用于建立请求 URL 和处理请求方法之间的对应关系。
2.出现位置:可以在类上(作为一级目录),也可以在方法上(作为二级目录),若类上有的话那么前台访问时的路径就要写一级路径+二级路径(user/hello)
3.属性:

  • value:用于指定请求的 URL。
  • method:用于指定请求的方式。
  • params:用于指定限制请求参数的条件。
  • headers:用于指定限制请求消息头的条件。

6.请求参数的绑定

<a href="params/getParams?username=smx&password=123">请求参数的绑定</a>

对应后台的代码为:

@Controller
@RequestMapping("/params")
public class ParamsTest {
    @RequestMapping("/getParams")
    public String getParams(String username,String password){
        System.out.println("测试请求参数的绑定");
        System.out.println("用户名为:"+username);
        System.out.println("密码为:"+password);
        return "success";
    }
}

7.常用注解

1.@RequestParam
作用:
把请求中指定名称的参数给控制器中的形参赋值。
属性:
value:请求参数中的名称。
required:请求参数中是否必须提供此参数。默认值:true。表示必须提供,如果不提供将报错
2.@RequestBody
作用:
用于获取请求体内容。直接使用得到是 key=value&key=value…结构的数据。
get 请求方式不适用。
属性:
required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值
为 false,get 请求得到是 null。
3.@PathVariable
作用:
用于绑定 url 中的占位符。例如:请求 url 中 /delete/{id},这个{id}就是 url 占位符。
url 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 rest 风格 URL 的一个重要标志。
属性:
value:用于指定 url 中占位符名称。
required:是否必须提供占位符。
4.@RequestHeader
作用:
用于获取请求消息头。
属性:
value:提供消息头名称
required:是否必须有此消息头
5.@CookieValue
作用:
用于把指定 cookie 名称的值传入控制器方法参数。
属性:
value:指定 cookie 的名称。
required:是否必须有此 cookie。
6.@ModleAttribute
作用:
该注解是 SpringMVC4.3 版本以后新加入的。它可以用于修饰方法和参数。出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。出现在参数上,获取指定的数据给参数赋值。
属性:
value:用于获取数据的 key。key 可以是 POJO 的属性名称,也可以是 map 结构的 key。
应用场景:
当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
例如:
我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数
据是肯定没有此字段的内容,一旦更新会把该字段内容置为 null,此时就可以使用此注解解决问题。
7.@SessionAttribute
作用:
用于多次执行控制器方法间的参数共享。
属性:
value:用于指定存入的属性名称
type:用于指定存入的数据类型。
学习这个注解时有一个问题就是----为什么要和Model扯上关系呢(经过思考得知是因为有了这个注解才会有方法间的参数共享所以model是为了演示共享的问题)

8. SpringMVC最基本的配置

springmvc-servlet.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"
       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
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--开启注解扫描-->
    <context:component-scan base-package="smx.bedroom"></context:component-scan>
    <!--加了这行代码之后自动配置处理器映射器和处理器适配器-->
    <mvc:annotation-driven />
    <!--视图解析器:DispatcherServlet给他的ModelAndView-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <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:springmvc-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!--用于处理乱码问题-->
    <filter>
        <filter-name>encoding</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>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

9.数据写回前端

数据显示到前端
第一种 : 通过ModelAndView

public class ControllerTest1 implements Controller {

   public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
       //返回一个模型视图对象
       ModelAndView mv = new ModelAndView();
       mv.addObject("msg","ControllerTest1");
       mv.setViewName("test");
       return mv;
  }
}

第二种 : 通过ModelMap

@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
   //封装要显示到视图中的数据
   //相当于req.setAttribute("name",name);
   model.addAttribute("name",name);
   System.out.println(name);
   return "hello";
}

第三种 : 通过Model(最常用的)

@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model){
   //封装要显示到视图中的数据
   //相当于req.setAttribute("name",name);
   model.addAttribute("msg",name);
   System.out.println(name);
   return "test";
}

10.重定向与转发

@Controller
public class ForwordRedirect {
    @RequestMapping("/tf")
    public String testForward(Model model){
        model.addAttribute("msg","testForword");
        //return "success";//存在试图解析器的转发它等价于-->return "forward:/WEB-INF/jsp/success.jsp"
        //return "/WEB-INF/jsp/success.jsp";//不存在试图解析器的转发
        return "forward:/WEB-INF/jsp/success.jsp";//存在试图解析器的转发
    }

    @RequestMapping("/tre")
    public String testreRedirect(Model model){
        model.addAttribute("msg","testreRedirct");
        return "redirect:/post.jsp";//重定向
        //return "/post.jsp";//没有试图解析器的重定向
    }

}

11.Restful风格

@Controller
public class RestfulController {
    @GetMapping("/tr/{a}/{b}")
    //@RequestMapping(value ="/tr/{a}/{b}",method = RequestMethod.GET)
    public String testRestful(@PathVariable int a, @PathVariable int b, Model model){
        int result=a+b;
        model.addAttribute("msg","结果为:"+result);
        return "success";
    }

    @PostMapping("/tr2/{a}/{b}")
    //@RequestMapping(value ="/tr/{a}/{b}",method = RequestMethod.POST)
    public String testRestful2(@PathVariable int a, @PathVariable int b, Model model){
        int result=a+b;
        model.addAttribute("msg","结果为:"+result);
        return "success";
    }
}

12.响应json数据

//@Controller
@RestController//它的作用等同于@RequestBody有了它将不再走视图解析器了之间返回字符串
public class JsonController {
    //@RequestBody有了它将不再走视图解析器了之间返回字符串
    @RequestMapping("/testjson")
    public String testjson() throws JsonProcessingException {
        User user = new User();
        user.setAge(20);
        user.setName("smx");
        ObjectMapper mapper=new ObjectMapper();
        String s = mapper.writeValueAsString(user);
        return s;
    }
}

13.文件的上传和下载

package smx.bedroom.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

@Controller
public class FileController {
    //@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象
    //批量上传CommonsMultipartFile则为数组即可
    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {

        //获取文件名 : file.getOriginalFilename();
        String uploadFileName = file.getOriginalFilename();

        //如果文件名为空,直接回到首页!
        if ("".equals(uploadFileName)){
            return "redirect:/index.jsp";
        }
        System.out.println("上传文件名 : "+uploadFileName);

        //上传路径保存设置
        String path = request.getServletContext().getRealPath("/upload");
        //如果路径不存在,创建一个
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        System.out.println("上传文件保存地址:"+realPath);

        InputStream is = file.getInputStream(); //文件输入流
        OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流

        //读取写出
        int len=0;
        byte[] buffer = new byte[1024];
        while ((len=is.read(buffer))!=-1){
            os.write(buffer,0,len);
            os.flush();
        }
        os.close();
        is.close();
        return "success";
    }


    /*
     * 采用file.Transto 来保存上传的文件
     */
    @RequestMapping("/upload2")
    public String  fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {

        //上传路径保存设置
        String path = request.getServletContext().getRealPath("/upload");
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        //上传文件地址
        System.out.println("上传文件保存地址:"+realPath);

        //通过CommonsMultipartFile的方法直接写文件(注意这个时候)
        file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));

        return "success";
    }

    /**
     * 文件下载
     */
    @RequestMapping(value="/download")
    public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{
        //要下载的图片地址
        String  path = request.getServletContext().getRealPath("/upload");
        String  fileName = "Java面试题以及答案.pdf";

        //1、设置response 响应头
        response.reset(); //设置页面不缓存,清空buffer
        response.setCharacterEncoding("UTF-8"); //字符编码
        response.setContentType("multipart/form-data"); //二进制传输数据
        //设置响应头
        response.setHeader("Content-Disposition",
                "attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));

        File file = new File(path,fileName);
        //2、 读取文件--输入流
        InputStream input=new FileInputStream(file);
        //3、 写出文件--输出流
        OutputStream out = response.getOutputStream();

        byte[] buff =new byte[1024];
        int index=0;
        //4、执行 写出操作
        while((index= input.read(buff))!= -1){
            out.write(buff, 0, index);
            out.flush();
        }
        out.close();
        input.close();
        return "success2";
    }
}

14.拦截器的配置

  <!--拦截器的配置-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**/"/>
            <bean class="smx.bedroom.config.MyIntercepter"/>
        </mvc:interceptor>

        <mvc:interceptor>
            <mvc:mapping path="/**/"/>
            <bean class="smx.bedroom.config.UserIntercepter"/>
        </mvc:interceptor>
    </mvc:interceptors>
相关推荐

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:1024 设计师:我叫白小胖 返回首页

打赏作者

Mr_Sang_

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值