Spring MVC的控制器的开发流程

调度器 org.springframework.web.servlet.DispatcherServlet

回顾接口ServletRequest中的方法getRequestDispatcher

javax.servlet
Interface ServletRequest

All Known Subinterfaces:

HttpServletRequest

 RequestDispatcher

getRequestDispatcher(java.lang.String path)
Returns a RequestDispatcher object that acts as a wrapper for the resource located at the given path.

该方法的含义是,如果一个ServletA的doGet方法中,有request.getRequestDispatcher(“/目标资源URI”);其中的URI可以是一个Servlet也可以是jsp。代表要把request对象转发给目标资源。注意路径是一个web应用下的绝对路径,因为请求转发只能转给本web应用下的其他路径。

这里的Dispatcher称为调度器,用于转发请求。那么Spring MVC的核心控制器也是这个作用。把请求转发给本web应用下的不同的Servlet,去完成不同的工作。

 

org.springframework.web.servlet.HandlerMapping

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/HandlerExecutionChain.html

该接口中只有一个方法:

HandlerExecutionChain

getHandler(HttpServletRequest request)

Return a handler and any interceptors for this request.

 

传入一个request对象,返回一个 HandlerExecutionChain  处理执行链对象。

在Spring MVC里,HandlerMapping主要做的是:

  1. Spring MVC启动时会对servlet包下控制器类中带@Controller(“XXX”)的注解进行解析,生成对应URI和请求的映射关系HandlerMapping对象,并注册对应的方法。
  2. 当请求来到时,Spring会对request请求中的URI进行截取,并找到对应的HandlerMapping,然后组织得到一个执行链。

 

HandlerMapping 通过 按需加入多个拦截器和1个控制器,形成一个执行链。

org.springframework.web.servlet.HandlerExecutionChain

该类是一个处理执行链(责任链模式),下面是它的示意图:把拦截器想成函数。

需要注意的就是,上面的图,是在每个拦截器中进行调用下一个拦截器的过程。

另外注意,从哪里调用,就返回到哪里。

这也就是杨开振书上的例子

执行顺序:(拦截器 本身无业务)

拦截器3 的before方法

拦截器2 的before方法

拦截器1 的before方法

原资源的执行

拦截器1 的after方法

拦截器2 的after方法

拦截器3 的after方法

 

RequestMappingHandlerAdapter

Spring会根据request请求的类型(request、include、forward 等类型)找到对应的RequestMappingHandlerAdapter,然后通过它去执行 HandlerExecutionChain的内容,执行的结果作为返回值,返回一个视图页面。

 

InternalResourceViewResolver

视图解析器InternalResourceViewResolver,用于配置DispatcherServlet调度器最终返回的视图URI。

包括,前缀、后缀、文件名。

 

Spring MVC开发流程

Spring MVC通过扫描控制器的注解@Controller标注;

通过@RequestMapping(“\URI”)注解标注在类或方法上,Spring MVC就可以知道注解中的URI和哪个类(或方法)作为一个处理请求的处理器。

 

关于拦截器,是Spring MVC在解析@RequestMapping时,会按需要加入拦截器,从而组成一个多个拦截器和一个控制器的形式,存放到一个HandlerMapping中,进而形成一个执行链。

 

当请求来临时,Spring MVC通过请求中的信息找到对应的HandlerMapping,进而找到对应的拦截器和控制器去运行。

@RequestMapping的配置

@RequestMapping(value = “/index2”, method = RequestMethod.GET)

public  ModelAndView  index2(){

 

  ModelAndView  mv = new  ModelAndView();

  mv.setViewName(“index”);

  return  mv;

}

 

控制器的开发过程

一般分为3步

获取request请求参数

不建议在注解@RequestMapping的方法的参数中,使用Servlet容器给与的API,比如不建议下面的写法:

这样写,使用了原生API中的 HttpSession和HttpServletRequest,也就和Tomcat这种特定容器关联了。不利于扩展和测试。

Spring MVC可以通过更多的注解来获取请求参数,比如参数注解@RequestParam(“  ”)

以获取请求参数id为例:Spring MVC可以这么写控制器

@RequestMapping(value=”/index2”, method=RequestMethod.GET)

public  ModelAndView index2(@RequestParam(“id”)  Long  id ){

   System.out.println(“param[id]=”+id);

   ModelAndView  mv = new ModelAndView();

   mv.setViewName(“index”);

   return  mv;

 

}

 

注意,这里参数是Long型的,是在进入index2方法之前,先有如下转换:

String  str = request.getParameter(“id”);

Long  id = Long.parseLong(str);

 

获取session中的参数

假如登录系统已经在Session中设置了userName这个域对象,如何在控制器中进行获取?

使用注解@SessionAtrribute去从Session中获取对应的数据,例如:某个控制器类中的方法的写法

 

@RequestMapping(value=”/index3”, method=RequestMethod.GET)

public  ModelAndView index3(@SessionAttribute(“userName”)  String   userName ){

   System.out.println(“session[userName]=”+ userName);

   ModelAndView  mv = new ModelAndView();

   mv.setViewName(“index”);

   return  mv;

 

}

 

处理业务逻辑(数据模型组件) 【控制器的写法】

以上的业务逻辑,是简单的打印出 request请求、session域对象中的参数

但其实更多的Servlet的业务是进行Service层中的方法的调用。

比如,有一个Spring MVC的控制器 RoleController,在其中去注入Spring IoC容器中已经存在的业务层类RoleService,并RoleService类中有一个查询的业务方法getRole(long  id ) ;

Spring MVC中我们要做的是把这个RoleService类中的业务方法getRole(long  id ) 在控制器中进行@RequestMapping(value= ”/getRole”的注入。

下面是控制器的写法

@Controller

@RequestMapping(“/role”)    //把RoleController控制器 与 浏览器请求的URI  “/role/*****”映射在一起

public class RoleController{

       @Autowired  //把Service层的一个类作为属性注入Spring IoC

       Private RoleServiceroleService = null ;

 

@RequestMapping(value= ”/getRole”, method=”RequestMethod.GET”)

//把该方法 与 浏览器请求的/role/getRole.do”映射在一起,但要注意,后缀的匹配是在web.xml中配置的Spring MVC的调度器DispatcherServlet的拦截中配置的

public  ModelAndView  getRole(@RequestParam(“id”)   Long  id)

       Role  role  =  roleService.getRole(id);

       ModelAndView  mv = new ModelAndView();

       mv.setViewName(“roleDetails”);   // 响应的目标是 /WEB-INF/jsp/roleDetails.jsp

mv.addObject(“role”, role ); //相当于是 request.setAttribute(“role”, role);

return  mv;

}

}

 

 

SpringMVC提供了几种数据模型组件,来处理带数据的视图,它们分别是:

1、ModelAndView (兼具视图 和 数据存储到request域对象)

2、Map、ModelMap及Model  (主要用来数据存储到request域对象)

3、其中,可以在类上标注@SessionAttributes,代表该模型的put、add方法存放数据是往session域中存放。

4、其中,可以在控制器方法的形参之前标注@ModelAttribute(“XXX” )类型  形参变量名 ,代表要把该形参变量加入到request域对象中,比如形参是: @ModelAttribute("item")Items  itemcustomer相当于是:

model.addAttribute(“itmes”,itemcustomer),

 

 

  1. ModelAndView

<a href="data/data">demo</a>

 

@Controller

@RequestMapping(value="/data")

public class test1{

    @RequestMapping(value="/data")

    // @RequestMapping("/data")

    public ModelAndView testModel{

         String view="success";

         ModelAndView mav=new ModelAndView(view);

         User user=new User("admin","123");

         mav.addObject(user);

         return mav;    

    }

}

 

<body>

   ${requestScope.user.username}

   ${requestScope.user.password}

</body>

 

  1. 使用Map、ModelMap、Model作为方法的参数处理数据

给SpringMVC一个Map类型的参数,如果向Map中增加数据,那么该数据也会被放到request作用域中

<a href="data/data">demo</a>

 

@Controller

@RequestMapping(value="/data")

public class test1{

    @RequestMapping(value="/data")

    public String testMap(Map<String,object> map){

         User user=new User("admin","123");

         map.put("user",user);

         return "success";

    }

}

 

<body>

   ${requestScope.user.username}

   ${requestScope.user.password}

</body>   

 

@Controller

@RequestMapping(value="/data")

public class test1{

    @RequestMapping(value="/data")

    // @RequestMapping("/data")

    public String testModelMap(ModelMap map){

         User user=new User("admin","123");

         map.put("use",user);

         return "success";

    }

}

 

@Controller

@RequestMapping(value="/data")

public class test1{

    @RequestMapping(value="/data")

    // @RequestMapping("/data")

    public String testModelMap(Model map){

         User user=new User("admin","123");

         map.addAttribute("use",user);

         return "success";

    }

}

 

3.使用@SessionAttributes

@SessionAttribute(value="user")

@Controller

@RequestMapping(value="/data")

public class test1{

    @RequestMapping(value="/data")

    // @RequestMapping("/data")

    public String testSessionAttribute(Map<String,Object>  map){

         User user=new User("admin","123");

         map.put("use",user);

         return "success";

    }

}

 

<body>

     request  作用域中 :${requestScope.user.username}

     session作用域中 :  ${sessionScope.user.username}

<body>

 

4.使用@ModelAttribute注解处理数据

1.@ModelAttribute的应用逻辑:

 

          (1). @ModelAttribute 修饰的方法会在请求之前执行

 

          (2).请求中提交的use对象中的属性和map中key-value 遵循以下规则

 

                   map中有的键值对(有)----------- user对象中属性(有)         覆盖

 

                   map对象中属性(有)------------user对象中属性(无)            不变        

 

                   map对象中属性(无)------------user对象中属性(有  )           null

 

          (3)如果map中的key与对象不一致,则需要在传入的对象前加@ModelAttribute("user1") User user

 

2.标有@ModelAttribute的方法会在请求处理类的每个方法 执行前都执行一次,因此需要谨慎使用

jsp页面

    <form action="data/data" method='post">

         <input type="hidden"  value="admin" name="username">

         密码<input type="text"  value="124" name="password">

         <input type="submit"  value="修改" >

    </form>

 

请求处理类

@Controller

@RequestMapping(value="/data")

public class test1{

    @ModelAttribute

    public void queryUserBeforeUpdate(String username,Map<String,Object> map){

       //使用带数据的实体类对象,模拟从数据库中获取用户名为admin的对象

       //模拟查询用户名为admin的对象属性

        User user=new User();

        user.setUsername(username);

        user.setPassword("123");

        map.put("user",user);   //user1

    }

 

    @RequestMapping(value="/data")

    public String testModelAttribute(User user){

        //省略数据库的更新操作

        return "success"

    }

}

 

视图渲染

视图渲染值得就是jsp脚本的编写,主要是使用jsp的jstl/core库的c标签,以及jsp的EL表达式:

Jsp/jstl/core库的c标签

<c:out  value=”${   } ”    >    </c:out>

等价于:

<%=     >

也等价于

out.println(  ) 

EL表达式:

${user[name]}   等价于   ${user.name}    也等价于  下面三行:

User user = (User)request.getAttribute(user);

String name = user.getName();

out.println(name);

 

 

 

 

 

 

附录: Spring MVC 数据模型(上)

https://book.itxueyuan.com/1Zn6/RoXq9

该文没有考虑完整架构,仅仅说明几个数据模型(视图)与原生request域对象、session域对象的关系。

1. 前言

本节课,将和大家一起聊聊 Spring MVC 在不同的作用域中如何封装数据。

继续之前,先理解本节课程提出的数据模型概念:Spring MVC 提供的在特定作用域内封装数据的组件。掌握理解数据模型组件的使用便是全文重点。

2. 请求作用域

WEB 程序的应用层使用的是 HTTP 协议,HTTP 协议有一个特点,无状态。

所谓无状态指上一次请求与下一次请求之间是隔离的,没有内在的联系。更通俗的讲,可理解为一个患有健忘症的人,只记得当前自己在做什么,不记得自己曾经做过什么,更不会知道自己将来要做什么。

HTTP 协议的这种无状态,最初设计时是从安全角度考虑。但是,在某些应用场景下,如购物车的应用场景下,却显得无能为力。购物车中的商品不一定是一次请求下的结果,往往是多次请求下的结果。

也就是说,购物车需要保存每一次请求获取到的数据。显然,直接使用 HTTP 协议是无法做到的。就需从技术层面上提供解决方案。

原生 Servlet 提供了 3 个作用域,可以根据用户的需要来保存每一次请求过程中产生的数据。

  • 请求作用域: 使用 HttpServletRequest 组件存储的数据可以在每一次的请求周期内存在。 请求结束,数据也将消失;
  • 会话作用域: 使用 HttpSession 组件保存的数据能在整个会话生命周期内存在。如购物车就可以保存在会话作用域中;
  • 应用程序作用域: 使用 ServletContext 组件保存的数据在整个应用程序生命周期之内存在。

Spring MVC 中,把数据保存在请求作用域,或是说在整个请求过程中数据都有效。有 2 种解决方案

  • 直接使用 HttpServletRequest 组件;
  • 使用 Spriing MVC 提供的高级数据模型组件。

2.1 使用原生 HttpServletRequest

先设定一个需要请求作用域的需求场景:

需求说明: 用户登录成功后,在登录成功后的页面中显示登录者的信息。

操作流程:

  1. 准备好 3 个静态页面;
  • login.html 登录页面,接收用户输入的用户名、密码等与登录相关的信息;
  • index.html 登录成功后跳转到的页面;
  • fail.html 登录失败后跳转到的页面。
  1. 编写 login.html 页面中的登录表单;
<form action="user/login" method="post">
        姓名:<input name="userName" value="" type="text"> <br />
    密码:<input name="userPassword" value="" type="password">
       <br />
       <input name="btnLogin" value="登录" type="submit">
       <input name="btnRe" value="重置" type="reset">
</form>
  1. 编写响应控制器;

package  com.mk.web.action;

@Controller

@RequestMapping(“/user”)

public  class  UserAction {

@RequestMapping("/login")
public String login(User user,HttpServletRequest request) {
        if("mk".equals(user.getUserName()) && "123".equals(user.getUserPassword())) {
               //请求作用域   
            request.setAttribute("loginUser", user); //向request域中存入属性loginUser
                return "index";
        }
        return "fail";
}
}

login()方法有 2 个参数:

  • user 参数:OOP 的方式,封装浏览器请求中传过来的数据(具体过程省略,只是示意);
  • request 参数: 注入原生 HttpServletRequest 组件。Spring 的注入功能很厉害的,只要你需要,它便能帮你拿到。登录者的信息保存在 HttpServletRequest 对象中。

Tips HttpServletRequest 组件具有服务器端数据存储功能,本质是内部维护有一个 map 对象。HttpServletRequest 的生命周期较短,从请求开始到请求结束。所以,其保存的数据也只能在整个请求范围内有效。

  1. 编写 index.html 和 fail.html 页面。
  • idnex.html 页面内,使用 EL 表达式,读取请求作用域中的登录者信息;
<body>
我是首页
<br/>
当前登录者:${loginUser.userName}
</body>

Tips 这里有一个坑,需要提醒一下。通过 maven 创建的 WEB 项目的 web.xml 文件的头信息版本偏低,使用 EL 表达式时,可能会在页面中出现红色的错误提示,其实并不影响发布。但终究让人看的烦心。可以找到 tomcat 服务器端的 web.xml 文件,用其头信息替换下。

  • fail.html 页面简单地加入一条 “失败” 提示语就可以了。

看一下最后的项目结构吧:

  1. 最后的测试。

Tips 登录的逻辑验证使用了硬代码,用户名:mk,密码:123。

登录成功后,会转到首页,且在首页中显示出登录者的信息。

2.2 使用 Spring MVC 模型组件

直接使用 HttpServletRequest 封装请求作用域级别的数据,不能说不好。但是,Spring MVC 存在的目的,就是为了简化开发者的工作,动不动就要 Spring 把底层的原生 API 弄出来,Spring MVC 存在的意义就不大了。

HttpServletRequest 的功能是全方面的,存储数据可以说是它的副业,为了一个数据存储,把它搬出来,好像有点大材小用。

其实,你可以告诉 Spring MVC ,我只要 HttpServletRequest 的存储功能。也就是说,只要 Spring MVC 引用出 HttpServletRequest 内置的 map 对象就可以了。

好了!现在重构一下上面的实例,仅仅修改控制器 login()方法的代码。

@RequestMapping(value="/login",method=RequestMethod.POST)
public String login(User user,Map map) {
        if("mk".equals(user.getUserName()) && "123".equals(user.getUserPassword())) {
               map.put("loginUser", user);
               return "index";
        }
        return "fail";
}

还是 2 个参数,user 参数就不啰嗦了。

map 参数则是一个神奇的存在。在方法的参数中,等于通知 Spring MVC ,帮我把某个作用域中的 map 对象引用出来。

如前言中所述,作用域有 3 个级别,Spring MVC 怎么知道你要哪一个层面的作用域。既然没有明说,Spring MVC 引用出来的是请求作用域也就是request域,即 HttpServletRequest 的内置 map 对象。好了,你可以放心的和前面一样测试代码,在 index.html 页面中你将看到登录者的信息。

搞了半天了,其实本质上是一样:一个直接把 HttpServletRequest 交给你用,一个仅仅只是把实现了存储的那一部分功能交给你。

有句话叫做透过现象看本质,Spring MVC 只是对原生 Servlet 开发做了高级封装。如同端午节吃棕子,礼品盒再怎么高级、漂亮,打开后还是棕子。

3. 小结

本节课和大家一起学习了 Spring MVC 中的数据模型。所谓数据模型,就是用来装数据的组件,当然,因 WEB 应用程序的特殊性,更多是要讨论存放在这个组件中的数据在一个什么样的范围之内能够被使用。

本节课学习到了,可以直接使用原生的 HttpServletRequest 完成请求作用域数据的存储,触类旁通,当然,你也可以直接使用原生 HttpSession 对象,保存会话作用域级别数据的保存。

有时,不需要为了吃一个桃子,砍掉一棵树。开发者可以使用 Spring MVC 引用出内部的存储对象,这样更小巧实用。是的,本节课程中出现的 map 是 Spring MVC 中的数据模型组件。

 

附录: Spring MVC 数据模型(下)

1. 前言

Spring MVC 为了解决 HTTP 协议的无状态性,提供了很多能适用于不同作用域需求的模型对象,从而保证程序中的数据能在开发者需要的地方出现。

本节课继续和大家聊聊 Spring MVC 中的数据模型组件。

  • Model;
  • ModelMap;
  • ModelAndView。

2. 更多数据模型

模型是一个用的很广的概念。本课程中数据模型应该有 2 层含义:

  • WEB 程序中封装数据的组件;
  • 此模型对象会有自己特定作用域。

上一小节中,向大家介绍了 Map 模型对象,其本质是对 HttpServletRequest 对象中的存储功能的引用。Map 还是比较原始和天然的。Spring MVC 为了展现自己的特色服务,对 Map 进行了多层面的封装,提供了更丰富的数据模型对象。

Tips 重要的事情强调一下,你将认识或使用到的数据模型会很多,但其本质是:

  • 如果是请求作用域,你只是在间接使用 HttpServletRequest 对象,本质上还是request域对象;
  • 如果是会话作用域,你只是在间接使用 HttpSession 对象,本质上还是session域对象。

2.1 Model

这个字面意思很明显,咱就是一个模型组件。

Model 是一个接口类型,Model 接口中提供了标准的保存数据的方法。

Model addAttribute(String attributeName, @Nullable Object attributeValue);

Model 使用起来很简单,将 Model 设为控制器方法的参数便可 ,其它的交给 Spring MVC,因为 Model 是一个接口类型,Spring MVC 会为我们辨明身份,注入一个具体的实例对象。

@RequestMapping(value="/login",method=RequestMethod.POST)
public String login01(User user,Model map) {
        if("mk".equals(user.getUserName()) && "123".equals(user.getUserPassword())) {
               map.addAttribute("loginUser", user);
               return "index";
        }
        return "fail";
}

Model 接口中还有其它的方法,但都不常用,感兴趣的话大家可以查阅其源代码或 API 文档。

2.2 ModelMap

这个组件的字面意思是说,我是用 Map 存储数据的模型。可以查阅一下其源代码结构.,本质上还就是一个链表实现的 Map,都是一家人呀。

Map、Map …… 又见 Map。

ModelMap 中提供的方法和 Model 接口差不多,不同之处在于有自己的实现。

public class ModelMap extends LinkedHashMap<String, Object> {
        public ModelMap addAttribute(String attributeName, @Nullable Object attributeValue) {
               Assert.notNull(attributeName, "Model attribute name must not be null");
               put(attributeName, attributeValue);
               return this;
        } 
}

如何使用?

Spring MVC 的世界,会让你感觉到自己的多余,因为很多事情 Spring MVC 都帮你温柔的解决。一样的,只需要设定为控制器方法的参数就可以了。

@RequestMapping(value="/login",method=RequestMethod.POST)
public String login01(User user,ModelMap map) {      
        if("mk".equals(user.getUserName()) && "123".equals(user.getUserPassword())) {
               map.addAttribute("loginUser", user);
               return "index";
        }
        return "fail";
}

会发现,大家除了名字不一样外,其它好像也没有什么不一样。

2.3 ModelAndView

从字面上了解这个组件,应该是除了充当模型的功能外,还与视图有关系。想要彻底看透它,很简单,查阅一下源代码结构。

public class ModelAndView {
@Nullable
private Object view;
@Nullable
private ModelMap model;
//……
}

Tips 搞了半天,会发现,ModelAndView 其实就是封装了 ModelMap 外加一个用来保存视图相关信息的 view 对象。

其实,大家都是一家人,根源是相同的,具有共同的遗传基因,当然,还会有只属于自己的独有功能。

ModelAndView 和其它的数据模型使用起来稍有一点不同,往往是作为控制器方法的返回值。

@RequestMapping(value="/login",method=RequestMethod.POST)
public ModelAndView login01(User user) {
        ModelAndView mv=new ModelAndView();
        if("mk".equals(user.getUserName()) && "123".equals(user.getUserPassword())) {
               mv.addObject("loginUser", user);
               mv.setViewName("index");
               return mv;
        }
        mv.setViewName("fail");
        return mv;
}

Tips ModelAndView 把数据模型和视图拼在了一起,便于一次性交给前端控制器处理。

3. 会话作用域

Map、Model 、ModelMap、ModelAndView 这几个数据模型组件,默认情况下,其中所保存的数据都是请求作用域级别的。

在很多应用场景下,需要数据在整个会话过程中都能访问到。比如登录者信息、购物车信息等。

面对这种数据需求时,Spring MVC 又如何实现?

你能想到的,Spring MVC 早就想到了。使用 @SessionAttributes 注解即可。

@SessionAttributes 注解是类级别的注解,需要添加在控制器类的前面。

@Controller
@RequestMapping("/user")
@SessionAttributes("loginUser")
public class UserAction {
@RequestMapping(value="/login",method=RequestMethod.POST)
        public ModelAndView login01(User user) {
        ModelAndView mv=new ModelAndView();
        if("mk".equals(user.getUserName()) && "123".equals(user.getUserPassword())) {
               mv.addObject("loginUser", user);
               mv.setViewName("index");
               return mv;
        }
        mv.setViewName("fail");
        return mv;
}
}

Tips @SessionAttributes(“loginUser”) 中的属性名 loginUser 必须保持和 mv.addObject(“loginUser”, user); 中的 loginUser 名一样。

从底层思维来讲, Spring MVC 即把数据保存到请求作用域中、也保存到会话作用域中。

测试时,只需要在 index.jsp 中添加如下面的 EL 表达式,指明数据的作用域。

<body>
 我是首页
 <br/>
 请求作用域中得到当前登录者:${requestScope.loginUser.userName}
 <br/>
 会话作用域中得到当前登录者:${sessionScope.loginUser.userName}
</body>

启动浏览器,打开登录页面,输入登录名、登录密码、点击登录,然后在浏览器中会看到无论是请求作用域、还是会话作用域中都可以获取到登录者的信息。

4. 小结

本节课程和大家一起讲解了 Model 、ModelMap、ModelAndView 数据模型,并讲解了可以使用 @SessionAttributes 注解提升数据模型的作用域。

从功能层面上讲,所有数据模型组件的功能是一样的。从底层上讲,区别在于实现 Map 的数据结构。

  • 直接使用 Map 做数据模型时, Spring MVC 注入的是一个 LinkedHashMap 实例。
  • ModelMap 是 LinkedHashMap 的子类,本质还是 LinkedHashMap,只是封装了 put 方法,让其显得高级一点。
  • Model 是接口,Spring MVC 注入的也是 LinkedHashMap 实例。

所以,无论是使用 Map 、Model 还是 ModelMap 其实都是在借助 LinkedHashMap 完成数据的存储。其区别在于应用场景,有时,需要接口注入,有时可能需要类注入。当然,还会有自己的功能实现。

附录:案例项目相关的Spring MVC的配置文件

web.xml中的相关内容

<!--springMVC前端控制器加载, -->

  <servlet>

    <servlet-name>springmvc</servlet-name>

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

    <!--contextConfigLocation配置SpringMVC加载的配置文件(配置处理器,映射器等等)

    如果不配置contextConfigLocation,默认加载的是:/WEB-INF/servlet名称-servlet.xml(springmvc-servlet.xml),但这里没有使用默认

    -->

    <init-param>

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

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

    </init-param>

  </servlet>

 

springmvc.xml内容(默认是/WEB-INF/springmvc-servlet.xml

    <!--开启注解方式:配置-->

    <!--使用annotation-driven 注解驱动,就可以代替 注解映射器 注解适配器 的配置-->

    <!--conversion-service 向处理器适配器中注入【自定义的参数绑定组件】。-->

    <!--validator 向处理器适配器,注入 校验器-->

    <mvc:annotation-driven conversion-service="conversionService" />

 

<!--组件扫描,可以扫描 controllerService...并注册添加到 spring 容器中

    这里扫描 controller,指定controller的包

    -->

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

只要配置了注解驱动和扫描的包,Spring MVC扫描的时候就会把@Controller标注的都扫描成控制器。

 

 

   <!--视图解析器-->

    <!--

    需要配置解析jsp的视图解析器

    jsp解析,默认使用jstl标签解析

    -->

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <!--拼接视图地址的前缀和后缀-->

        <property name="prefix" value="/WEB-INF/jsp/"/>

        <property name="suffix" value=".jsp"/>

</bean>

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值