MVC
M:Model,模型层,指工程中的JavaBean
javabean分俩种:
①实体类bean
②业务处理bean :指Service或Dao对象
V: View,视图层,指工程中html或jsp页面
C: Controller,控制层,指工程中servlet
SpringMVC
1.是Spring的一个后续产品,是Spring的一个子项目
2.是Spring为表述层开发提供的一阵套完备的解决方案
SpringMVC的特点
1.Spring家族原生产品
2.基于原生的Servlet
3.代码清新简洁
依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
web.xml
DispatcherServlet在他的创建过程中,会同时创建springmvc容器对象。
读取springmvc的配置文件,把这个配置文件中的对象都创建好,当用户发起请求时就可以直接使用对象servlet的初始化会执行init()方法
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 自定义springmvc读取的配置文件的位置-->
<init-param>
<!-- springmvc的配置文件的位置的属性-->
<param-name>contextConfigLocation</param-name>
<!-- 指定自定义文件的位置-->
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 在tomcat启动后创建Servlet对象
load-on-startup:表示tomcat启动后创建对象的顺序,值为整数,数值越小tomcat创建对象的时间越早-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- url-pattern可以使用俩种值
1.扩展名方式语法 *.xxx,xxx是自定义扩展名。常用的方式*.do,*.mvc,*.action等等
http://localhost:8080/springmvc/some.do
交给springmvc servlet处理
2.使用“/” 表示静态资源和未映射的请求都交给tomcat的default处理
使用/导致所有的静态资源都给DispatcherServlet处理,默认情况下 DispatcherServlet没有处理静态资源的能力没有控制器对象能处理静态资源的访问,所 以静态资源404-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
Controller
//@Controller:创建处理器对象,对象放在springmvc容器中
@Controller
public class MyController {
/* 使用方法来处理请求,方法自定义,有多种返回值,多种参数
准备使用dosome方法处理some.do请求
@RequestMapping:请求映射,作用是把一个请求地址和一个方法绑定在一起,一个请求指定一个处理方法
value 是一个string 表示请求url的地址,值唯一不能重复
位置 1. 在方法的上面,常用
2. 在类的上面
@RequestMapping修饰方法可以处理请求的,类似servlet中的doget,dopost
返回值:ModelAndView
Model:数据,请求处理完成后,要显示给用户的数据
View:视图,比如jsp等*/
@RequestMapping(value = "/some.do")
public ModelAndView dosome(){
ModelAndView mav= new ModelAndView();
//添加数据,框架在请求的最后把数据放入到request作用域
//request.setAttribute("msg","");
mav.addObject("msg", "欢迎使用springmvc做web开发");
mav.addObject("fun", "执行的dosome方法");
//指定视图,指定视图的完整路径
//框架对视图执行的forword操作,request.getRequestDispather("/.jsp").forword(..)
mav.setViewName("/show.jsp");
//返回mav
return mav;
}
}
springmvc.xml
开启扫描组件
<context:component-scan base-package="wjh.controller"></context:component-scan>
中央调度器DispatcherServlet
1.负责创建springmvc容器对象,读取xml配置文件,创建文件中的Controller对象
2.负责接收用户的请求,分派给自定义的Controller对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jeWHL8Ec-1657536934495)(C:\Users\OMEN\AppData\Roaming\Typora\typora-user-images\image-20220301211537636.png)]
springmvc执行过程源代码
1.tomcat启动,创建容器的过程
通过load-on-start标签指定的1,创建DispatcherServlet对象
DispatcherServlet他的父类是继承HttpServlet的,是一个servlet,在被创建时会执行init()方法
在init()方法中
创建容器,读取配置文件
WebApplicationContext ctx = new ClassPathXmlApplicationContext(“.xml”);
把容器对象放入到ServletContext中
getServletContext().setAttribute(key,ctx);
上面创建容器作用:创建@Controller注解所在的类的对象,创建MyController对象,
这个对象放入到springmvc的容器中,容器时map,类似map.put(“myController”,MyController对象)
2.请求的处理过程
1)执行servlet的service()
protected void service(HttpServletRequest request,HttpServletResponse response)
protected void doService(HttpServletRequest request,HttpServletResponse response
this.doDispatch(request,response){
调用MyController的dosome()方法
}
接收形式参数
逐个接收请求参数:
要求:处理器(控制器)方法的形参名和请求中参数名保持一致
同名的请求参数赋值给同名的形参
框架接收请求参数
1.使用request对象接收请求参数
String name=request.getParameter(“name”)
2.springmvc框架通过DispatcherServlet 调用MyController的doSome()方法
调用方法时,按名称对应,把接受的参数赋值给形参
@RequestMapping(value = {"/Other.do", "/second.do" })
public ModelAndView doOther(String name,int age){
ModelAndView mav= new ModelAndView();
mav.addObject("myname", name);
mav.addObject("myage", age);
mav.setViewName("show2");
//返回mav
return mav;
}
使用post提交出现中文乱码
请求映射
@RequestMapping : 请求映射 不指定则没有限制
属性 method 表示请求方式
get请求 RequestMethod.GET
post RequestMethod.post*/
@RequestMapping(value = {"/some.do", "/first.do" } , method = RequestMethod.GET)
@RequestMapping(value = {"/some.do", "/first.do" } , method = RequestMethod.POST)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IHIkdLVQ-1657536934496)(D:\edge\springmvc (1)].png)
返回值
1.ModelAndView
表示视图和数据
public ModelAndView dosome(){
ModelAndView mav= new ModelAndView();
//添加数据,框架在请求的最后把数据放入到request作用域
//request.setAttribute("msg","");
mav.addObject("myname", "name");
mav.addObject("myage", "age");
//指定视图,指定视图的完整路径
//框架对视图执行的forword操作,request.getRequestDispather("/.jsp").forword(..)
mav.setViewName("show2");
//返回mav
return mav;
}
2.String
表示视图,可以使用逻辑名称,也可以是完整视图路径
public String doString(String name,Integer age){
System.out.println(name + " " + age);
//配置视图解析器使用逻辑地址
//返回mav
return "show2";
}
3.void
不能表示视图,也不能表示数据
public void doajax(HttpServletResponse response,String name, int age) throws IOException {
//处理ajax,使用json做数据格式
//service调用完成,使用student表示处理结果
System.out.println(name+" "+age);
Student student= new Student();
student.setRname(name);
student.setRage(age);
String json="";
if(student!=null){
ObjectMapper om = new ObjectMapper();
json = om.writeValueAsString(student);
System.out.println(json);
}
response.setContentType("application/json;charset=utf-8");
PrintWriter pw= response.getWriter();
pw.println(json);
pw.flush();
pw.close();
}
4.Object
例如String,Integer,Student等都是对象,对象有属性,属性就是数据。所以返回Object表示数据,和视图无关,可以使用对象表示数据,响应Ajax请求
1.加入处理json的工具库依赖,springmvc默认使用Jackson
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
2.在springmvc配置文件之间加入mvc:annotation-driven注解驱动
json = om.writeValueAsString(student);
3.在处理器方法的上面加入@ResponseBody注解
response.setContentType("application/json;charset=utf-8");
PrintWriter pw= response.getWriter();
pw.println(json);
springmvc处理器方法返回object,可以转为json输出到浏览器,响应ajax的内部原理
1.mvc:annotation-driven注解驱动
注解驱动实现的功能是完成java对象到json,xml,text,二进制等数据格式的转换
mvc:annotation-driven 在加入到springmvc配置文件后,会自动创建HttpMessageConverter接口的7个实现类对象,包括MappingJackson2HttpMessageConverter(使用Jackson工具库中的ObjectMapper实现java对象转为json字符串)
HttpMessageConvter接口:消息转换器
功能:定义了java转为json,xml等数据格式的方法。这个接口有很多的实现类
这些实现类完成java对象到ojson,java到xml转换
boolean canWrite(Class<?> var1,@Nullable MediaType var2)
void write()
这俩个方法是控制器类把结果输出给浏览器使用的
1)canWrite检测student(lisi,20)能否转成var2表示的数据格式,如果能转为json,返回true
MediaType :表示数据格式的,例如json ,xml
2)write:把处理器方法的返回值对象,调用jackson中的objectMapper转为json字符串
json = om.writeValueAsString(student);
2.@ResponseBody注解
放在处理器方法的上面,通过HttpServletResponse输出数据,响应ajax请求的
PrintWriter pw= response.getWriter();
pw.println(json);
pw.flush();
pw.close();
3.实例
1)自定义类型
@RequestMapping(value = "/studentJson.do")
@ResponseBody//和其他注解没有顺序关系
/*
1.框架会把返回的Student类型,调用框架中的ArrayList<HttpMessageConvter>中的每个类的canWrite()方法,检查哪个HttpMessageConvter接口的实现类能处理Student类型的数据 MappingJackson2HttpMessageConverter
2.框架会调用实现类的write(),MappingJackson2HttpMessageConverter的write()方法把李四同学的student对象转为json,调用jackson的objectMapper实现转为json
ContextType : application/json;charset=utf-8
3.框架会调用@ResponseBody把2的结果数据输出到浏览器,ajax请求处理完成
*/
public Student doStudentJsonObject(String name,Integer age){
Student student = new Student();
student.setRname("张三同学");
student.setRage(20);
return student;
}
2)List集合
@RequestMapping(value = "/studentsJson.do")
@ResponseBody//和其他注解没有顺序关系
public List<Student> doStudentsJsonObject(String name, Integer age){
List<Student> studentList = new ArrayList<>();
Student student = new Student();
student.setRname("张三同学");
student.setRage(20);
Student student2 = new Student();
student2.setRname("李四同学");
student2.setRage(23);
studentList.add(student);
studentList.add(student2);
return studentList;
}
success:function(resp){
// alert(resp.rname+" " +resp.rage);
$.each(resp,function (i,n) {
alert(n.rname+ " " + n.rage)
})
}
3)String返回数据
区分是返回视图还是返回数据 @ResponseBody
//Content-Type: text/plain;charset=ISO-8859-1导致中文乱码
// 解决:text/plain;charset=utf-8设置produces值
@RequestMapping(value = "/stringData.do",produces = "text/plain;charset=utf-8")
@ResponseBody
public String doStringData(String name,Integer age){
System.out.println(name + " " + age);
//返回mav
return "Hello 返回数据";
}
静态资源处理
1.mvc:default-servlet-handler
<!-- 加入这个后框架会创建DefaultServletHttpRequestHandler(类似自己创建的MyController)
DefaultServletHttpRequestHandler这个对象可以把接收的请求转发给tomcat的Default-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
mvc:default-servlet-handler和@RequestMapping注解有冲突 需要加入 mvc:annotation-driven
2.mvc:resources
<!-- mvc:resources 加入框架后会创建ResourceHttpRequestHandler这个处理器对象
让这个对象处理静态资源的访问,不依赖tomcat服务器
mapping: 访问静态资源的url地址,使用通配符**
location : 静态资源在项目中的目录位置
images/** : 表示images下所有文件
mvc:resources和@RequestMapping有一定的冲突-->
<!-- <mvc:resources mapping="images/**" location="/images/"></mvc:resources>-->
<!-- <mvc:resources mapping="html/**" location="/html"/>-->
<!-- <mvc:resources mapping="js/**" location="/js/"/>-->
<!-- 使用一句话整合所有静态资源-->
<mvc:resources mapping="static" location="/static/"/>
拦截器
1.创建一个普通类,作为拦截器
1)实现HandleeInterceptor接口
2)实现接口中的三个方法
public class Myinterceptor implements HandlerInterceptor {
/*
* 预处理方法
* Object handler:被拦截的控制器对象
* 返回值Boolean:
* true:表示通过
* false:表示不通过
* 特点:
* 在控制器的方法之前执行,用户请求首先到达此方法,可以验证用户是否登录
* */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
/*
* 后处理方法
* Object handler:被拦截的控制器对象
* ModelAndView modelAndView:处理器方法的返回值
* 在处理器方法之后执行
* 能够获取到处理器方法的返回值,可以修改ModelAndView中的数据和视图,可以影响到最后的执行结果
* 作用可以用来做二次修正
* */
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
/*
* 最后执行的方法
* Object handler:被拦截器的处理对象
* Exception ex :程序中发生的异常
* 框架中规定是视图处理完成后,对视图执行嘞forward。就认为请求处理完成
* 一般做资源回收工作的,程序请求过程中创建嘞一些对象,在这里可以删除,把占用的内存回收
*
* */
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
2.创建配置文件
1)组件扫描器
2)声明拦截器,并指定拦截的请求url地址
<mvc:interceptors>
<mvc:interceptor>
<!-- **可以表示多级目录和目录中的文件-->
<mvc:mapping path="/static/html/**"/>
<bean class="wjh.handler.Myinterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
跨域
@CrossOrigin注解
(1条消息) 注解@CrossOrigin详解_MobiusStrip的博客-CSDN博客_crossorigin注解
文件
1)组件扫描器
2)声明拦截器,并指定拦截的请求url地址
<mvc:interceptors>
<mvc:interceptor>
<!-- **可以表示多级目录和目录中的文件-->
<mvc:mapping path="/static/html/**"/>
<bean class="wjh.handler.Myinterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
跨域
@CrossOrigin注解