SpringMVC——进阶

前言:请先观看SpringMVC——快速入门之后再看此篇文章,方便理解。SpringMVC——快速入门_热爱编程的申同学的博客-CSDN博客SpringMVC的概述及工作原理,开发快速入门https://blog.csdn.net/select_myname/article/details/127542903?spm=1001.2014.3001.5501

目录

1、数据绑定

1.1、绑定servlet内置对象

1.2、@PathVariable

1.3、@RequestParam

1.4、@CookieValue

1.5、POJO对象绑定参数

1.6、基本数据类型绑定

1.7、解决乱码问题

1.8、通用页面跳转

1.9、数组类型

1.10、绑定复杂类型

1.11、jsp和jstl视图解析器

2、SpringMVC的异步交互

2.1、回顾ajax

2.2、@ResponseBody

2.3、@RequestBody

3、处理静态资源

3.1、测试前端代码

3.2、web.xml配置方式(三种解决方式之一)

3.3、springmvc-servlet.xml配置文件(三种解决方式之一)

3.4、springmvc-servlet.xml配置文件简化方式(三种解决方式之一)

4、SpringMVC拦截器

4.1、拦截器概述

4.2、拦截器的实现

4.3、拦截器链

5、过滤器和拦截器的区别

5.1、Filter过滤器

5.2、Interceptor拦截器

6、RESTfull风格

6.1、什么是RESTfull风格

6.2、RESTfull与传统URL对比


1、数据绑定

1.1、绑定servlet内置对象

可以在controller控制类方法中获取request和response对象,以及session对象

@Controller
@RequestMapping("user")
//@RestController  //相当于@Controller 和 @ResponseBody
public class UserController {
    @RequestMapping("test1")
    @ResponseStatus(HttpStatus.OK)
    public void test1(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
        System.out.println(request);
        System.out.println(response);
        System.out.println(session);
    }
}

请求localhost:8080/user/test1.do路径 

SpringMVC——进阶_第1张图片

1.2、@PathVariable

@Controller
@RequestMapping("user")
//@RestController  //相当于@Controller 和 @ResponseBody
public class UserController {
    @RequestMapping("test2/{id}/{name}")
    public String test2(@PathVariable int id, @PathVariable String name) {
        ModelAndView mv = new ModelAndView();
        mv.addObject("id", id);
        mv.addObject("name", name);
        return "user";
    }
}

 将user页面存放在webapp包下,后缀为jsp文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


我是user页面

${id} ${user}

请求路径:localhost:8080/user/test2/12002/zhangsan.do 

SpringMVC——进阶_第2张图片

1.3、@RequestParam

属性名 属性值
value 参数名
required true(默认) false
defultValue 默认值,如果不给参数值,就走默认值
@Controller
@RequestMapping("user")
//@RestController  //相当于@Controller 和 @ResponseBody
public class UserController {
    @RequestMapping("test3")
    @ResponseStatus(HttpStatus.OK)
    public void test3(@RequestParam(value = "id", required = false, defaultValue = "222") int id, @RequestParam("name") String name) {
        System.out.println(id);
        System.out.println(name);
    }
}

请求路径localhost:8080/user/test3.do?name=itssl,因为id给定了默认值且为不必要参数,所以没有写id参数SpringMVC——进阶_第3张图片SpringMVC——进阶_第4张图片

1.4、@CookieValue

     /**
     * 通过后台跳转到cookie视图
     *
     * @return
     */
    @RequestMapping("toCookie")
    public String toCookie() {
        return "cookie";
    }

    /**
     * 获取cookie的值
     *
     * @param
     */
    @RequestMapping("test5")
    @ResponseStatus(HttpStatus.OK)
    public void test5(@CookieValue(value = "name", required = false) String name) {
        System.out.println("cookie的值为:" + name);
    }

cookie.jsp页面,首先先请求toCookie到此页面,然后通过页面点击a标签请求test5接口 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


测试cookie


 SpringMVC——进阶_第5张图片

点击测试cookie ,idea控制台输出

1.5、POJO对象绑定参数

创建实体类,这里使用lombok依赖进行set/get。

    
      org.projectlombok
      lombok
      1.16.18
    

user实体类 

@Data //set/get方法
@AllArgsConstructor  //有参构造
@NoArgsConstructor   //无参构造
public class User {
    private int id;
    private String name;
    private int age;
    private String address;
}

书写一个控制类,填写user对象参数,以及request对象用来把user对象放到request域中,让jsp页面进行获取数据。

 @RequestMapping("test6")
    public String test6(User user, HttpServletRequest request) {
        request.setAttribute("user", user);
        return "user";
 }

user.jsp页面 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


我是user页面

${user}

SpringMVC——进阶_第6张图片

 注意:如果请求路径中没有填写相应的实体类属性,会以各个属性类型的默认值呈现。如:int类型为0,boolean类型为false...

1.6、基本数据类型绑定

    //跳转到login页面
    @RequestMapping("toUser")
    public String toUser() {
        return "login";
    }

    @PostMapping("test8")
    @ResponseStatus(HttpStatus.OK)
    public void test8(@RequestParam("name") String name,
                      @RequestParam("age") Integer age,
                      @RequestParam("income") Integer income,
                      @RequestParam("isMarried") Boolean isMarried,
                      @RequestParam("interests") String interests) {
        System.out.println(name);
        System.out.println(age);
        System.out.println(income);
        System.out.println(isMarried);
        System.out.println(interests);
    }

login.jsp页面 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


姓名:
年龄:
收入:
结婚:
兴趣:
听歌 书法 看电影

 请求toUser接口跳转到login页面SpringMVC——进阶_第7张图片

提交表单,ieda控制台输出

SpringMVC——进阶_第8张图片

1.7、解决乱码问题

如果上面返回的数据存在乱码的话,那就是post请求乱码,在以往servlet学习中,直接对request对象进行设置utf-8就能解决,那么现在springMVC中如何解决这个问题呢?

需要在web.xml中通过过滤器来进行解决

 
    
        
        encodingFilter    
        org.springframework.web.filter.CharacterEncodingFilter  
           
            encoding  
            utf-8   
        
    

     
        encodingFilter
        /*
    

1.8、通用页面跳转

我们发现上面我们写了很多次页面跳转的方法,其实我们可以抽取统一

@Controller
@RequestMapping("toPage")
public class ToPage {
    @RequestMapping("{page}")
    public String toPage1(@PathVariable("page") String page){
        return page;
    }
}

1.9、数组类型

    @RequestMapping("test9")
    @ResponseStatus(HttpStatus.OK)
    public void test9(String[] addr) {
        for (String s : addr) {
            System.out.println(s);
        }
    }
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    数组


郑州
上海
杭州
北京
曹县

先通过通用页面跳转接口跳转到address.jsp页面 

 SpringMVC——进阶_第9张图片

选择上海和北京提交 

 

1.10、绑定复杂类型

实体类中拥有很多类型,数组、包装类、Map、List等这种复杂实体类如何接收呢?

@Data
public class UserVO {
    private String name;
    private Integer age;
    private User user;
    private List list;
    private Map map;
    private String[] addr;
}

 控制类代码

    @RequestMapping("test10")
    @ResponseStatus(HttpStatus.OK)
    public void test10(UserVO userVO) {
        System.out.println(userVO);
    }

list.jsp页面 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


姓名: 年龄:
user属性中的姓名:
user属性中的年龄:
list中第一个user对象的年龄:
list中第一个user对象的姓名:
list中第二个user对象的年龄:
list中第二个user对象的姓名:
map中第一个键值对中值user对象的年龄:
map中第一个键值对中值user对象的姓名:
map中第二个键值对中值user对象的年龄:
map中第二个键值对中值user对象的姓名:
请选择喜欢的城市: 郑州
上海
杭州
北京
曹县

SpringMVC——进阶_第10张图片

1.11、jsp和jstl视图解析器

使用jstl核心标签库需要导入依赖坐标


    javax.servlet
    jstl
    1.2

@GetMapping("test11")
    public ModelAndView test11(ModelAndView mv) {
        List list=new ArrayList<>();
        User user = new User();
        user.setId(1);
        user.setName("张三");
        user.setAge(23);
        user.setAddress("郑州");

        User user1 = new User();
        user1.setId(2);
        user1.setName("李四");
        user1.setAge(22);
        user1.setAddress("上海");

        User user2=new User();
        user2.setId(3);
        user2.setName("王五");
        user2.setAge(24);
        user2.setAddress("杭州");

        list.add(user);
        list.add(user1);
        list.add(user2);
        mv.addObject("list",list);
        mv.setViewName("list2");
        return mv;
    }
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


    Title




        
ID Name Age Address
${user.id} ${user.name} ${user.age} ${user.address}

SpringMVC——进阶_第11张图片

2、SpringMVC的异步交互

在之前我们讲的请求响应都是同步的,但是在实际开发中我们都是使用异步请求,所以下面我们使用ajax发送异步请求!

在异步请求中数据传输的格式我们都是使用josn来进行传输,速度快,小巧,使用方便!!

在响应的同时,我们也是响应json字符串,在前端解析json字符串即可!

2.1、回顾ajax

1、发送ajax请求:$.ajax() / $.get() / $.post() / $.load()

2、响应json数据:new ObjectMapper().writeValueAsString()

我们学习完SpringMVC之后,就不用像之前那么麻烦了,还要创建ObjectMapper对象来转换成josn数据进行响应。

SpringMVC已经帮我们做这些事情了。SpringMVC提供了两个注解@RequestBody和@ResponseBody实现josn数据的转换

2.2、@ResponseBody

用于将controller方法返回的对象通过转换器转换为指定的格式(通常为json)之后,写入到response对象的响应体中。

把js文件放到webapp包下的js文件夹中,下面链接即为jquery-3.4.1的文件

链接:https://pan.baidu.com/s/1IFfhWAQs023LK-_9eu0tPw 
提取码:ppdf 

创建一个html页面,发送ajax异步请求,请求控制类获取数据 



    Title


name age

控制类 

    @PostMapping("ajaxResponse")
    @ResponseBody
    public User ajaxTest(){
        User user = new User();
        user.setName("jack");
        user.setAge(99);
        return user;
    }

SpringMVC——进阶_第12张图片

2.3、@RequestBody

用于接收前端请求体中的json数据,使用@RequestBody注解就可以自动的封装指定的对象中




    
    Title
    


    

    /**
     * 接受json串
     * @param user
     */
    @PostMapping("ajaxRequest")
    public void test(@RequestBody User user){
        //User(name=jack, age=99)
        System.out.println(user);
    }

3、处理静态资源

3.1、测试前端代码

SpringMVC在默认情况下,所有的静态资源都会被拦截(js,css。html,图片、视频、音频),在web.xml文件中,我们配置的拦截路径是/ 这种形式除了jsp都会被拦截。


    springmvc
    
    /

把拦截路径设置为 / 时,会发现连html静态页面都无法访问  

对于静态资源,需要手动配置静态资源过滤。有三种形式可以选择:

3.2、web.xml配置方式(三种解决方式之一)


    springmvc
    
    /




    default
    *.jpg


    default
    *.js


    default
    *.css


    default
    *.html

3.3、springmvc-servlet.xml配置文件(三种解决方式之一)




  

3.4、springmvc-servlet.xml配置文件简化方式(三种解决方式之一)



4、SpringMVC拦截器

4.1、拦截器概述

SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。

preHandle 执行目标方法之前进行拦截; true 放行 false 拦截不放行
postHandle 在目标方法执行之后,进行增强
afterCompletion 在视图渲染完毕后,进行资源释放

4.2、拦截器的实现

自定义拦截器:使用自定义拦截器,SpringMVC提供了 HandlerInterceptor 接口。我们重写 preHandlepostHandleafterCompletion 这三个方法!

创建一个interceptor包,在包中创建一个类去实现拦截器接口HandlerInterceptor

SpringMVC——进阶_第13张图片

public class MyInterceptor implements HandlerInterceptor {
    //方法执行之前进行拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("执行方法前进行拦截1111111111");
        //放行
        return true;
    }
    //方法执行之后,进行增强
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("目标方法执行之后,进行增强1111111111");
    }
    //视图渲染完毕后,进行资源释放
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("在视图渲染完毕后,进行资源释放11111111111");
    }
}

配置springmvc-config.xml文件 





    
    
    
    
         
             
             
             
             
         
    

    
    
        
            
            
            
        
    


    
    
        
            
            
            
            
            
            
            
        
    



4.3、拦截器链

多个拦截器,拦截同一个目标资源,形成一个链条,就是拦截器链!

拦截方法的执行顺序:先进先出

拦截器的执行顺序

跟springmvc配置文件中的配置顺序有关系

mvc:interceptor 谁先配置谁先执行!

SpringMVC——进阶_第14张图片

再创建一个类实现拦截器接口 

SpringMVC——进阶_第15张图片

public class MyInterceptor2 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("执行方法前进行拦截22222222222");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("目标方法执行之后,进行增强22222222");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("在视图渲染完毕后,进行资源释放222222222");
    }
}

    
        
            
            
         
            
            
        
    

    
    
        
            
                   
            
            
        
    

SpringMVC——进阶_第16张图片

5、过滤器和拦截器的区别

5.1、Filter过滤器

1、实现Filter接口
2、通过web.xml或注解方式完成配置
3、重写的方法 init  doFilter   destroy
4、过滤器过滤的是所有请求,不分controller和页面

5.2、Interceptor拦截器

1、实现HandlerInterceptor接口
2、需要在springmvc核心配置文件中配置

3、重写的方法
preHandle  调用handler方法之前执行,true表示放行,false表示不放行
postHandle  调用handler方法之后执行
afterCompletion  视图渲染之后执行
4、只拦截controller请求    

6、RESTfull风格

6.1、什么是RESTfull风格

REST(英文:Representational State Transfer,简称REST,意思:表述性状态转换,描述了一个架构样式的网络系统,比如web应用)。

Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

应用场景:前后端分离开发的架构中

6.2、RESTfull与传统URL对比

传统url

请求路径处理名字 表明 是做什么操作

请求路径时 也告 请求方式 (addUser + post) (deleteUserById + delete)

前端 后台 描述
http://localhost:8080/user/findAllUsers @RequestMapping(/user/findAllUsers) public List findAllUsers() 查询所有用户
http://localhost:8080/user/findUserById?id=1 @RequestMapping(/user/findUserById) public User findUserById(int id) 查询指定用户
http://localhost:8080/user/addUser @RequestMapping(/user/addUser) public void addUser(User user) 添加用户
http://localhost:8080/user/updateUser @RequestMapping(/user/updateUser) public void updateUser(User user) 修改用户
http://localhost:8080/user/deleteUserById?id=1 @RequestMapping(/user/deleteUserById) public User deleteUserById(int id) 删除用户

RESTfull风格

Restful风格的请求是使用==“url+请求方式”(名饲+动词)==表示一次请求目的的,HTTP 协议里面四个表示操作方式的动词如下:

请求方式 描述
GET 用于获取资源
POST 用于新建资源
PUT 用于更新资源
DELETE 用于删除资源
前端 后台 描述
http://localhost:8080/user/ @RequestMapping(/user,method=GET) public List findAllUsers() GET查询所有用户
http://localhost:8080/user/1 @RequestMapping(/user/{id},method=GET) public User findUserById(@PathVariable int id) GET查询id为1用户
http://localhost:8080/user/ @RequestMapping(/user,method=POST) public void addUser(User user) POST添加用户
http://localhost:8080/user/1 @RequestMapping(/user/{id},method=PUT) public void updateUser(@PathVariable int id) PUT修改id为1用户
http://localhost:8080/user/1 @RequestMapping(/user/{id},method=DELETE) public User deleteUserById(@PathVariable int id) DELETE删除id为1的用户

上述url地址/user/1中的1就是要获得的请求参数,在SpringMVC中可以使用占位符进行参数绑定。RequestMapping中/user/1可以写成/user/{id},占位符{id}对应的就是1的值。在业务方法中我们可以使用@PathVariable注解进行占位符的匹配获取工作。

@RequestMapping("user")
@RestController  //  @Controller + @ResponseBody
public class RestFulController {

    /**
     * 查询所有  get
     */
    @GetMapping("users")
    public String findAll(){
        return "查询所有";
    }

    /**
     * 指定查询  get
     * @param id
     * @return
     */
    @GetMapping("users/{id}")
    public String findUserByid(@PathVariable Integer id){
        return "根据id进行查询,id为:"+id;
    }

    /**
     * 添加用户  post
     * @return
     */
    @PostMapping("users")
    public String addUser(){
        return "添加用户";
    }

    /**
     * 修改用户 put
     * @return
     */
    @PutMapping("users/{id}")
    public String updateUser(@PathVariable Integer id){
        return "修改用户,id为:"+id;
    }

    /**
     * 删除用户 delete
     */
    @DeleteMapping("users/{id}")
    public String deleteUserById(@PathVariable("id") Integer id){
        return "删除用户,id为:"+id;
    }
}

你可能感兴趣的:(Spring,servlet,java,spring)