登录 or

SpringMVC相关总结整理

Spring MVC
model view controller
model:数据动态(数据和行为)现在分开为数据Dao和服务层service
 
web.xml要继承容器tomcat的web.xml
Myservler.class
extend HttpServlet导包
dopost
dpget
页面发请求:
转发:客户端给服务端发请求,服务器给客户端反馈
 
重定向:多次反馈
面试问:1.mvc 和  webflux有什么不同
 2.jsp九大内置对象
 
 响应式扩
 
 springMvc是模块不是框架
 
 dispatcherservlet前端控制器
 
 前端控制器的流程(mvc的流程)
 
 选项目文字右键framework加web
 导maven包,webmvc,springweb
 
 1.springMVC流程图
 
 
 
 
2.创建最基础的springmvc项目
idea-newproject-maven
AddFramework Support----web APPlication
 
 
编写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/ja ... ot%3B
         version="4.0">
    <!--配置DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--关联springmvc的配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
    </servlet>
    <!--匹配servlet的请求,/标识匹配所有请求-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--/*和/都是拦截所有请求,/会拦截的请求不包含*.jsp,而/*的范围更大,还会拦截*.jsp这些请求-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
 
resource——applicationContext.xml
 <!--自动扫描包,由IOC容器进行控制管理-->
    <context:component-scan base-package="com.mashibing"></context:component-scan>
<!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>
 
 
编写HelloController.java类
@Controller
public class HelloController{
    /*
    * @RequestMapping就是用来标识此方法用来处理什么请求,其中的/可以取消
    * 取消后默认也是从当前项目的根目录开始查找,一般在编写的时候看个人习惯
    * 同时,@RequestMapping也可以用来加在类上,
*什么时候在类上添加此注解?当包含多个controller,同时在不同的controller中包含同名的请求的时候,需要添加
 
    * */
    @RequestMapping("/hello")
    public String hello(Model model){
        model.addAttribute("msg","hello,SpringMVC");
        return "hello";
    }
}
 
 
总结springmvc的流程
1.客户端发送请求http://localhost:8080/hello
2.首先交给tomcat容器
3.在web.xml文件中配置DispatcherServlet(前端控制器)的类(pom依赖导入),所以会由当前的DispatcherServlet类接受请求
4.查看请求地址和@RequestMapping注解的哪个相匹配,找到具体的类的处理方法
6.前端控制器找到目标类和方法之后,执行目标方法,返回一个(页面)值
5.springMVC视图解析器根据返回值进行解析,映射对应的jsp页面
6.jsp页面进行渲染
7.将渲染结果返回前端控制台(dispatcherservlet),拿到对应路径地址之后响应用户,返回给浏览器
 
1、SpringMVC对请求参数的处理
​ 在之前的servlet中我们可以通过request.getParameter()来获取请求中的参数,但是在我们编写的SpringMVC的应用程序中,在具体请求的方法中并不包含request参数,那么我们应该如何获取请求中的参数呢?
 
​ 需要使用以下几个注解:
 
​ @RequestParam:获取请求的参数
 
​ @RequestHeader:获取请求头信息
 
​ @CookieValue:获取cookie中的值
 
@Controller
public class RequestController {
 
    /**
     * 如何获取SpringMVC中请求中的信息
     *  默认情况下,可以直接在方法的参数中填写跟请求一样的名称,此时会默认接受参数
     *      如果有值,直接赋值,如果没有,那么直接给空值
     *
     * @RequestParam:获取请求中的参数值,使用此注解之后,参数的名称不需要跟请求的名称一致,但是必须要写
     *      public String request(@RequestParam("user") String username){
     *
     *      此注解还包含三个参数:
     *      value:表示要获取的参数值
     *      required:表示此参数是否必须,默认是true,如果不写参数那么会报错,如果值为false,那么不写参数不会有任何错误
     *      defaultValue:如果在使用的时候没有传递参数,那么定义默认值即可
     *
     *
     * @param username
     * @return
     */
    @RequestMapping("/request")
    public String request(@RequestParam(value = "user",required = false,defaultValue = "hehe") String username){
        System.out.println(username);
        return "success";
    }
}
 
 
@PathVariable可以获取请求路径中的值
在路径中要使用{变量名称}做标识
在方法参数中可以添加@PathVariable做识别,如果路径中的名称跟参数的名称不一致的时候,可以添加路径中的变量,推荐添加
 
testVariable?id=1&name=zhangsan
改写后为testVariable/1/zhangsan 这种叫做REST风格
 
@RequestParam获取参数后面的值(?k=v的v值)
经常跟PathVariable混淆,一个是上面路径,一个是形参
 
  
 
rest风格
REST,翻译过来叫做表现层状态转化
人话:我们在获取资源的时候就是进行增删改查的操作,如果是原来的架构风格,需要发送四个请求,分别是:
 
​ 查询:localhost:8080/query?id=1
 
​ 增加:localhost:8080/insert
 
​ 删除:localhost:8080/delete?id=1
 
​ 更新:localhost:8080/update?id=1
 
​ 按照此方式发送请求的时候比较麻烦,需要定义多种请求,而在HTTP协议中,有不同的发送请求的方式,分别是GET、POST、PUT、DELETE等,我们如果能让不同的请求方式表示不同的请求类型就可以简化我们的查询
 
​ GET:获取资源 /book/1
 
​ POST:新建资源 /book
 
​ PUT:更新资源 /book/1
 
​ DELETE:删除资源 /book/1
 
​ 一切看起来都非常美好,但是大家需要注意了,我们在发送请求的时候只能发送post或者get,没有办法发送put和delete请求,那么应该如何处理呢?下面开始进入代码环节:
 
RestController.java
 
package com.guaguauu.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
 
@Controller
public class RestController {
 
    @RequestMapping(value = "/user",method = RequestMethod.POST)
    public String add(){
        System.out.println("添加");
        return "success";
    }
 
    @RequestMapping(value = "/user/{id}",method = RequestMethod.DELETE)
    public String delete(@PathVariable("id") Integer id){
        System.out.println("删除:"+id);
        return "success";
    }
 
    @RequestMapping(value = "/user/{id}",method = RequestMethod.PUT)
    public String update(@PathVariable("id") Integer id){
        System.out.println("更新:"+id);
        return "success";
    }
 
    @RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
    public String query(@PathVariable("id") Integer id){
        System.out.println("查询:"+id);
        return "success";
    }
}
 
web.xml
关键词:HiddenHttpMethodFilter
<!--此过滤器完成请求方式的转换,将post请求转换成put和delete-->
    <filter>
        <filter-name>hidden</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hidden</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
 
rest.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="/user" method="post">
        <input type="submit" value="增加">
    </form>
    <form action="/user/1" method="post">
        <input name="_method" value="delete" type="hidden">
        <input type="submit" value="删除">
    </form>
    <form action="/user/1" method="post">
        <input name="_method" value="put" type="hidden">
        <input type="submit" value="修改">
    </form>
    <a href="/user/1">查询</a><br/>
</body>
</html>
 
 
乱码问题解决:
我们需要设置request和response的编码方式,可以自己手动编写过滤器,也可以由现成的框架来实现
post:必须要分别设置request和response的编码格式
get:在tomcat的servlet.xml文件中,添加URIEncod=utf-8
 
在一个应用程序中可能包含N多个过滤器,这N多个过滤器一般没有顺序的要求,但是如果你设置了编码过滤器,那么要求必须要将编码过滤器设置到最上面,保证编码过滤器优先执行
 <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <!--解决post请求乱码-->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <!--解决响应乱码-->
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
 
 
 
 
/**
     * SpringMVC也可以在参数上使用原生的Servlet API
     *
     *  HttpSession
     *  HttpServletRequest
     *  HttpServletResponse
     *
     *  java.security.Principal 安全协议相关
     *  Locale:国际化相关的区域信息对象
     *  InputStream:
     *      ServletInputStream inputStream = request.getInputStream();
     *  OutputStream:
     *      ServletOutputStream outputStream = response.getOutputStream();
     *  Reader:
     *      BufferedReader reader = request.getReader();
     *  Writer:
     *      PrintWriter writer = response.getWriter();
     * @param session
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("api")
    public String api(HttpSession session, HttpServletRequest request, HttpServletResponse response){
        request.setAttribute("requestParam","request");
        session.setAttribute("sessionParam","session");
        return "success";
    }
 
 
2.回显数据
在向页面回显数据的时候,可以在方法的参数中显示的声明
Map: public String out(Map<String,String> map){map.put("msg","hello"); return "success";}
 
ModelMap:
@RequestMapping("/modelmap")
    public String modelMap(ModelMap modelMap){
        modelMap.addAttribute("msg","欢迎");
        System.out.println(modelMap);
        return "success";
    }
 
Model:
@RequestMapping("/output3")
    public String output3(Model model){
        model.addAttribute("msg","欢迎3");
        System.out.println(model);
        return "success";
    }
 
ModelAndView:
@RequestMapping("/output4")
    public ModelAndView outPut4(){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("success");
        mv.addObject("msg","hello,spring4,modelandview");
        return mv;
    }
 
 
都可以将数据进行回显:回显之后的数据是保存在哪个作用域中的?
page:
request:
session:
applciation
在当前请求,也就是request中
 
@SessionAttributes
当需要向session中设置数据的时候,可以在当前Controller上添加@SessionAttributes注解,
此注解表示,每次在向request作用域中设置属性值的时候,顺带着向Session中保存了一份
 
@SessionAttributes(value = {"username","msg"},types = Integer.class)
value和type都写上表示两者都可,或的关系
 
@ModelAttribute
crud,不能修改的字段虽然是空但可带上
在使用@ModelAttribute的时候,需要注意:
1.如果参数中的注解没有写名字的话,默认是用参数名称的首字母小写来匹配
2.如果有值,直接返回,如果没有值,会去session中进行查找,也就是会判断当前类上是否添加过@SessionAttributes
推荐:注解中最好添加参数,来作为标识,进行对象属性的赋值
 
 
转发和重定向注解
1.使用forward实现页面转发
 @RequestMapping("/forward01")
    public String forward(){
        System.out.println("1");
        return "forward:/index.jsp";
    }
 
 
    @RequestMapping("/forward02")
    public String forward2(){
        System.out.println("2");
        return "forward:/forward01";
    }
 
2.使用redirect来实现重定向
@RequestMapping("redirect")
    public String redirect(){
        System.out.println("redirect");
        return "redirect:/index.jsp";
    }
 
    @RequestMapping("/redirect2")
    public String redirect2(){
        System.out.println("redirect2");
        return "redirect:/redirect";
    }
 
重定向操作也不会经过视图处理器
 
区别 转发forward()           重定向sendRedirect()
根目录 包含项目访问地址       没有项目访问地址
地址栏 不会发生变化           会发生变化
哪里跳转 服务器端进行的跳转   浏览器端进行的跳转
请求域中数据 不会丢失       会丢失
 

0 个评论

要回复文章请先登录注册