• 【SpringMVC】基础、环境搭建、注解搭建、 and so on……


    SpringMVC

    springMVC是一种基于Java实现MVC模型的轻量级Web框架

    • 是一种表现层框架技术
    • 用于进行表现层功能开发

    【原理】:

    【原理每个人的理解不一样,面试考】
    在这里插入图片描述

    一、why?:

    【重点解决的是servlet问题】以前一个请求写一个servlet,违背了面向对象的原则,都是操作一个模块,却写了很多servlet,麻烦。
    创建一个Controller类,请求多个方法,一个模块的执行可以写一个类文件。

    二、环境搭建(配置方式):

    ▶1.导入jar包
      
      <properties>
        <spring.version>4.0.2.RELEASEspring.version>
      properties>
      
    	<dependency>
    		<groupId>org.springframeworkgroupId>
    		<artifactId>spring-webartifactId>
    		<version>${spring.version}version>
    	dependency>
    	<dependency>
    		<groupId>org.springframeworkgroupId>
    		<artifactId>spring-webmvcartifactId>
    		<version>${spring.version}version>
    	dependency>
    	
    	
    	
        <dependency>
          <groupId>javax.servletgroupId>
          <artifactId>servlet-apiartifactId>
          <version>2.5version>
        dependency>
        
        <dependency>
          <groupId>javax.servlet.jspgroupId>
          <artifactId>jsp-apiartifactId>
          <version>2.2version>
        dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    ▶2.创建简单测试----创建Controller类继承AbstractController
    //创建IndexController.java类,继承AbstractController,会重写方法
    public class IndexController extends AbstractController {
    	@Override
        protected ModelAndView handleRequestInternal(HttpServletRequest httpServletRequest, 
                                                     HttpServletResponse httpServletResponse) throws Exception {
            System.out.println("测试输出====");
            //return返回的试图就是页面
            return new ModelAndView("index.jsp");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    ▶3.如何读取Controller文件,创建SpringMVC.xml配置文件,映射Controller

    命令空间有两个没有用到,后续会用的。-------看注释

    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
           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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
        
        
        <bean name="/indexController" class="com.jules.controller.IndexController">bean>
    
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    ▶4.在web.xml中读取SpringMVC.xml配置文件
    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 Applicationdisplay-name>
      
      
      <servlet>
        <servlet-name>springMVCservlet-name>  
        
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class> 
        <init-param>
          <param-name>contextConfigLocationparam-name>
          <param-value>classpath:SpringMVC.xmlparam-value> 
        init-param>
        <load-on-startup>1load-on-startup> 
      servlet>
      <servlet-mapping>
        <servlet-name>springMVCservlet-name>
        <url-pattern>/url-pattern>
      servlet-mapping>
    web-app>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    ▶5.项目加入Tomcat(Tomcat应该都配置好了,前期Maven有教程)。

    【▲注意:启动服务器,要想浏览器可以直接打开项目,下图:如果“/”后还有东西,在浏览器地址要加上“/”后面的名称。】
    在这里插入图片描述

    ▶6.此处没有项目,只是测试我们的Controller是否可以读取,springMVC配置是否完成

    在这里插入图片描述
    在这里插入图片描述


    三、注解驱动控制器Controller(注解方式)

    上面我们发现执行Controller依旧很麻烦,所以项目一般使用注解进行

    ▶1.web.xml

    和上面一样,它 是读取配置文件的,一直需要。

    ▶2.SpringMVC.xml配置(头部关于context的命令)
    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
           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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
    
    
    
        
        <context:component-scan base-package="com.hz.controller" />
        
        <mvc:annotation-driven/>
    
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    ▶3.Controller,不需要继承
    • @Controller:标注一个普通的JavaBean成为可以处理请求的控制器

    • @RequestMapping:通过请求URL进行映射,可以写在方法上,也可以写在类上表示整个模块

    @Controller    //必须有
    //@RequestMapping("/indexController")
    public class IndexController {
    //这样可以写多个方法====
    
        //在方法上注解
        //方法一:
        @RequestMapping("/index")
        public ModelAndView index() {
            System.out.println("index方法~~~~");
            return new ModelAndView("index.jsp");
        }
    
    	//方法二:
        @RequestMapping("/aaa")
        public ModelAndView aaa() {
            System.out.println("aaaa方法~~~~");
            return new ModelAndView("index.jsp");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    四、关于@RequestMapping()

    • ▶标识在类上:标识这一个模块,区别两个模块中的重复方法

    • ▶标识在方法上:作为路径

      • 拥有属性method

        method:
        RequestMethod.GET------必须以GET方式进入 @GetMapping
        RequestMethod.POST----必须以POST方式进入 @PostMapping

    • ▶传参:

      @Controller
      @RequestMapping("/provider")
      public class ProviderController {
          @RequestMapping(value = "/index",method = RequestMethod.GET)
          //直接传参
          public ModelAndView index(String proName,String proCode) {
              System.out.println("proName=="+proName);
              System.out.println("proCode=="+proCode);
              return new ModelAndView("/index.jsp");
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • ▶拥有属性params:请求参数的映射条件,指定请求的URL地址需要带那些参数:params={ “param1=value1” , “param2” , “!param3” --不传}

      • 必须要传的值
        @Controller
        @RequestMapping("/provider")
        public class ProviderController {
        															 //此时proName必须传
            @RequestMapping(value = "/index",method = RequestMethod.GET,params = {"proName"})
            public ModelAndView index(String proName,String proCode) {
                System.out.println("proName=="+proName);
                System.out.println("proCode=="+proCode);
                return new ModelAndView("/index.jsp");
            }
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11

    五、关于@RequestParam()传参

    • 属性value传递参数的别名;
    • 属性required是否必须传此参数,默认false;
    • 属性defaultValue设置默认值
    • 必须传的值required = true与设置默认值defaultValue="0000"是冲突的
    • 不管是Integer类型还是String类型,传递默认值都要加引号
       public ModelAndView index(@RequestParam(value = "pName",required = true) String proName,
                                String proCode,
                                @RequestParam(value = "id",defaultValue = "1")Integer id) {
          System.out.println("proName=="+proName);
          System.out.println("proCode=="+proCode);
          return new ModelAndView("/index.jsp");
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    六、传对象

    要加入实体类

    
    <body>
        <form action="/provider/testProvider" method="post">
            供应商编号:<input type="text" name="proCode" /><br/>
            供应商名称:<input type="text" name="proName" /><br/>
            <input type="submit" value="注册">
        form>
    body>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    @RequestMapping(value = "/testProvider",method = RequestMethod.POST)
        public ModelAndView saveProvider(Provider provider) {
            System.out.println(provider.toString());
            return new ModelAndView("/index.jsp");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    七、参数传递(作用域):

    【前四种是request域,最后一个是session作用域】

    1.加注解@ModelAttribute
    @Controller
    public class IndexController {
        @RequestMapping("/index1")
                                 //uname放入request作用域
        public ModelAndView index(@ModelAttribute("uname") String uname) {
            System.out.println("uname==="+uname);
            return new ModelAndView("/index.jsp");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    2.new ModelAndView()
    @Controller
    public class IndexController {
        @RequestMapping("/index2")
        public ModelAndView index() {
            //自定义数据放域
            String msg = "这是IndexController类";
            ModelAndView mv = new ModelAndView("/index.jsp");
            mv.addObject("msg",msg);
            //mv.setViewName("视图名");
            return mv;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    3.model
        @RequestMapping("/index3")
        public String index1(Model model)
        {
            model.addAttribute("user_name","张三");
            return "/index.jsp";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    4.map
        @RequestMapping("/index4")
        public String index2(Map<String ,Object> map){
            map.put("user_name","789");
            return "/index.jsp";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    【注意:使用EL表达式加-----isELIgnored="false"】

    //index.jsp 测试上面request作用域传值
    <%@ page contentType="text/html;charset=UTF-8" isELIgnored="false" language="java" %>
    <html>
    <body>
    <h2>首页~Hello World!h2>
    		${uname}     <br/>
    		${msg}       <br/>
    		${user_name} <br/>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    【开启服务器,访问 @RequestMapping("/index~")等路径测试作用域】

    5.@SessionAttributes

    【@SessionAttributes只能定义在类上,作用是将指定的Model中的键值对添加至session中】

    • @SessionAttributes(types=User.class)会将model中所有类型为 User的属性添加到会话中。
    • @SessionAttributes(value={“user1”, “user2”}) 会将model中属性名为user1和user2的属性添加到会话中。
    • @SessionAttributes(types={User.class, Dept.class}) 会将model中所有类型为 User和Dept的属性添加到会话中。
    • @SessionAttributes(value={“user1”,“user2”},types={Dept.class})会将model中属性名为user1和user2以及类型为Dept的属性添加到会话中。
    @Controller
    @SessionAttributes(value = {"name"}) //与Model中的键key保持一致
    public class IndexController {
    
        @RequestMapping("/index0")
        public ModelAndView index0(String user_name){
            ModelAndView mv = new ModelAndView("/index.jap");
            //存入Request作用域和Session作用域
            mv.addObject("name",user_name);
            return mv;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述
    在saveProvider.jsp获取数据测试数据是否保存在session中${name}

    在这里插入图片描述

    6.转发与重定向

    【return默认是转发,重定向放在request的值拿不到 】

    public String test(User user)
    {
        .....
        return "redirect:/user.jsp";  //重定向
        return "forward:页面";        //转发 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    八、@ResponseBody返回json数据

    @ResponseBody这个注解通常使用在控制层(controller)的方法上,其作用是将方法的返回值以特定的格式写入到response的body区域,进而将数据返回给客户端。当方法上面没有写ResponseBody,底层会将方法的返回值封装为ModelAndView对象。

    • 假如是字符串则直接将字符串写到客户端。如果返回String,默认按iso8859-1编码,页面可能出现乱码。因此在注解中我们可以手动修改编码格式,例如@RequestMapping(value=“/路径”,produces=“text/html;charset=utf-8”),前面是请求的路径,后面是编码格式。

    • 假如是一个对象,此时会将对象转化为json串然后写到客户端,返回对象,按utf-8编码。

    • 可以加在类上,下面的所有方法数据返回json
    • 加在方法上,设置当前控制器方法响应内容为当前返回值,无需解析
    • 使用前先导坐标
      
          <dependency>
            <groupId>com.fasterxml.jackson.coregroupId>
            <artifactId>jackson-coreartifactId>
            <version>2.4.3version>
          dependency>
          <dependency>
            <groupId>com.fasterxml.jackson.coregroupId>
            <artifactId>jackson-databindartifactId>
            <version>2.4.3version>
          dependency>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 使用类上的时候:@RestControlle相当于@Controller+@ResponseBody,直接使用@RestControlle即可。
    @Controller
    //@ResponseBody     //给下面所有方法返回JSON
    //@RestController   //相当于@Controller+@ResponseBody
    public class IndexController {
    	/**
         * 对象返回JSON
         * @return
         */
        @RequestMapping("/findProviderJSON")
        @ResponseBody    //自动返回json
        public Provider findProviderJSON() {
            Provider provider= new Provider();
            provider.setProCode("7811");
            provider.setProName("三百七七");
            return provider;
        }
    
        /**
         * 集合返回对象
         * @return
         */
        @RequestMapping("/findProListJSON")
        @ResponseBody    //自动返回json,就不会返回页面
        public List<Provider> findProListJSON(){
            List<Provider> provider = new ArrayList<Provider>();
            Provider provider1 = new Provider();
            provider1.setProName("朱尔斯");
            provider1.setCreationDate(new Date());
            Provider provider2 = new Provider();
            provider2.setProName("Jules");
            provider2.setCreationDate(new Date());
            provider.add(provider1);
            provider.add(provider2);
            return provider;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    对象返回JSON

    在这里插入图片描述
    集合返回JSON

    在这里插入图片描述

    1.@JsonSerialize(include)空值不返回

    【看测试图发现没有传的值会返回null,对象中添加@JsonSerialize(),表示空值null不返回】

    实体类上添加:
    @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
    表示属性为null不返回
    
    • 1
    • 2
    • 3
    2.@JsonSerialize(using)处理前后端对状态类字段不统一,需转换

    【@JsonSerialize注解,主要用于数据转换,该注解作用在该属性的getter()方法上。】

    【1.实体类上在需要装换的字段上加上注解】

    /**
     * 文字型状态值
     */
    @JsonSerialize(using = MySerializerUtils.class)
    private int status;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    【2.负责转化的类的规则】

    public class MySerializerUtils extends JsonSerializer<Integer> {
        @Override
        public void serialize(Integer status, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
            String statusStr = "";
            switch (status) {
                case 0:
                    statusStr = "暂存";
                    break;
                case 1:
                    statusStr = "待上报";
                    break;
                case 2:
                    statusStr = "待审核";
                    break;
                case 3:
                    statusStr = "已审";
                    break;
                case 4:
                    statusStr = "退回";
                    break;
                case -1:
                    statusStr = "已删";
                    break;
                default:
                    statusStr = "状态信息不符合";
            }
            jsonGenerator.writeString(statusStr);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    http://www.qb5200.com/article/406882.html

    3.关于Date时间数据类型格式化

    时间格式化,否则是一串数字:

    • @DateTimeFormat(pattern=" ") 入参时间格式化
    • @JsonFormat(pattern=" ") 输出时间格式化
    • timezone = “GMT+8”,我们在页面显示的时间与北京时间相差8个小时,加timezone处理时差
    	//@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")  //入参不乱
    	//@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")  //返回json的时候防止时间乱
    	
    	@Setter
    	@Getter
    	
    	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") 
    	private Date creationDate; //创建时间
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    【但在项目中时间一般用String类型】

    九、视图解析器

    【在return路径的时候,我们可以省略“/”和“.jsp”,jsp文件名mv.setViewName("index") , 这就需要视图解析器的前缀后缀】
    在这里插入图片描述
    springMVC.xml中

    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
    	//前缀:jsp文件所在的路径
    	<property name="prefix" value="/WEB-INF/view/"/>
    	<property name="suffix" value=".jsp"/>
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    看图理解前缀路径如何写的
    在这里插入图片描述

    十、REST风格

    在我们访问一些网站的时候会发现,它的最后有一串数字,或者数字.html,这是如何实现的呢?

    在这里插入图片描述

    @Controller
    @RequestMapping("/provider")
    public class ProviderController {
     @RequestMapping(value = "/jules/{id}.html")
        public ModelAndView stylePage(@PathVariable("id") Integer id) {
            System.out.println("id======"+id);
            return new ModelAndView("index");
        }
    }
    
    //请求路径为:http://localhost:8080/provider/jules/11.html
    //@RequestMapping(value = "/jules/{id1}/{id}.html") 也可以传多个
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述
    【后缀显示html页面实际上是我们自己的风格,页面还是jsp而已~~】

  • 相关阅读:
    说出几条 Java 中方法重载的最佳实践
    中国的LPR改革及其意义
    常见端口及其脆弱点
    dos2unix命令
    尚硅谷大数据项目《在线教育之实时数仓》笔记004
    【循环自相关和循环谱系列7】OFDM循环自相关推导分析、时间参数估计原理仿真及某无人机实际图传信号验证(含矩形/非矩形、有无循环前缀等情况)
    大咖说·对话生态|当Confluent遇见云:实时流动的数据更有价值
    IDM(Internet Download Manager)2024中文版下载工具软件
    蓝桥杯2024年第十五届省赛
    牛客网-《刷C语言百题》第二期
  • 原文地址:https://blog.csdn.net/m0_70083523/article/details/127730146