springMVC学习笔记(2),包括三层架构与SSM的关系,springMVC中MVC模式的实现,配置视图解析器。

SpringMVC学习笔记(1)中,我们了解了SpringMVC的主要作用,并一步步的指导完成了第一个基于SpringMVC的web应用。

SSM与三层架构的关系

到这里,我们可以将SSM框架与三层架构之间的关系搞清:

  • SpringMVC:界面层,接收用户请求,显示处理结果
  • Spring:业务层,处理业务逻辑,Spring会负责Service,DAO,工具类等对象的创建和管理
  • MyBatis:持久层,实现数据库的访问,对数据进行增删改查等。

SpringMVC中的MVC模式应用

从上面可以看出,SpringMVC实现界面层的功能,其框架的各组成部分,也是按MVC模型来进行设计的。这些类也分别实现MVC各层的功能。即三层架构中的界面层,再可以按MVC模式,分成M(Model),V(View),C(Controller)这三部分,其中:

  • C(Controller),在SpringMVC中,分为两部分:
    • 前端控制器(front controller),就是DispatcherServlet,也叫中央控制器,或中央处理器。所有的用户请求,都由这个前端控制器实行分配,通过查找请求映射,来将请求再交给具体的后端控制器。
    • 后端控制器(back controller),是我们自己定义的Controller类,用@Controller注解,springMVC框架会自动创建该对象,在后端控制器中,可以定义使用@RequestMapping注解处理器方法或控制器方法来真正处理用户请求。处理完成后,可以通过返回值,来返回Model和View
  • M(Model),后端处理器定义的处理器方法在处理完用户请求后,可以通过返回ModelAndView类型或Object类型来返回数据,这个数据就是Model。这个Model(数据)可以在View(视图)中进行显示。
  • V(View),后端处理器定义的处理器方法在处理完用户请求后,可以通过返回ModelAndView类型或String类型来返回View的路径,通过springMVC框架会通过请求转发来将request域转发给View。比如上例中的show.jsp(最后显示处理结果的页面),在View中,可以显示Model中的各数据。

所以,从SpringMVC处理用户请求的过程,我们也可以很好的去理解三层架构与MVC模式之间的关系。

下面继续后面的知识。

配置视图解析器

在上一节学习中,我们发现一个问题,就是View视图文件(show.jsp),放在了webapp目录下面。
在这里插入图片描述
我们可以直接通过地址栏输入对这个视图文件的访问。

在这里插入图片描述
由于这个访问没有通过MyController控制器,所以,并没有任何数据。我们需要避免。
方法为将View视图页面放在用户不能直接访问到的WEB-INF目录下(在学习java web开发时,应该知道这一点,WEB-INF目录下的所有目录或文件对用户不开放,用户是直接访问不了)。

常用作法是,在WEB-INF目录下创建一个子目录,命名为view,或pages等。当然,还可以根据需要创建子目录结构。并将视图(show.jsp)放在该目录下(在idea中,可以直接使用鼠标拖动来移动文件,移动文件属于重构(refactor)操作,按提示确定即可)
在这里插入图片描述
移动后,show.jsp文件处于WEB-INF目录下的view目录中。
在这里插入图片描述
这时,如果用户想自己去访问show.jsp文件,是不被允许的,因为WEB-INF目录下的所有资源或文件,不允许用户直接访问。
在这里插入图片描述
但是,我们只要修改MyController类中的控制器处理方法doSome(),将里面指定视图的路径修改成新的路径即可。

        //mv.setViewName("/show.jsp");
        mv.setViewName("/WEB-INF/view/show.jsp");

这时重新启动Tomcat,再将访问首页index.jsp
在这里插入图片描述
点击链接

在这里插入图片描述
说明View视图页访问正常。

我们往往会在一个Controller中定义多个控制器处理方法,来处理不同的请求,比如我们一个Controller处理增删改查四种不同的请求。这就会有四个不同的控制器处理方法。在每个方法处理完成后,可能会指定不同的视图路径,来打开不同的View视图页面。这时,我们会发现,在路径字符串中,有许多信息是重复的,比如View所在的目录(例如我们这里是/WEB-INF/view目录),还有扩展名都是.jsp

下图代码并不作为实例代码,只是作为示例,便于理解视图解析器的作用。
在这里插入图片描述

我们可以在springMVC框架中声明视图解析器来减少这种重复工作。
具体作法是,修改springMVC的配置文件springmvc.xml。添加视图解析器

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前缀:视图文件的路径-->
        <property name="prefix" value="/WEB-INF/view/" />
        <!--后缀:视图文件的扩展名-->
        <property name="suffix" value=".jsp" />
    </bean>

修改MyController的控制器处理方法中的指定View路径的代码

        //当配置了视图解析器后,可以使用逻辑名称(文件名)来指定视图
        //mv.setViewName("/WEB-INF/view/show.jsp");
        mv.setViewName("show");

可以看出,当配置了视图解析器后,可以使用逻辑名称(文件名)来指定视图,而且,当配置了视图解析器后,只能使用逻辑名称来指定视图,如果还继续使用全路径来指定,则视图解析器也会帮你加上前缀和后缀,这样,最后的路径将会不正确。

关于请求映射的属性(@RequestMapping)

value属性

前面我们通过设置value值,来实现请求与控制器处理方法之间的映射关系。这种映射可以是

  • 一对一,即一个请求有一个处理方法;
  • 多对一,即多个请求,可以由一个处理方法来处理;
  • 不能一对多,即一个请求不可能对应有多个处理方法。

对于一个控制器处理方法,我们可以让多个不同的请求都让该方法来处理。例如:

@RequestMapping(value = {"/some.do","/first.do"})
public ModelAndView doSome(){
	...
}

value属性的值为一个数组,每个元素对应一种请求,所以,当是some.do或first.do请求,都会被中央处理器交给这个控制器处理方法dosome()来处理。
在这里插入图片描述
另外,请求名称(some.do和first.do)和控制器处理方法名称(dosome())不需要相同, 彼此没有任何关系。只是所有请求名称(包括路径在内的URI)必须唯一。

method属性

method属性用来指定请求的方法类型;如果不指定该属性值,则请求可以是任意类型。默认是对请求类型不限制。
但如果想限制请求只能是某一种类型时,则需要设置method属性。其值为枚举类型RequestMethod,下面代码是其定义。

public enum RequestMethod {
    GET,
    HEAD,
    POST,
    PUT,
    PATCH,
    DELETE,
    OPTIONS,
    TRACE;

    private RequestMethod() {
    }
}

例如:我们希望请求只能是POST请求,可以如下设置:

    @RequestMapping(value = "/some.do",method = RequestMethod.POST)
    public ModelAndView doSome(){  //功能上类似doGet()
    	...
    }

通过设置属性value = "/some.do",method = RequestMethod.POST,限定请求/some.do必须为POST请求,如果不是,则会出错。
例如通过链接来提交该请求为GET方式。
在这里插入图片描述
在这里插入图片描述
我们看到,会出现405错误码,方法不允许,即要求的是POST方法,但发起的是GET方法。客户端请求类型有错。同学们有兴趣,可以修改index.jsp文件,增加一个form,提交方法为POST。

<form action="some.do" method="post">
    <button type="submit" >提交</button>
</form>

在这里插入图片描述
点击表单提交按钮,发起POST请求
在这里插入图片描述
请求类型正确,处理正常。

指定模块名称

通常情况下,我们进行开发时,会按功能划分模块,即某一功能下的所有请求,都会在一个模块下面。
比如前面我们的所有请求都在user模块下,那么,控制器的请求映射中,请求名称应该包括模块名称。如下:
在这里插入图片描述
为了方便对于模块名称的管理,避免重复输入模块名,也避免在修改模块名时,需要修改多个地方,我们可以通过在控制类的上面添加@RequestMapping注解。

当@RequestMapping注解放在类的上面时,是设置对于该控制类中所有控制器处理方法公共的部分。
修改MyController类代码,在类定义上添加@RequestMapping注解,并添加value属性,值为所有映射到处理器方法的请求的公共部分,一般为模块名。

@RequestMapping(value = "/user")
public class MyController {
    @RequestMapping(value = "/some.do",method = RequestMethod.POST)
    public ModelAndView doSome(){ 
    	...
    }
    @RequestMapping(value = {"/listAll.do","/second.do"})
    public ModelAndView doListAll(){
		...
    }
    @RequestMapping(value = "/add.do")
    public ModelAndView doAdd(){
		...
    }    

这时,实际与处理器方法映射的请求名称为/user/some.do,/user/listAll.do,/user/second.do,/user/add.do。

所以,如果有模块名,则可以通过在类上添加@RequestMapping注解来定义该类的准备映射的所有请求的模块名称。

当然,index.jsp文件中,发起请求的链接地址也需要添加上模块名称。

<p>第一个SpringMVC项目</p>
<p><a href="user/some.do">发起some.do请求</a></p>

<form action="user/some.do" method="post">
    <button type="submit" >提交</button>
</form>

下一节,我们再继续讨论关于处理器方法的参数

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java Man

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值