版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Stream_who/article/details/84713522
一、基础概念
1. Spring web MVC框架提供了MVC(模型 - 视图 - 控制器)架构和用于开发灵活和松散耦合的Web应用程序的组件
2. Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架
3. Spring Web MVC框架也是一个基于请求驱动的Web框架,并且也使用了前端控制器模式来进行设计,再根据请求映射规则分发给相应的页面控制器(动作/处理器)进行处理
4. MVC模式导致应用程序的不同方面(输入逻辑,业务逻辑和UI逻辑)分离,同时提供这些元素之间的松散耦合
1)模型(Model):模型层,业务数据的信息表示,关注支撑业务的信息构成,通常是多个业务实体的组合
2)视图(View): 视图层,负责渲染模型数据,为用户提供UI,重点关注数据的呈现,为用户提供界面
3)控制器(Controller): 控制层,调用业务逻辑产生合适的数据(Model),传递数据给视图(View)用于呈现
5. springMVC的优点
1)进行更简洁的Web层的开发
2)天生与Spring框架集成(如IoC容器、AOP等)
3)支持灵活的URL到页面控制器的映射
4)非常容易与其他视图技术集成,如Velocity、FreeMarker等等,因为模型数据不放在特定的API里,而是放在一个Model里(Map数据结构实现,因此很容易被其他框架使用)
5)非常灵活的数据验证、格式化和数据绑定机制,能使用任何对象进行数据绑定,不必实现特定框架的API
6)提供一套强大的JSP标签库,简化JSP开发
7)支持灵活的本地化、主题等解析
8)更加简单的异常处理
9)对静态资源的支持
10)支持Restful风格
二、工作原理与组件
1. 组件
1)DispatcherServlet —— 前端控制器(不需要工程师开发),由框架提供
(1)作用:接收请求,响应结果,相当于转发器,中央处理器。有了dispatcherServlet减少了其它组件之间的耦合度
(2)用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性
2)HandlerMapping —— 处理器映射器,(不需要工程师开发),由框架提供
(1)作用:根据请求的url查找Handler
(2)HandlerMapping负责根据用户请求找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等
3)HandlerAdapter —— 处理器适配器
(1)按照特定规则(HandlerAdapter要求的规则)去执行Handler
(2)通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
4)Handler —— 处理器,需要工程师开发,(比如项目里面的@Controller下的@RequestMapping)
(1)编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler
(2)Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理
(3)由于Handler涉及到具体的用户业务请求,所以一般情况需要工程师根据业务需求开发Handler
5)View resolver —— 视图解析器(不需要工程师开发),由框架提供
(1)作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)
(2)View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户
(3)springmvc框架提供了很多的View视图类型,包括:jstlView、freemarkerView、pdfView等
(4)一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由工程师根据业务需求开发具体的页面
6)视图View —— (需要工程师开发,例如jsp…)
(1)View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf...)
2. 工作原理
1)首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制
2)DispatcherServlet——>HandlerMapping, HandlerMapping 将会把请求映射为HandlerExecutionChain 对象(包含一个Handler 处理器(页面控制器)对象、多个HandlerInterceptor 拦截器)对象,通过这种策略模式,很容易添加新的映射策略
3)DispatcherServlet——>HandlerAdapter,HandlerAdapter 将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器
4)HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter 将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView 对象(包含模型数据、逻辑视图名)
5)ModelAndView的逻辑视图名——> ViewResolver, ViewResolver 将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术
6)View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术
7)返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束
三、springMVC常规配置
1. web.xml配置
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2. springMVC或spring文件中配置
<!-- 扫描包 -->
<context:component-scan base-package="com.yiibai" />
<!-- 开启mvc注解 -->
<mvc:annotation-driven />
<!-- 设置默认的静态资源处理器,不设置配了视图解析器会报404错误 -->
<mvc:default-servlet-handler/>
<!-- 配置视图解析器,项目中用不到也可以不配 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
3. 定义控制器
@Controller
@RequestMapping("/hello")
public class HelloController{
@RequestMapping("/test")
public String printHello(ModelMap model) {
model.addAttribute("message", "Hello Spring MVC Framework!");
return "hello";
}
}
4. 创建视图jsp,并请求 /hello/test,即会返回有指定数据的指定视图
四、springMVC常用注解
1. 组件型注解
1)@Component: 在类定义之前添加@Component注解,他会被spring容器识别,并转为bean
2)@Repository: 对Dao实现类进行注解 (特殊的@Component)
3)@Service: 用于对业务逻辑层进行注解, (特殊的@Component)
4)@Controller 用于控制层注解 ,(特殊的@Component)
5)@RestController 相当于@Controller和@ResponseBody的效果
2. 请求和参数型注解
1)@RequestMapping:用于处理请求地址映射,可以作用于类和方法上
(1)value:定义request请求的映射地址
(2)method:定义地request址请求的方式,包括【GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE.】默认接受get请求,如果请求方式和定义的方式不一样则请求无法成功
(3)params:定义request请求中必须包含的参数值
(4)headers:定义request请求中必须包含某些指定的请求头,如:RequestMapping(value = "/something", headers = "content-type=text/*")说明请求中必须要包含"text/html", "text/plain"这中类型的Content-type头,才是一个匹配的请求
(5)consumes:定义请求提交内容的类型
(6)produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
示例:
@RequestMapping(value="/requestTest.do",params = {"name=sdf"},headers = {"Accept-Encoding=gzip, deflate, br"},method = RequestMethod.GET)
public String getIndex(){
System.out.println("请求成功");
return "index";
}
2)@RequestParam:用于获取传入参数的值题
(1)value:参数的名称
(2)required:定义该传入参数是否必须,默认为true,(和@RequestMapping的params属性有点类似)
示例:
@RequestMapping("/requestParams2.do")
public String requestParams(@RequestParam(value = "name",required = false) String names){
System.out.println("name = "+names);
return "index";
}
3)@RequestBody:用于获取传入参数的值(json格式)
(1)application/json、application/xml等格式的数据,必须使用@RequestBody来处理
(2)multipart/form-data,@RequestBody不能处理这种格式的数据。(form表单里面有文件上传时,必须要指定enctype属性值为multipart/form-data,意思是以二进制流的形式传输文件。)
(3)application/x-www-form-urlencoded,这种情况的数据@RequestParam、@ModelAttribute可以处理,@RequestBody也可以处理
4)@PathViriable:用于定义路径参数值
(1)value:参数的名称
(2)required:定义传入参数是否为必须值
示例:
@RequestMapping("/{myname}/pathVariable2.do")
public String pathVariable(@PathVariable(value = "myname") String name){
System.out.println("myname = "+name);
return "index";
}
5)@ResponseBody:作用于方法上,可以将整个返回结果以某种格式返回,如json或xml格式
6)@Resource和@Autowired
(1)@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入
(2)@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的 required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用
(3)@Resource默认按照ByName自动注入
五、springMVC常规用法
1. 文件上传
1)SpringMVC实现文件上传,需要再添加两个jar包。一个是文件上传的jar包,一个是其所依赖的IO包。这两个jar包,均在Spring支持库的org.apache.commons中
2)bean中配置
<!-- springMVC上传文件时,需要配置MultipartResolver处理器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="10485760000"></property>
<property name="maxInMemorySize" value="40960"></property>
</bean>
3)上传方法中多了一个MultipartFile对象
@RequestMapping("/upload.do")
public String upload(@RequestParam MultipartFile[] myfiles,HttpServletRequest request) throws IOException {
for(MultipartFile file : myfiles){
// 此处MultipartFile[]表明是多文件,如果是单文件MultipartFile就行了
if(file.isEmpty()){
System.out.println("文件未上传!");
}
else{
// 得到上传的文件名
String fileName = file.getOriginalFilename();
// 得到服务器项目发布运行所在地址
String path1 = request.getSession().getServletContext().getRealPath("image")+File.separator;
// 此处未使用UUID来生成唯一标识,用日期做为标识
String path = path1+ new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+ fileName;
// 查看文件上传路径,方便查找
System.out.println(path);
// 把文件上传至path的路径
File localFile = new File(path);
file.transferTo(localFile);
}
}
return "uploadSuccess";
}
2. 全局异常处理
<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.Exception">errors/error</prop>
<prop key="java.lang.Throwable">errors/err</prop>
</props>
</property>
<property name="statusCodes">
<props>
<prop key="errors/error">500</prop>
<prop key="errors/404">404</prop>
</props>
</property>
<!-- 设置日志输出级别,不定义则默认不输出警告等错误日志信息 -->
<property name="warnLogCategory" value="WARN"></property>
<!-- 默认错误页面,当找不到上面mappings中指定的异常相应视图时,使用本默认配置 -->
<property name="defaultErrorView" value="errors/error"></property>
<!-- 默认HTTP状态码 -->
<property name="defaultStatusCode" value="500"></property>
</bean>
3. springMVC中配置拦截器
1)自定义拦截器,实现HandlerInterceptor接口
2)配置文件中增加配置
<mvc:interceptors>
<!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->
<mvc:interceptor>
<!-- 进行拦截:/**表示拦截所有controller -->
<mvc:mapping path="/**" />
<!-- 不进行拦截 -->
<mvc:exclude-mapping path="/index.html"/>
<bean class="com.bybo.aca.web.interceptor.Login"/>
</mvc:interceptor>
</mvc:interceptors>
4. 配置多视图解析器(相同类型或者不同类型的视图解析器,order的值越大, 优先级越低)
<!-- FreeMarker视图解析器 -->
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="cache" value="false" />
<property name="prefix" value="/WEB-INF/ftl/"></property>
<property name="suffix" value=".ftl"></property>
<property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
<property name="contentType" value="text/html;charset=UTF-8"></property>
<property name="exposeRequestAttributes" value="true" />
<property name="exposeSessionAttributes" value="true" />
<property name="exposeSpringMacroHelpers" value="true" />
<property name="requestContextAttribute" value="base"></property>
<property name="order" value="1"></property>
</bean>
<!-- 视图解析器1 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
<property name="viewNames" value="jsp*"></property>
<!-- 定义模板顺序 -->
<property name="order" value="2"></property>
</bean>
<!-- 视图解析器2 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/html/"></property>
<property name="suffix" value=".html"></property>
<property name="viewNames" value="html*"></property>
<!-- 定义模板顺序 -->
<property name="order" value="3"></property>
</bean>
参考网址
注:文章是经过参考其他的文章然后自己整理出来的,有可能是小部分参考,也有可能是大部分参考,但绝对不是直接转载,觉得侵权了我会删,我只是把这个用于自己的笔记,顺便整理下知识的同时,能帮到一部分人。
ps : 有错误的还望各位大佬指正,小弟不胜感激