【SSM基础知识8】SpringMVC概述

SpringMVC是一个基于Spring开发的MVC轻量级框架,Spring3.0后发布的组件,SpringMVC和Spring可以无缝整合,使用DispatcherServlet作为前端控制器,且内部提供了处理器映射器、处理器适配器、视图解析器等组件,可以简化JavaBean封装,Json转化、文件上传等操作。

web层MVC框架思想与设计思路

- MVC框架思想及其设计思路

原始Javaweb开发中,Servlet充当Controller的角色,Jsp充当View角色,JavaBean充当模型角色,后期Aiax异步流行后,在加上现在前后端分离开发模式成熟后,View就被原始Html+Vue替代。原始Javaweb开发中,Service充当Controller有很多弊端,显而易见的有如下几个:

Servlet作为Controller的问题 

1.每个业务功能请求都对应一个Servlet 

2.解决思路和方案根据业务模块去划分Controller ,每个Servlet的业务操作太繁琐 

解决思路和方案: 将通用的行为,功能进行抽取封装

Servlet获得Spring容器的组件只能通过客户端代码去获取,不能优雅的整合

解决思路和方案: 通过Spring的扩展点,去封装一个框架,从原有的Servlet完全接手过来web层的业务

SpringMVC简介

1.导入spring-mvc坐标

2.配置前端控制器DispatcherServlet

3.编写Controller,配置映射路径,并交给SpringMVC容器管理

<dependency>

    <groupId>org.springframework</groupId>

    <artifactId>spring-webmvc</artifactId>

    <version>5.3.7</version> 

</dependency>

webapp包下WEB-INF下web.xml

<!-配置DispatcherServlet-->

<servlet>

 <servlet-name> DispatcherServlet </servlet-name>

 <servlet-class>org.springframework.web.servletDispatcherServlet </servlet-class>

</servlet>

<servlet-mapping>

    <servlet-name>DispatcherServlet</servlet-name>

    <url-pattern>/</url-pattern>

</ servlet-mapping>
 @Controller

public class QuickController {

     @RequestMapping("/show")

     public void show(){

         System.out.println("show running....");

     }

}

spring-mvc.xml

<!--组件扫描-->

<context:component-scan base-package="com.ting.controller">

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

version="3.1">


<!--配置DispatcherServlet-->

<servlet>

    <servlet-name>DispatcherServlet</servlet-name>

    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>


    <init-param>

        <param-name>contextConfigLocation</param-name>

        <param-value>classpath:spring-mvc.xml</param-value>

    </init-param>


    <load-on-startup>2</load-on-startup>

</servlet>

<servlet-mapping>

    <servlet-name>DispatcherServlet</servlet-name>

    <url-pattern>/</url-pattern>

</servlet-mapping>

</web-app>

  页面报500--视图指定

index.jsp

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

<html>

<head>

<title>Title</title>

</head>

<body>

<hl>HelloSprinqMVC!</h1>

</body>

</html>
@Controller

public class QuickController {

@RequestMapping("/show")

public String show(){

System.out.println("show running....");

return "/index.jsp";

}

controller中直接注入spring维护的bean

public interface QuickService{}
 @Service

 public class QuickServiceImpl implements QuickService {}

applicationContext.xml

 <!--组件扫描--> 

<context:component-scan base-package="com.ting.service"/>

web.xml

 <!--配置ContextLoaderListener-->

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>classpath:applicationContext.xml</param-value> 

</context-param>

<listener>

    <listener-class>orq.sprinqframework.web.context.ContextLoaderListener</listener-class>

</listener> 
@Controller

public class QuickController {

//直接注入Service进行使用

    @Autowired

    private QuickService quickService;

    @RequestMapping("/show")

    public String show(){

        System.out.println("show running...."+quickService); 

        return "/index.jsp";

    }

}

SpringMVC关键组件浅析

核心功能类,一般称为组件。当请求到达服务器时,是哪个组件接收的请求,是哪个组件帮我们找到的Controller,是哪个组件帮我们调用的方法,又是哪个组件最终解析的视图

组件:处理器映射器:HandlerMapping 匹配映射路径对应的Handler,返回可执行的处理器链对象HandlerExecutionChain对象 组件组件RequestMappingHandlerMapping

组件:处理器适配器:HandlerAdapter 

匹配HandlerExecutionChain对应的适配器进行处理器调用,返回视图模型对象 组件:RequestMappingHandlerAdapter

组件:视图解析器:ViewResolver 

对视图模型对象进行解析 InternalResourceViewResolver

SpringMVC的请求处理

 请求映射路径的配置

配置映射路径,映射器处理器才能找到Controller的方法资源,目前主流映射路径配置方式就是@RequestMapping

@RequestMapping 设置控制器方法的访问资源路径,可以接收任何请求 用在方法和类上

@GetMapping 设置控制器方法的访问资源路径,可以接收GET请求 用在方法和类上

@PostMapping 设置控制器方法的访问资源路径,可以接收POST请求 用在方法和类上

请求数据的接收

接收普通请求数据,当客户端提交的数据是普通键值对形式时,直接使用同名形参接收即可

username=haohao&age=35

@GetMapping("/show")

public String show( String username,int age){

    System.out.println(username+"="+age);

    return "/index.jsp";

}
@Controller

public class ParamController {

    //http://localhost/paraml?username=zhangsan&age=18

    @GetMapping("/param2")

    public String param2(@RequestParam("username") String name, int age){

        System.out.println(name+"===="+age);

        return "/index.jsp";

    }

}
@Controller

public class ParamController{

    //http://localhost/param3?hobby=zg&hobby=pq&hobby=tq

    @GetMapping("/param3")

    public Stringparam3(String[] hobby){

        for (String s :hobby) {

        System.out.println(s);

        }

        return"/index.jsp";

    }

}
@Controller

public class ParamController{

    //http://localhost/param4?hobby=zq&hobby=pg&hobby=tq

    @GetMapping("/param4")

    public string param4(@RequestParam List<String> hobby){

        for (String s :hobby) {}
    
        System.out.println(s);

    }

    return "/index.isp";

}



@Controller

public class ParamController {

//http://localhost/param5?username-=zhangsan&age=18

    @GetMapping("/param5")

    public String param5(@RequestParam Map<String,String> map){

     map.forEach((k,v)->{

           System.out.println(k+"==>"+v); 

     });

     return "/index.jsp";

}


 

接收实体JavaBean属性数据,单个JavaBean数据:提交的参数名称只要与Java的属性名一致,就可以进行自动封装

username=haohao&age=35&hobbies=eat&hobbies=sleep

public class User {

    private String username;

    private Integer age;

    private String[] hobbies;

    private Date birthday;

    private Address address;

    //...省略get和set方法..

}
@GetMapping("/show")

public String show(User user){

    System.out.println(user);
    
    return "/index.jsp";

 }
//http://localhost/param6?username=zhangsan&age=18&hobbies=zq&hobbies=pq&birthday=2018/11/11&address.city=tj

    @GetMapping("/param6")

    public String param6(User user){

    System.out.println(user);
    
    return "/index.jsp";

}
//http://localhost/param7

@PostMapping("/param7")

public Stringparam7(@RequestBody String body){

    System.out.println(body);

    return "/index.jsp"; 

}

使用Json工具(jackson)将Json格式的字符串转化为JavaBean进行操作

<dependency>

    <groupid>com.fasterxml.jackson.core</groupId>
    
    <artifactid>jackson-databind</artifactId>

    <version>2.9.0</version>

</dependency>
@PostMapping("/show")

public String show ( @RequestBody String body) throws IOException {

    System.out.println(body);

}

//获得ObjectMapper

ObjectMapper objectMapper =new ObjectMapper();

//将json格式字符串转化成指定的User

User user=objectMapper.readValue(body,User.class);

System.out.println(user);

return "/index.jsp";

接收Json数据格式数据,Json数据都是以请求体的方式提交的,且不是原始的键值对格式的,所以我们要使用@RequestBody注解整体接收该数据。

{

"username":"haohao",

"age":18,

"hobbies":["eat","sleep"],

'birthday":"1986-01-01",

"address":[

"city":"tj",

"area":"binhai"

}

}
@PostMapping("/show6")

public String show6(@RequestBody String body){

    System.out.println(body);

    return "/index.jsp";

}

配置RequestMappingHandlerAdapter,指定消息转换器,就不用手动转换json格式字符串了

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> 

   <property name="messageConverters">

      <list>

         <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>

       </list>

    </property>

</bean>
@PostMapping("/show")

public String show(@RequestBody User user){

    System.out.println(user);

    return "/index.jsp";

}

接收Restful风格数据

什么是Restful风格?

Restful(Representational State Transter)美象化状太转变(表述性状态转变),在2000年被提出,基于HTTPURIxml、JSON等标准和协议,支持轻量级、跨平台、跨语言的架构设计。是Web服务的一种新网络应用程序的设计风格和开发方式。

1.用URI表示某个模块资源,资源名称为名词;

用户模块 user0 http://localhost/user

商品模块product http://localhost/product

账户模块 account http://localhost/account

日志模块 log http://localhost/log #

2.用请求方式表示模块具体业务动作,例如:GET表示查询、POST表示插入、PUT表示更新、DELETE表示删除

3.用HTTP响应状态码表示结果,国内常用的响应包括三部分:状态码、状态信息、响应数据

{

"code":200,

"message":"成功”,

"data":{

"username":"haohao",

"age":18

}
{

"code":300,

"message";"执行错误”,

'data":"",

}

接收Restful风格数据,Restful请求数据一般会在URL地址上携带,可以使用注解@PathVariable(占位符参数名称)

//http://localhost/user/100

@PostMapping("/user/{id}")

public String findUserById(@PathVariable("id")Integer id){

    System.out.println(id);

    return"/index.jsp";

}

请求URL资源地址包含多个参数情况

//http://localhost/user/haohao/18

@PostMapping("/user/{username}/{age}")

public String findUserByUsernameAndAge(@PathVariable("username")String username,@PathVariable("age") Integer age){

    System.out.printin(username+"=="rage);

    return"/index.jsp";

}

//http://localhost/user/100=>根据id查询

@GetMapping("/user/{xxx}")

public String findUserById(@PathVariable("xxx") int id){

    System.out.println("id==>"+id);

    return "/index.jsp";

}



接收文件上传的数据,文件上传的表单需要一定的要求,如下:

1.表单的提交方式必须是POST

2.表单的enctype属性必须是multipart/form-data

3.文件上传项需要有name属性

<form action="" enctype="multipart/form-data" method="post">

    <input type="file"name="myFile">

</form>

服务器端,由于映射器适配器需要文件上传解析器,而该解析器默认未被注册,所以手动注册

<!--配置文件上传解析器,注意:id的名字是固定写法-->

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

    <property name="defaultEncoding" value="UTF-8"/><!--文件的编码格式 默认是ISO8859-1-->

    <property name="maxUploadSizePerFile" value="1048576"/><!--上传的每个文件限制的大小 单位字节-->

    <property name="maxUploadsize" value="3145728"/><!--上传文件的总大小-->

    <property name="maxInMemorysize" value="1048576/><!--上传文件的缓存大小-->

</bean>

而CommonsMultipartResolver底层使用的Apache的是Common-fileuplad等工具API进行的文件上传

<dependency>

    <groupId>commons-fileupload</groupId>

    <artifactid>commons-fileupload</artifactId

    <version>1.4</version>

</dependency>
 @PostMapping("/param10")

 public String param10(@RequestBody MultipartFile myFile) throws IOException{

     System.out.println(myFile);

     return "/index.jsp";
    
}
@PostMapping("/param10")

public String param10(@RequestBody MultipartFile myFile) throws IOException{

     System.out.println(myFile);

    //将上传的文件进行保存

    //1、获得当前上传的文件的输入流

    Inputstream inputStream=myFile.getInputstream();

    //2、获得上传文件位置的输出流

    OutputStream outputStream=new FileOutputStream("c:\\Users\\haohao\\"+myFile.getOriginalFilename());

    //3、执行文件拷贝

    IOUtils.copy(inputStream,outputStream)

    return"/index.jsp";

    //4、关闭流资源

    inputStream.close();

    outputStream.close();

    return "/index.jsp";

}

获得客户端携带的Cookie数据

@GetMapping("/cookies")

public String cookies(@CookieValue(value “JSESSIONID",defaultValue ="") String jsessionid){

    System.out.println(jsessionid);

    return "/index.jsp";

}

获得转发Request域中数据,在进行资源之间转发时,有时需要将一些参数存储到request域中携带给下一个资源

@GetMapping("/request1")

public String request1(HttpServletRequest request){

    //存储数据

    request.setAttribute("username","haohao");

    return "/request2";

}

@GetMapping("/request2")

public String request2(@RequestAttribute("username") String username) {

    System.out.printin(username);

    return "/index,jsp";

}

- 请求静态资源

静态资源请求的三种解决方案:

第一种方案,可以再次激活Tomcat的DefaultServlet,Servlet的url-oattern的匹配优先级是:精确匹配>目录匹配>扩展名匹配>缺省匹配,所以可以指定某个目录下或某个扩展名的资源使用DefaultServlet进行解析:

<servlet-mapping>

    <servlet-name>default</servlet-name>

    <url-pattern>/img/*</url-pattern>

</servlet-mapping>

<servlet-mapping>

    <servlet-name>default</servlet-name>

    <url-pattern>*.html</url-pattern>

</servlet-mapping>

第二种方式,在spring-mvc.xml中去配置静态资源映射,匹配映射路径的请求到指定的位置去匹配资源

<!-- mapping是映射资源路径,location是对应资源所在的位置--!>


<mvc:resources location="/img/" mapping="/img/**"/>   

<mvc:resources location="/js/" mapping="/js/**"/>  
  

<mvc:resources location="/css/" mapping="/css/**"/>  

第三种方式,在spring-mvc.xml中去配置<mvc:default-servlet-handler>,该方式是注册了一个DefaultServletHttpRequestHandler 处理器,静态资源的访问都由该处理器去处理,这也是开发中使用最多的

<mvc:default-servlet-handler/>

-注解驱动·<mvc:annotation-driven>标签

mvc的注解驱动内部会帮我们注册RequestMappingHandlerMapping、注册

RequestMappingHandlerAdapter并注入Json消息转换器等,上述配置就可以简化成如下:

<!--mvc注解驱动-->

<mvc:annotation-driven/>

<!--配置DefaultServletHttpRequestHandler-->

<mvc:default-servlet-handler/>

PS:<mvc:annotation-driven>标签在不同的版本中,帮我们注册的组件不同,Spring 3.0.X版本注册是DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter,由于框架的发展,从Spring 3.1.X开始注册组件变为RequestMappingHandlerMapping和RequestMappingHandlerAdapter

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值