整理了动力节点Springmvc的学习笔记,王鹤老师讲的springmvc,看了这么多网上的视频,还是只有王鹤老师讲的能听明白…就喜欢讲的细的,而且老师条理很清晰
视频资源:https://www.bilibili.com/video/BV1sk4y167pD
第二章 SpringMVC 注解式开发
2.1 @RequestMapping注解的使用。
属性: value 请求的uri地址。
位置: 1) 在方法的上面, 必须的。 2)在类的上面作为模块名称
@RequestMapping(value ="/some.do")
public ModelAndView doSome(){
属性 method 请求的方式, 使用RequestMehtod类的枚举,表示请求方式
@RequestMapping(value ="/other.do",method = RequestMethod.POST)
public ModelAndView doOther(){
2.2 接收请求中的参数
对应HttpServletRequest, HttpServletResponse, HttpSession 只需要在控制器方法的形参列表中,定义就可以了。框架会给参数赋值, 在控制器方法内部可以直接使用 request,response,session参数。
400 : http status , 表示客户端异常。 主要是发生在用户提交参数过程中。
接收请求中的参数: 逐个接收, 对象接收
2.2.1 逐个接收
逐个接收: 请求中的参数名和控制器方法的形参名一样。按照名称对象接收参数
<p>逐个接收请求参数</p>
<form action="receive-property.do" method="post">
姓名:<input type="text" name="name"> <br/>
年龄:<input type="text" name="age"> <br/>
<input type="submit" value="提交参数">
</form>
Controller接收参数
@RequestMapping(value ="/receive-property.do")
public ModelAndView doPropertyParam(String name, Integer age) {}
接收参数的问题:
- 参数最好使用包装类型。 例如Integer ,能接收空值情况, 接收的是null
- 框架可以使用String到int ,long, float, double等类型转换。
- post请求中有乱码的问题, 使用字符集过滤器。
2.2.2 CharacterEncodingFilter使用:
在web.xml 声明过滤器
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--给过滤器属性赋值-->
<init-param>
<!--项目使用的字符编码-->
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<!--强制请求(request)对象使用encoding的编码方式-->
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<!--强制应答(response)对象使用encoding的编码方式-->
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<!--强制所有请求,先经过过滤器处理-->
<url-pattern>/*</url-pattern>
</filter-mapping>
2.2.3 请求中参数名和形参名不一样,使用@RequestParam
/**
* 逐个接收请求参数, 请求中参数名和形参名不一样
* @RequestParam : 解决名称不一样的问题
* 属性: value 请求中的参数名称
* required : boolean类型的,默认是true
* true:请求中必须有此参数,没有报错。
* false:请求中可以没有此参数。
* 位置: 在形参定义的前面
*/
@RequestMapping(value ="/receive-param.do")
public ModelAndView doReceiveParam(
@RequestParam(value = "rname",required = false) String name,
@RequestParam(value = "rage",required = false) Integer age) { }
2.2.4 对象接收
对象接收: 在控制器方法的形参是java对象, 使用java对象的属性接收请求中参数值。
要求: java对象的属性名和请求中参数名一样。
例子:
*/
public class Student {
// 属性名和请求中参数名一样
private String name;
private Integer age;
// set| get方法
}
@RequestMapping("/receive-object.do")
public ModelAndView doReceiveObject(Student student){
System.out.println("MyController的方法doReceiveObject="+student);
ModelAndView mv = new ModelAndView();
mv.addObject("myname", student.getName());
mv.addObject("myage", student.getAge());
mv.setViewName("show");
return mv;
}
2.3 控制器方法的返回值
控制器方法的返回值表示本次请求的处理结果,返回值有ModelAndView, String, void , Object
请求的处理结果包含: 数据和视图。
2.3.1 ModelAndView 数据和视图
请求的结果有数据和视图,使用ModelAndView最方便
数据:存放request作用域。
视图:执行forward转发操作
2.3.2 String 视图
框架对返回值是String,执行的是forward转发操作。
视图可以表示为完整视图路径, 或者视图的逻辑名称
@RequestMapping(value ="/return-string-view.do")
public String doReturnStringView1(HttpServletRequest request,String name, Integer age) {
System.out.println("执行了MyController的doReturnStringView1方法name=");
//返回结果,forward,转发到show.jsp
//逻辑名称, 需要配置视图解析器
return "show";
}
@RequestMapping(value ="/return-string-view2.do")
public String doReturnStringView2(HttpServletRequest request,String name, Integer age) {
System.out.println("执行了MyController的doReturnStringView2方法name=");
//完整视图路径,不能使用视图解析器
return "/WEB-INF/view/show.jsp";
}
2.3.3 void 没有数据和视图
void: 没有数据和视图, 可以使用HttpServletResponse对象输出数据,响应ajax请求。
2.3.4 Object
返回Student 表示数据,还是视图。 所以控制器方法返回对象Object, 用来响应ajax请求。
返回对象Object ,可以是List, Student , Map ,String ,Integer… 这些都是数据, 而ajax请求需要的旧是数据。 在ajax请求中,一般需要从服务器返回的是json格式的数据, 经常要处理java对象到json的转换。而且还需要输出数据响应ajax请求。 框架提供了处理 java对象到json转换, 还是数据输出工作。
2.3.4.1 HttpMessageConverter 消息转换器
HttpMessageConverter 接口,作用是 1)实现请求的数据转为java对象, 2) 把控制器方法返回的对象转为json,xml,text,二进制等不同格式的数据。
public interface HttpMessageConverter<T> {
/**
作用: 检查clazz这个类型的对象,能否转为 mediaType表示的数据格式
如果能转为mediaType表示的类型, 返回true, 返回true调用read()
*/
boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
/**
作用: 接收请求中的数据,把数据转为 clazz表示的对象
*/
T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException;
/**
作用:检查clazz这种数据类型,能否转为mediaType表示的数据格式
*/
boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
/**
作用: 把t对象,按照contentType说明的格式,把对象转为json或者xml
*/
void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException;
}
MediaType:媒体类型,表示互联网中数据的格式。例如application/json, text/html, image/gif
HttpMessageConverter 接口的实现类:
MappingJackson2HttpMessageConverter : 用jackson工具库的ObjectMapper把java对象转为json数据格式
StringHttpMessageConverter : 把字符串类型的数据,进行格式转换和编码
怎么使用实现类:
框架根据控制器方法的返回类型, 自动查找使用的实现类。
@RequestMapping("/receive-object.do")
public Student doReceiveObject(String name,Integer age){
System.out.println("MyController的方法doReceiveObject=");
Student student = new Student();
student.setName("lisi");
student.setAge(20);
return student;
}
默认情况下: springmvc使用了HttpMessageConveter接口的4个实现类。包括了StringHttpMessageConverter.
需要在springmvc的配置文件,加入注解驱动的标签 mvc:annotation-driven. 加入这个标签后, springmvc项目启动后,会创建HttpMessageConveter接口的7个实现类对象,包括StringHttpMessageConverter 和 MappingJackson2HttpMessageConverter。
2.3.4.2 @ResponseBody
@ResponseBody注解的作用,就是把student转换后的json通过HttpServletResponse对象输出给浏览器。
//输出json,响应ajax
response.setContentType("application/json;charset=utf-8");
PrintWriter pw = response.getWriter();
pw.println(json);
pw.flush();
pw.close();
@ResponseBody注解作用就上面的代码的实现
2.3.4.3 控制器方法返回对象转为json的步骤
1)pom.xml加入jackson依赖,springmvc框架,默认处理json就是使用jackson
2)在springmvc的配置文件中,加入注解驱动的标签mvc:annotation-dirven
- 在控制器方法的上面加入@ResponseBody注解,表示返回值数据,输出到浏览器。
2.4 静态资源处理
访问地址:
当web.xml中DispatcherServlet的url-pattern是 *.do
http://localhost:8080/ch05_url_pattern/index.jsp tomcat
http://localhost:8080/ch05_url_pattern/js/jquery-3.4.1.js tomcat
http://localhost:8080/ch05_url_pattern/images/p1.jpg tomcat
http://localhost:8080/ch05_url_pattern/html/test.html tomcat
http://localhost:8080/ch05_url_pattern/some.do DispatcherServlet(springmvc框架)
2.4.1 tomcat的default servlet
tomcat安装目录/conf/web.xml
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
default 叫做默认servlet ,作用:
1.它提供静态资源的处理
2.它处理所有未映射到其他请求的请求处理
2.4.2 中央调度器设置 “/”
http://localhost:8080/ch05_url_pattern/index.jsp tomcat 成功访问
http://localhost:8080/ch05_url_pattern/js/jquery-3.4.1.js 404 没有对应的控制器对象
http://localhost:8080/ch05_url_pattern/images/p1.jpg 404 没有对应的控制器对象
http://localhost:8080/ch05_url_pattern/html/test.html 404 没有对应的控制器对象
http://localhost:8080/ch05_url_pattern/some.do 200 MyController
使用斜杠 "/" . 导致中央调度器称为了默认的default servlet。
需要处理静态资源和其他的未映射的请求。 默认中央调度器没有处理
静态资源的控制器对象, 所以静态资源都是 404 。 some.do这个请求
有MyController对象, 所以能访问。
如果项目中 , 中央调度器设置了“/” , 动态资源能访问,静态资源不能访问。
需要处理静态资源的访问工作。
2.4.3 第一种方式处理静态资源
在springmvc的配置文件加入 mvc:default-servlet-handler标签, springmvc框架会在项目运行时,加入DefaultServletHttpRequestHandler对象,让这个对象处理静态资源的访问。
<!--声明注解驱动
default-servlet-handler和@RequestMapping使用有冲突
-->
<mvc:annotation-driven />
<!--声明静态资源的第一种处理方式
创建DefaultServletHttpRequestHandler处理静态资源。
DefaultServletHttpRequestHandler把接收的静态资源的地址,转发给了tomcat的default
优点:
解决方式简单
缺点:
依赖tomcat服务器提供的能力。
-->
<mvc:default-servlet-handler />
2.4.4 第二种静态资源的处理方式
在springmvc配置文件中加入一个 mvc:resources标签, 框架会创建ResourceHttpRequestHandler控制器对象, 使用这个对象处理静态资源的访问。 不依赖tomcat服务器。 推荐使用的。
<!--声明注解驱动
resources和@RequestMapping使用有冲突
-->
<mvc:annotation-driven />
<!--声明静态资源的第二种处理方式
mapping: 访问静态资源的uri地址, 可以使用通配符(**)。
** : 表示任意的目录和目录和资源名称
location: 静态资源在项目中的位置, 不要使用/WEB-INF目录
-->
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/html/**" location="/html/" />
<mvc:resources mapping="/js/**" location="/js/" />
<!--一句话设置静态资源-->
<!--<mvc:resources mapping="/static/**" location="/static/" />-->