SpringMVC学习笔记(三)

您所在的位置:网站首页 Dao层是干嘛的 SpringMVC学习笔记(三)

SpringMVC学习笔记(三)

2024-07-09 09:55| 来源: 网络整理| 查看: 265

这篇笔记主要记录我在处理请求时遇到的一系列问题,持续更新。

本篇笔记中使用的视图解析器均为InternalResourceViewResolver。

1、Model类

Model是一个存储模型数据的容器,我们可以将需要传递到客户端的数据存储在一个Model对象中,也可以访问Model对象中的任何数据。在每一次请求时,SpringMVC都会创建一个隐含的model对象,我们可以将它作为控制器方法的入参:

@Controller @RequestMapping({"/Ayo","/home","/hompage","/"}) public class HomeController { @RequestMapping( method =GET ) public String home(Model model){ String message = "Welcome"; model.addAttribute("message",message); return "home"; } }

SpringMVC会自动将model的指针传给home方法,这样在home方法内就可以往model中存储数据了,数据以key-value对的形式存储在model中,通过调用model的addAttribute(String key,Object value)方法来实现。如果在调用addAttribute()方法时没有指定key,那么key将会默认为value对象名的小写,因此:

model.addAttribute("message",message); 等价于 model.addAttribute(message);

将我们想要传给页面的数据存储在model对象中之后,我们不需要将model作为控制器方法的返回值。实际上,返回值还是可以不变,仍然为String。为什么呢?前面刚刚提到,model对象由框架创建,控制器得到了它的指针,将数据写入model对象中,之后的一切就交给框架来完成。因此,Controller只负责将数据存进model对象中,并且返回视图名,model中的数据就会自动被传给负责解析视图的组件,按照我们想要的方式渲染到视图中。 回到上面的代码,home方法向model内写入了一条数据,key为"message",然后返回了视图名"home"。现在我要把model里的数据渲染到home.jsp中去,通过一行很简单的代码来实现:

${message} to AYO's Room!

渲染结果(使用了CSS): 渲染结果

总结一下,model对象由SpringMVC在每次请求时创建,它可以作为控制器方法的入参,控制器方法只负责将要传递给页面的数据以键值对的形式存进model对象,在jsp中就可以直接通过key来获取数据了。

2、ModelAndView类

顾名思义,ModelAndView就是模型和视图。SpringMVC的开发者将两者整合为了一个类,便于我们使用。首先看一下使用ModelAndView类之后HomeController的代码:

@Controller @RequestMapping({"/Ayo","/home","/hompage","/"}) public class HomeController { @RequestMapping( method =GET ) public ModelAndView home(){ ModelAndView mav = new ModelAndView(); String viewName = "home"; String message = "Welcome"; mav.addObject("message",message); mav.setViewName(viewName); return mav; } }

可以看到home方法的代码变化很大,但是效果是完全不变的。对比之前,我们是使用model对象来传递数据,而model对象是由框架替我们创建好的,但现在我们使用了ModelAndView(以下简称MAV),因此我们需要手动new一个MAV实例。接下来,将需要传递的数据通过mav的addObject(String key, Object value)方法存入mav对象中。 数据存好了,我们还需要返回一个视图名。之前我们是直接返回一个字符串作为视图名,而在这里我们需要返回一个MAV对象,它会同时拥有模型数据和视图名。通过setViewName(String viewName)方法来设置视图名。在填充完模型数据和视图名后,将我们手动创建的这个mav对象返回。之后的事情交给框架来搞定,我们只需要在jsp中调用模型中的数据就行了,效果与使用model是完全一样的。 总结:使用ModelAndView来传递数据给视图时,需要在控制器方法中手动创建一个mav对象,将模型数据和视图名存储在mav对象中,然后将其返回即可。 与使用model比起来,控制器方法不再需要一个额外的入参了,简化了参数列表,也使得代码的维护更为简单(只需要专注于mav一个对象就行了)。

3、请求重定向

在控制器方法中,可以通过给视图名添加"redirect:"前缀的形式来实现:

return "redirect:/Ayo/home";

使用ModelAndView时,同样:

mav.setViewName("redirect:/Ayo/home");

视图解析器看到视图名中的"redirect:“前缀,就会将其解析为重定向的规则而不是视图名称。ps. “forward"前缀也可以被视图解析器识别。 重点需要注意的是,一旦使用了重定向规则,那么模型中的数据就无法传递到重定向之后的页面。需要在处理重定向请求的控制器方法中添加模型数据,才可以顺利渲染重定向之后的页面。 举个例子吧, ①客户端向地址”/Ayo/login"发送了一个POST请求,把用户名和密码传给了服务器。 ②服务器上的控制器A处理了这个请求,并往模型中添加了欢迎信息,但是返回的视图名为"redirect:/Ayo/home”。 ③视图解析器将其解析为一次重定向,而不是一个视图,于是服务器没有返回任何一个视图,而是返回了一次重定向的命令。模型数据就在这里丢失了。 ④客户端收到重定向的命令,又对地址"/Ayo/home"发送了一次GET请求。服务器上的控制器B负责处理对这个地址的请求,它往模型中添加了驱逐信息,并返回了一个视图名 “home”。 ⑤视图解析器将其解析为一个视图,于是模型中的驱逐信息被渲染到了home页面中,服务器将这个home页面返回给客户端。 ⑥最终客户端显示的不是一个欢迎登陆的home页面,而是一个责令你立马下线的home页面。

4、接收表单提交

在很多情况下,我们会需要接收一个来自客户端的表单,比如登录和注册功能。下面是一个简单的登录页面:

Login h1{ color: coral; font-style: inherit; } Login Username Password

页面的渲染结果应该是这样的: 渲染结果 我们看到,标签只设置了method属性为"post",这意味着表单会被提交到页面本身的url上,即"/Ayo/login"。那么在服务器端,我们就需要在LoginController中增加一个方法,来处理这个提交的表单:

@RequestMapping(method = RequestMethod.POST) public ModelAndView processLogin(LoginForm loginForm){ //loginForm的属性会使用请求中同名的参数来填充 this.username = this.loginServlet.processLogin(loginForm); ModelAndView mav = new ModelAndView(); String view = null; System.out.println(this.username + " just login"); if(this.username == null){ view = "login"; }else{ mav.addObject("username",this.username); view = "firstChallenge"; } mav.setViewName(view); return mav; }

上面的控制器方法processLogin()接受了一个LoginForm类的对象,LoginForm是我自己写的一个数据模型对象,拥有两个属性username和password。LoginForm类的代码:

package Models; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class LoginForm { private String username; private String password; @Autowired public LoginForm(){ } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }

你可能已经发现了,LoginForm类的两个属性刚好匹配表单中的两个input参数:username和password。在processLogin()方法的入参中只有一个LoginForm类的对象,SpringMVC会自动使用请求中同名的参数来填充loginForm对象的属性。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3