Spring MVC简单入门
Spring MVC简单入门
概述
- Spring MVC是Spring框架的web层的解决方案
Spring MVC框架提供了MVC(模型 - 视图 - 控制器)架构和用于开发灵活和松散耦合的Web应用程序的组件。 MVC模式导致应用程序的不同方面(输入逻辑,业务逻辑和UI逻辑)分离,同时提供这些元素之间的松散耦合。
- M: model(模型):封装了程序数据,通常是一些POJO类组成的。
- V: view(视图):负责绚烂模型数据,生成浏览器可以解析的HTML。
- C:controller(控制器):负责处理用户请求并构建相应的数据模型,然后将其传递给视图进行数据渲染。
引用Spring官方文档的话:
- Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more commonly known as “Spring MVC”.
- 意思是Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring Framework中。正式名称“Spring Web MVC”来自其源模块(spring-webmvc)的名称,但它通常被称为“Spring MVC”。
使用配置的方式构建一个Spring MVC项目
编写pom文件:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.21.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.21.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.21.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.21.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
SpringMVC01
org.apache.tomcat.maven
tomcat7-maven-plugin
2.2
UTF-8
/SpringMVC01
8080
编写web.xml文件
- <!DOCTYPE web-app PUBLIC
“-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”
“http://java.sun.com/dtd/web-app_2_3.dtd“ >
Archetype Created Web Application
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern>
- <!DOCTYPE web-app PUBLIC
准备Spring MVC的配置文件
- 默认情况下必需放在WEB-INF下
- 该文件的命名是-servlet.xml。(但是该文件的名称和路径都可以更改)
- 如我这里配置文件名字就是springmvc-servlet.xml
编写后端控制器
package com.fxyh.springmvc.web;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("info", "Hello World Spring Mvc");
modelAndView.setViewName("success");
return modelAndView;
}
}
编写JSP文件(success.jsp)
- <%@ page contentType=”text/html;charset=UTF-8” language=”java” isELIgnored=”false” %>
Title
${info}
- <%@ page contentType=”text/html;charset=UTF-8” language=”java” isELIgnored=”false” %>
编写Spring MVC配置文件
<?xml version=”1.0” encoding=”UTF-8”?>
目录结构图
Spring MVC默认配置
Default implementation classes for DispatcherServlet’s strategy interfaces.
Used as fallback when no matching beans are found in the DispatcherServlet context.
Not meant to be customized by application developers.
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMappingorg.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapterorg.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolverorg.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
映射处理器(HandlerMapping)
- BeanNameUrlHandlerMapping(配置方式)
- DefaultAnnotationHandlerMapping(注解方式)
映射适配器(HandlerAdapter)
- SimpleControllerHandlerAdapter(配置方式)
- HttpRequestHandlerAdapter(配置方式)
- AnnotationMethodHandlerAdapter(注解方式)
视图解析器(ViewResolver)
- InternalResourceViewResolver(配置和注解方式)
异常处理(HandlerExceptionResolver)
- DefaultHandlerExceptionResolver(配置方式)
- AnnotationMethodHandlerExceptionResolver(注解方式)
- ResponseStatusExceptionResolver(注解方式)
关于Spring MVC配置文件重命名问题:
- 默认情况下为WEB-INF下的-servlet.xml
真实开发中:
springmvc
org.springframework.web.servlet.DispatcherServlet
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:springmvc.xml</param-value>
springmvc
*.action
在servlet配置的时候添加初始化参数,指定contextConfigLocation参数
关于映射处理器问题
多个映射路径映射到了同一个后端控制器
<property name="mappings">
<props>
<prop key="/abc.action">handlerMappingController</prop>
<prop key="/handlerMapping.action">handlerMappingController</prop>
</props>
</property>
<!--<property name="order" value="1"/>-->
- 上述场景下,会执行handlerMapping处理器,因为从上而下执行,先找到上面的handlerMapping的处理器,所以直接解析了,所以两个处理器换一个位置就可以换一个处理器执行。
- 处理器也可以设置order,数值越小的优先级越高,配置方式如上注释的property。
- 如果多个映射处理器中配置了order的优先级比没有配置order的高,从上而下执行的情况只有所有的处理器都没有配置order属性的时候才有效。
怎么看是执行哪个处理器?
- org.springframework.web.servlet.DispatcherServlet的doDispatch方法里面
- 在这里打上断点,然后查看mappedHandlerd的值
关于映射适配器问题
- 后端控制器的执行方法(handleRequest)是由适配器调用。
适配器来适配后端控制器实现的接口
- 如:HelloController实现Controller接口,那么使用SimpleControllerHandlerAdapter适配器可以成功调用
如:
package com.fxyh.springmvc.web;
import org.springframework.web.HttpRequestHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class HandlerAdapterController implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setAttribute("info", "http request handler");
request.getRequestDispatcher("/WEB-INF/pages/adapter/success.jsp").forward(request, response);
}
}这个Controller实现的是HttpRequestHandler接口,使用SimpleControllerHandlerAdapter那么就会报错误
javax.servlet.ServletException: No adapter for handler [com.fxyh.springmvc.web.HandlerAdapterController@517db47a]
如果要让这个正常使用,必须要改适配器
-
- 使用HttpRequestHandlerAdapter适配器来适配,这里测试的时候这样玩,实际开发中是不会的,最好统一风格
-
关于跳转问题
服务器端跳转(转发)
- modelAndView.setViewName(“forward/success”);
- modelAndView.setViewName(“forward:/WEB-INF/pages/forward/success.jsp”);
- // 第三种: 只适合在后端控制器实现了HttpRequestHandler接口的时候
request.getRequestDispatcher(“/WEB-INF/pages/forward/success.jsp”).forward(request,response); - View view = new JstlView(“/WEB-INF/pages/forward/success.jsp”);
modelAndView.setView(view);
重定向
public class RedirectController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("info", "redirect");
modelAndView.setViewName("redirect:/redirectResult.action");
return modelAndView;
}
}public class RedirectResultController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("redirect/success");
return modelAndView;
}
}- 属性值取不到了,但是会做成http://localhost:8787/SpringMVC01/redirectResult.action?info=redirect
后端控制器
MultiActionController
package com.fxyh.springmvc.web;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class UserController extends MultiActionController {
public ModelAndView add(HttpServletRequest request, HttpServletResponse response) {
System.out.println("add");
return null;
}
public ModelAndView delete(HttpServletRequest request, HttpServletResponse response) {
System.out.println("delete");
return null;
}
public ModelAndView update(HttpServletRequest request, HttpServletResponse response) {
System.out.println("update");
return null;
}
public ModelAndView list(HttpServletRequest request, HttpServletResponse response) {
System.out.println("list");
return null;
}
}
* <bean id="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
<property name="paramName" value="method"/>
</bean>
<bean id="userController" name="/user.action" class="com.fxyh.springmvc.web.UserController">
<property name="methodNameResolver" ref="methodNameResolver"></property>
</bean>
* http://localhost:8787/SpringMVC02/user.action?method=update 会调用UserController的update方法
* http://localhost:8787/SpringMVC02/user.action?\[paramName\]=方法名 的方式来通过不同的参数值来调用不同的方法
2. ### ServletForwardingController ###
* package com.fxyh.springmvc.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import java.io.IOException;
public class DemoServlet extends HttpServlet {
private static final long serialVersionUID = 2206792018849975111L;
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
System.out.println("进来了");
}
}
* <servlet>
<servlet-name>demoServlet</servlet-name>
<servlet-class>com.fxyh.springmvc.servlet.DemoServlet</servlet-class>
</servlet>
* <bean id="servletForwardingController" name="/servlet.action" class="org.springframework.web.servlet.mvc.ServletForwardingController">
<property name="servletName" value="demoServlet"/>
</bean>
* 这里在web.xml中配置的servlet可以不配置servlet-mapping,这里请求servlet.action就会转发到DemoServlet。
还没有评论,来说两句吧...