[SpringMVC 02] 注解开发 RestFul风格 转发重定向

SpringMVC 02


1. 注解开发

新建项目

  1. web.xml中配置DispatcherServlet:

    <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>
    
  2. 写springmvc-servlet.xml的spring配置文件

    (添加扫描包,过滤器,之前配置的Mapping和Adapter被取代,resolve依然需要)

    注意前缀prefix的路径!!!, 最后面有一个/

    <?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.roy.controller"/>
    <!--    自动过滤.js,.jsp,.css,.mp3等静态资源,让其不参与视图的前后缀-->
        <mvc:default-servlet-handler/>
    <!--    自动配置Mapping和Adapter-->
        <mvc:annotation-driven/>
    <!--    配置视图解析-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    </beans>
    

以后<mvc的自动配置和自动过滤自己产生,不需要写

  1. 写Controller(用注解写)

    被这个注解所注解的类中的所有方法,如果返回值是String,并且有具体的页面可以跳转,就会被解析器解析

    注意传输的是Model!!! 不是ModelAndView

    @RequestMapping注解用于映射url到一个控制器上(类),或者一个控制器的方法上(可以嵌套使用,即

    /类上的路径/方法上的路径

    @Controller    //实现Controller注解,成为控制器,可以返回mv对象
    public class HelloController {
        @RequestMapping("/hello")//这里指,访问的url需要添加的地址
        public String hello(Model model){
            model.addAttribute("msg", "Hello");
            return "hello"; //会被视图解析器处理
        }
    }
    
  2. 前端取参数

2. RestFul风格

是一个资源定位、资源操作的风格,不是标准也不是协议, 更简洁比较容易实现缓存等机制。(都是/, 不需要?传参,&拼接这些)

1. 实现方式:

重点:

之前使用URL: localhost:8080?a=1&b=2

现在使用URL: localhost:8080/1/2

在函数参数中加注解@PathVariable, 在@RequestMapping中添加路径后面的参数

@Controller
public class HelloController {
@RequestMapping("/add/{a}/{b}")
    public String test(@PathVariable int a, @PathVariable int b, Model model){
        int res = a+ b;
        model.addAttribute("msg", res);
        return "test";
    }
}

前端页面:test.jsp

${msg}

2. 在Restful风格下相同的URL走不同的方法

注解@RequestMapping中有参数method, 可以设置提交请求的方法(查看源码), 是一个枚举类,默认为get方法

@RequestMapping(value="/add/{a}/{b}", method=RequestMethod.GET)

或者直接写

@GetMapping//去源码里找
或
@PostMapping
或
@PutMapping//等

如果写两个函数有相同的路径,但提交方式不同,默认使用get,如果前端指定使用post则用post提交,但url是相同的

3. 转发与重定向

WEB-INF中的资源不能被直接访问(全路径)或者重定向(Controller中重定向)访问,只能在Controller的转发中访问

当配置了视图解析器:

默认走转发,通过视图解析器匹配视图来访问

@RequestMapping("/t1")
public String test2(Model model){
    model.addAttribute("msg", "HelloDispatcher");
    return "test2";
}

当使用forward关键字: 不通过视图解析器,直接使用全路径转发

return "forward:/WEB-INF/jsp/test2.jsp";

当使用redirect关键字:不通过视图解析器,进行重定向

return "redirect:/index.jsp";

4. 接受请求参数及数据回显

1. 前端提交的数据名与参数名名称一致:

前端提交:

http://localhost:8080/t1?name=Roy

后端处理:

@RequestMapping("/t1")
public String test2( String name, Model model){
    model.addAttribute("msg", name);
    return "test2";
}

2. 前端提交的变量名与参数名不一致:

前端提交:

http://localhost:8080/t1/username=Roy

后端处理:添加注解@RequestParam("username")

@RequestMapping("/t1")
public String test2(@RequestParam("username") String name, Model model){
    model.addAttribute("msg", name);
    return "test2";
}

3. 提交的是一个对象

实体类User

public class User{
    private int id;
    private int age;
    private String name;
    get/set/constructor/toString
}

提交:

http://localhost:8080/t1/user?id=1&age=15&name=Roy

后端处理:

1.如果传入User,匹配User对象中的字段名,如果一致则传入数据;如果有一个字段名username和name不一致,则此值为空

返回值分别为:

User{id=1, age=3, name='Roy'} 一致

User{id=1, age=3, name=null} 不一致

@RequestMapping("/t1")
public String test2(User user, Model model){
    model.addAttribute("msg", user.toString());
    return "test2";
}

4. 数据回传前端

  1. ModelAndView
  2. Model
  3. ModelMap

Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解;
ModelMap 继承了 LinkedMap,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;
ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。

5. 乱码问题

  1. 可以自己写filter过滤器(参考JavaWeb)

  2. 使用springMVC的过滤器

    在web.xml中配置完DispatcherServlet之后,再配置一个过滤器:

    <filter>
    	<filter-name>encoding</filter-name>
    	<filter-class>org.springframework.web.filter.CharacterEncodingFilter
    	<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>
    

    注意:url-pattern一定要是/*

  3. 再tomcat中可配置:(不用这个)

<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"/>
posted @ 2022-01-06 22:08  Roy2048  阅读(70)  评论(0)    收藏  举报