SpringMVC项目搭建

SpringMVC

一. web.xml与springMVC.xml

web.xml是整个项目的配置文件,它用来搭配tomcat等容器食用。

springMVC.xml是springMVC框架的配置文件。spring框架的作用是IoC和AOP,那么springMVC就是以spring为基础,加入对于MVC功能的支持。springMVC是集成了一些现成的类,如分发器,适配器等,作为一个新的子框架运行。

二. step by step搭建

使用Maven构建,首先要加入spring和springMVC依赖依赖:

<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.1.10.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.1.10.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.1.10.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.1.10.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>5.1.10.RELEASE</version>
    </dependency>

1. 容器部分

对于一个web项目,其本质就是一个又一个的http请求。而我们所要做的就是,当给定一个url能给客户返回一个他们想要的资源。

web容器为我们做的是,当请求来到了HTTP服务器,服务器会转交给Web容器,此时容器会创建一个代表当前的请求的 HttpServletRequest 对象,并将请求相关信息设置给该对象。同样也会创建一个相应的对象 HttpServletResponse,作为之后要对客户端进行响应的 Java 对象。

正常来说,我们会使用<servlet>和<servlet-mapping>标签告诉容器什么样的路径匹配到哪个servlet。每个servlet都会直接写成java文件进行声明。

然而现在我们有了springMVC,我们要使用spring容器来管理servlet:

配置一个DispatcherServlet,这个类由springMVC框架提供,还要使用init-param将参数指向配置springMVC的xml文件。init-param是用来定义servlet范围内的参数的。

<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*:springMVCContext.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

有了这个配置后,web容器在接收到请求后,就会将其传递给spring容器中的DispatcherServlet对象,进而,会引发一系列的处理。

2. springMVC部分

前面已经说到请求已经通过web容器传递给DispatcherServlet对象了。下面就具体说说springMVC是如何进行处理的。

20200608144529177.png" alt="image-20200608144529177" style="zoom:50%;" />

A. 获取handler对象

接收到请求后,DispatcherServlet从容器中取出所有 HandlerMapping 的实例并遍历,其最终。目的是找到可以处理请求到Handler

因此,我们需要在springcontext.xml中配置要使用的HandlerMapping实例。

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

这相当于是告诉spring容器实例化一个RequestMappingHandlerMapping对象(这个类实现了HandlerMapping接口)。

对于RequestMappingHandlerMapping这个对象,会将请求map到controller的方法。(而有一些HandlerMapping对象会将请求map到一个controller)。

在找到对应的handler(执行程序)后,再加上HandlerInterceptor(拦截器)形成HandlerExecutionChain返回给DispatcherServlet对象。

[有关更多的HandlerMapping具体详见:https://www.cnblogs.com/tengyunhao/p/7658952.html]

[了解核心流程源码看这个:https://blog.csdn.net/hong10086/article/details/88715960]

B. 执行handler处理方法

通过职责链——HandlerExecutionChain,分发Servlet就可以获得最后能处理请求的Handler对象。然而,这个方法不能直接用,会有一个handlerApdater适配器来操作Handler对象,比如获取入参传入Handler方法。

handlerApdater同样需要在springcontect.xml中进行声明,由spring容器进行管理。

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

在处理结束后,MVC中的C就完成了。通过handler处理方法可以返回一个对象ModelAndView。而接下来也会进入view的生成部分。

不过,在此之前,需要看一眼这段流程中的demo。

这整个流程中,我们需要编写的只涉及两个方面,一个是处理器,一个是拦截器。

Handler编写:

在Controller中, @RequestMapping使HanlerMapping能够通过请求找到这个方法。

@Controller本质上是一种@Component。在spring.xml中配置<context:component-scan base-package="com.etc.web" />对包内容进行扫描,即可用spring容器管理该对象。

@Controller
public class AController {@RequestParam("ename") 

    @RequestMapping("/hello")
    public ModelAndView hello(@RequestParam("ename") String name){
				//...
    }
}
拦截器编写:

[最简单的拦截器编写在这里:https://my.oschina.net/fengshuzi/blog/364397]

拦截器和过滤器容易分不清,简单来说,过滤器是一种特殊的servlet,其使用用在web容器中的。而过滤器是基于spring的AOP原理,切面编程,动态拦截,其拦截目标是controller的方法。

[过滤器和拦截器的区别:https://blog.csdn.net/nizhengjia888/article/details/86605243]

在这里插入图片描述

web容器启动时,就会加载过滤器,而拦截器只会在url申请发生时进行拦截。

C. 生成视图1——ModelAndView

在上一步中,handler方法返回了一个对象叫做ModelAndView。这个对象并不是真正的视图,它是一种逻辑视图。接下来由ViewResolver和View来生成真正的视图。

ViewResolver就会把该逻辑视图名称解析为真正的视图View对象。View是真正进行视图渲染,把结果返回给浏览器。

ViewResolver允许定义前缀后缀,为ModelAndView返回的viewName拼接url。同样,要把这个对象加入spring容器中进行管理;

<!--   视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

当分发Servlet收到返回的ModelAndView时候,就会遍历视图解析器实例,找到适合的viewResolver,来获取视图。最后返回视图并进行渲染。

@RequestMapping("/hello")
    public ModelAndView hello(@RequestParam("ename") String name){

        System.out.println(name);

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("hello");//寻找“/hello.jsp”
        modelAndView.addObject("message",name);
        return modelAndView;
    }

hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>hello</title>
</head>
<body>
    <% // request作用域获取model
        String msg = request.getAttribute("message").toString();
        out.print(msg);
    %>
</body>
</html>

渲染过程就是hello.jsp转换为浏览器可以认识的html模样。

D. 生成视图2——返回json

虽然正儿八经的叫springMVC模式,但是如果一个请求想要返回的不是view,而仅仅是一个json对象呢?

Controler配置

@RestController
public class ReController {

    @RequestMapping("api/all")
    public CodeMessage fetchAll(){
        CodeMessage codeMessage = new CodeMessage();
        codeMessage.setCode("200");

        List<Item> lists = new ArrayList<>();
        Item item = new Item();
        item.setId(6);

        codeMessage.setData(lists);

        return codeMessage;
    }
}

但是!没找到合适的视图解析器!!待补充!

于是暂时替换为:

		@RequestMapping("api/all")
    public String fetchAll(){
        CodeMessage codeMessage = new CodeMessage();
        codeMessage.setCode("200");

        ....
				
        //target为要传回去的数据对象
        codeMessage.setData(target);

        // java对象直接转换字符
        ObjectMapper om = new ObjectMapper();

        String result = null;
        try {
            result = om.writeValueAsString(codeMessage);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return result;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值