文章目录
SpringMVC笔记
课程目标
1: springmvc简介
2: springmvc流程
3: springmvc入门案例
4: springmvc接收表单数据
5: springmvc 跳转方式。
6: 数据类型转换
1.Springmvc简介
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发的。
2.SpringMVC的执行流程
1.用户向服务器发送请求,请求被Spring 前端控制器 DispatcherServlet捕获;
2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得对应的Handler
3. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。
4. 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
5. Handler执行完成后,向DispatcherServlet 返回视图、数据;
6. 根据返回的视图与数据,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
7. ViewResolver 结合视图与数据,来渲染视图
8. 将渲染结果返回给客户端。
3.springMvc的入门案例
基于注解配置
1.web.xml跟上面配置一致
2.Springmvc.xml
<!-- 扫描注解 -->
<context:component-scan base-package="com.offcn"></context:component-scan>
<!-- 开启springmvc注解驱动 自动装配处理器映射器、处理器适配器 -->
<mvc:annotation-driven />
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
3.处理器 package com.offcn.demos;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class IndexController{
@RequestMapping("/index")
public String demo1(HttpServletRequest request) {
request.setAttribute("info","张三");
return "/background";
}
}
4.页面跟上面一样
5.访问路径跟上面一样
4./ 与 /* 的区别
/和/的区别:
< url-pattern > / </ url-pattern > 不会匹配到.jsp,即:.jsp不会进入spring的 DispatcherServlet类 。但是会匹配到静态资源
< url-pattern > / </ url-pattern > 会匹配*.jsp,也会匹配到静态资源。会出现返回jsp视图时再次进入spring的DispatcherServlet 类,导致找不到对应的controller所以报404错。
总之,关于web.xml的url映射的小知识:
< url-pattern>/ 会匹配到/login这样的路径型url,不会匹配到模式为*.jsp这样的后缀型url
< url-pattern>/ 会匹配所有url:路径型的和后缀型的url(包括/login,.jsp,.js和.html等)
结论:在配置视图的时候尽量用/这种方式。
5.静态资源处理问题
凡是能通过http请求直接访问的非web资源都称为静态资源 css文件、js文件、图片、音频…
如果我们将拦截的路径配置成/ 所有静态资源无法访问。
示例:
在webcontent下建立images目录并存入一张图片,再新建index.jsp
加载静态资源
浏览器访问:http://localhost:8080/springmvc/index.jsp,测试发现图片的确无法加载开放所有静态资源
mvc:default-servlet-handler/
6.Springmvc跳转:
Servlet: 请求转发和重定向
Springmvc:
redirect:跳转的资源文件路径(重定向)
forward:跳转的资源文件路径(请求转发)
@RequestMapping(value = “/ar”)
public String actionRedirect(HttpServletRequest request){
request.setAttribute(“info”,“redirect”);
System.out.println(“跳转的资源文件路径(重定向)”);
return “redirect:index.jsp”;
}
@RequestMapping(value = "/af")
public String actionForward(HttpServletRequest request){
request.setAttribute("info","forward");
System.out.println("跳转的资源文件路径(请求转发)");
return "forward:index.jsp";
}
Webcontent下index.jsp添加${info}
浏览器访问:http://localhost:8080/springmvc/af
转发:地址不变,request域中的数据能读取
浏览器访问:http://localhost:8080/springmvc/ar
重定向:址址改变了, index.jsp无法读取request域中的数据。
7.Form表单数据处理
Servlet:
getParameter(“name”);
getParameterNames();
getParameterValue(name);
getParameterMap();—beanutils(map集合中的数据—自动填充到java模型对象上);
自动参数映射
直接将我们的表单数据定义成方法参数
1、基本数据类型
方法的参数可以是任意基本数据类型,如果方法参数名与 http 中请求的参数名称相 同时会进行自动映射
@RequestMapping("/param1")
public String param1(int id,String name,String password) {
System.out.println(“id=”+id);
System.out.println(“name=”+name);
System.out.println(“password=”+password);
return “show”;
}
建立前端表单页面,提交
测试发现控制中的参数都都被映射上
2、简单对象类型
建立person实体类
public class Person {
private int id;
private String name;
private String password;
//get,set,toString
}
控制方法使用person自定类型使作为参数
@RequestMapping("/param2")
public String param2(HttpServletRequest request,Person person) {
System.out.println(person);
request.setAttribute(“info”, person);
return “show”;
}
表单中只需要将控制的名称和类中的属性直接对应,默认的将我们的数据封装成对象直接使用
前端表单页面
提交表单,发现person的所有属都对有值了
3、复杂的对象类型
这里指的复杂数据类型指的是一个自定义类型中还包含另外一个对象类型,如用户类型中包含产品对象,或含List,Map,Set集合
不能直接在Controller的参数中指定List,Map,Set类型,定义一个类型包装 List 集合在其中
建立Dog
public class Dog {
private String name;
private int age;
}
在建立Person
public class Person {
private int id;
private String name;
private String password;
private Dog dog;
private List<Dog> list;
private Map<String, Dog> map;
private Set<Dog> set;
//get,set,toString
}
针对于集合类型的,list map,针对于模型中的属性想要回去表单数据的话,需要提供setter and gettter 方法
Controller方法
@RequestMapping("/param2")
public String param2(HttpServletRequest request,Person person) {
System.out.println(person);
request.setAttribute(“info”, person);
return “show”;
}
前端表单页面
映射Dog dog
--------------映射Dog dog------------------
<input type="submit" value="提交">
</form>
映射List list
--------------映射List < Dog > list------------------
映射Map map
<p>--------------映射Map < Dog > map------------------</p>
<label>map第一组-name:</label><input type="text" name="map[key1].name"><br />
<label>map第一组-age:</label><input type="text" name="map[key1].age"><br />
<hr />
<label>map第二组-name:</label><input type="text" name="map[key2].name"><br />
<label>map第二组-age:</label><input type="text" name="map[key2].age"><br />
<input type="submit" value="提交">
</form>
8.表单中String类型转Date类型
由于日期数据有很多种格式,所以springmvc没办法把字符串转换成日期类型。所以需要自定义参数绑定。前端控制器接收到请求后,找到注解形式的处理器适配器,对RequestMapping标记的方法进行适配,并对方法中的形参进行参数绑定。在springmvc这可以在处理器适配器上自定义Converter进行参数绑定。
测试代码
新建User
public class User {
private int id;
private String name;
private Date birthday;
}
控制器
@RequestMapping("/param3")
public String param2(HttpServletRequest request,User user) {
System.out.println(user);
request.setAttribute(“info”, user);
return “show”;
}
前端表单页面
提交表单后发现无法正常映射User对象,因为String类型无法转换为Date类型。
当表单输入的数据类型与后台对象属性数据类型不匹配时,提交时就会绑定参数失败便会出现400
解决方法:
方法一:在时间属性上加上注解
@DateTimeFormat(pattern=“yyyy-MM-dd”)
private Date birthday;
使用该方法,前台时间字符串将会自动转型,但是如果前台传入如2016-06-06 19:20:66 则会报错,必须传入标准的时间字符串。
方法二:自定义DataConvertor类, 并实现Convertor接口
1.编写时间类型转换器
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
/*
- String(当前类型) Date(目标类型)
*/
// 自定义类型转换器
public class DateConveter implements Converter<String,Date> {
@Override
public Date convert(String createtime) {
SimpleDateFormat simpleDateFormat =null;
if(createtime.contains("/")) {
simpleDateFormat = new SimpleDateFormat(“yyyy/MM/dd HH:mm:ss”);
}else {
simpleDateFormat = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
}
try {
// 转成直接返回
return simpleDateFormat.parse(createtime);
} catch (ParseException e) {
e.printStackTrace();
}
// 如果参数绑定失败返回null
return null;
}
}
2.配置转换器 springmvc.xml
<bean id="dateConveter" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<!-- 这里写自定义的转换工具类 -->
<bean class="com.offcn.utils.DateConverter" />
</list>
</property>
</bean>
3.使用转换器
<mvc:annotation-driven conversion-service=“dateConveter” />
使用了springmvc注解扫描方式conversion-service 使用这个属性调用自己定义的转换器服务,这样我们整个web工程只要使用springmvc的方式,日期等自己定义这种转换器就会自动完成数据的转换。