首先按照 SpringMVC框架原理 需要先配置前端控制器
前端控制器配置 DispatcherServlet
前端控制器DispatcherServlet
在web.xml里面配置前端控制器 DispatcherServlet
<!--配置SpringMVC前端控制器 -->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--为前端控制器指定各种handler映射器,handler适配器,视图解析器,语言环境解析器,异常解析器 -->
<!--如果不配置ContextConfigLocation 默认加载的是WEB-INF/servlet名称-servlet.xml (springmvc-servlet.xml) -->
<init-param>
<param-name>ContextConfigLocation</param-name>
<!--此配置文件内部配置handler映射器,handler适配器,视图解析器,语言环境解析器,异常解析器的bean,交由IOC容器管理 -->
<param-value>classpath:SpringMVCBeans.xml</param-value>
</init-param>
</servlet>
<!--配置url和DispatcherServlet之间的映射规则 -->
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<!--url-pattern:第一种: *.action 表示 所有以.action结尾的请求由DispatcherServlet进行解析 -->
<!--第二种: / 表示所有地址都由DispatcherServlet进行解析,这种方法可以实现RESTful风格的url -->
<!--第三种: /* 这种配置存在问题,使用这种配置,在转发到jsp页面时,DispatcherServlet会jsp地址,不能根据jsp页面找到handler -->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
补充:
其实当用户配置好前端控制器(DispatcherServlet)后,不配置处理器映射器(HandlerMapping)和处理器适配器(HandlerAdapter),程序照样可以运行。
这是因为SpringMVC会加载SpringMVC依赖jar包下默认的配置文件DispatcherServlet.properties,该文件内部对于处理器映射器和处理器适配器都有默认配置。
# 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.DefaultAnnotationHandlerMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
org.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
(SpringMVC提供了两种选择)(另外SpringMVC允许用户同时配置这两个处理器映射器(两者可以共存))
1.在SpringMVCBeans.xml配置处理器映射器HandlerMapping (将处理器适配器交由SpringMVC容器管理)
<!--配置处理器映射器 -->
<!-- 处理器映射器,将bean的name作为url进行查找,需要在配置Handler时候配置BeanName(即url) -->
<bean id="CelebrityController" name="/saveAndGetCelebrity.action" class="com.ncs.controller.CelebrityController">
</bean>
<bean id="HandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
</bean>
2.在SpringMVCBeans.xml配置(第二种)处理器映射器SimpleHandlerMapping
<!--配置Handler(controller) 指定BeanName(Url) class -->
<bean id="CelebrityController" class="com.ncs.controller.CelebrityController">
</bean>
<!--第二种处理器映射器 (前端控制器DispatcherServlet会根据URl能够被那个映射器处理就让哪个映射器执行,所以SpringMVC多个处理器映射器可以并存) -->
<bean id="SimpleHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/saveAndGetCelebrity2.action">CelebrityController(这里是bean(controller)的id)</prop>
<prop key="/saveAndGetCelebrity3.action">CelebrityController(这里是bean(controller)的id)</prop>
</props>
</property>
</bean>
处理器适配器配置 HandlerAdapter
处理器映射器(SpringMVC提供了两种选择)
1.在SpringMVCBeans.xml配置处理器适配器HandlerAdapter (将处理器适配器交由SpringMVC容器管理)
<!--注意:handler需要实现Controller接口才能生效-->
<bean id="HandlerAdapter" class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter">
<!--这种适配器要求Handler必须实现Controller接口-->
</bean>
<!--所有的处理器适配器都是实现了HandlerAdapter接口-->
<!--通过(handler instanceof Controller)语句判断配置的适配器是ControllerHandler适配器-->
@Override
public boolean supports(Object handler) {
return (handler instanceof Controller);
}
public interface Controller {
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
2.第二种处理器适配器,在SpringMVCBeans.xml配置处理器适配器HandlerAdapter
<!--第二种处理器适配器 -->
<!--注意:handler需要实现HttpRequestHandler接口才能生效 -->
<bean id="HttpRequestHandlerAdapter" class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter">
</bean>
<!--所有的处理器适配器都是实现了HandlerAdapter接口-->
<!--通过(handler instanceof HttpRequestHandler)语句判断配置的适配器是HttpRequestHandler适配器-->
@Override
public boolean supports(Object handler) {
return (handler instanceof HttpRequestHandler);
}
public interface HttpRequestHandler {
void handleRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException;
}
编写Handler(Controller)
//第一种 实现Controller接口
@Component
public class CelebrityController implements Controller {
@Autowired
private CelebrityService celebrityService;
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
Celebrity celebrity = new Celebrity();
celebrity.setID(1);
celebrity.setName("Tim");
ModelAndView modelAndView = new ModelAndView();
try {
Map<String, Object> result = celebrityService.saveAndView(celebrity, celebrity.getID());
Iterator iterator = result.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Entry) iterator.next();
// 指定model
modelAndView.addObject("celebrity", celebrity);
// 指定视图
modelAndView.setViewName("/WEB-INF/jsp/show.jsp");
}
}catch(Exception e){
// 指定model
modelAndView.addObject("error", e);
// 指定视图
modelAndView.setViewName("/WEB-INF/jsp/error.jsp");
}
return modelAndView;
}
}
//第二种 实现HttpRequestHandler接口
@Component
public class CelebrityControllerForHttpRequestHandlerAdapter implements HttpRequestHandler {
@Autowired
private CelebrityService celebrityService;
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Celebrity celebrity = new Celebrity();
celebrity.setID(1);
celebrity.setName("Tim");
try {
Map<String, Object> result = celebrityService.saveAndView(celebrity, celebrity.getID());
Iterator iterator = result.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Entry) iterator.next();
// 指定model
request.setAttribute("celebrity", celebrity);
// 指定视图
request.getRequestDispatcher("/WEB-INF/jsp/show.jsp").forward(request, response);
}
} catch (Exception e) {
// 指定model
request.setAttribute("error", e);
// 指定视图
request.getRequestDispatcher("/WEB-INF/jsp/error.jsp").forward(request, response);
}
}
}
视图编写
编写视图 jsp,pdf、、、
配置视图解析器ViewResolver
在SpringMVCBeans.xml配置视图解析器ViewResolver (将处理器适配器交由SpringMVC容器管理)
<!--配置jsp视图解析器 "javax.servlet.jsp.jstl.core.Config"默认支持jstl -->
<bean id="ViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--配置视图页面的前缀和后缀,方便开发 -->
<!-- <property name="prefix" value="/WEB-INF/jsp/"/> -->
<!-- <property name="suffix" value=".jsp"/> -->
</bean>