工作流程
控制器
public class MyController implements Controller { @Override public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception { ModelAndView mv = new ModelAndView(); mv.addObject("message", "Hello Vue"); mv.setViewName("/WEB-INF/jsp/welcome.jsp"); return mv; } }
Dispatch配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="/my.do" class="com.xx.handlers.MyController"/> </beans>
注册控制器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:myDispatch.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
URLPattern中用 / 出现的静态资源访问问题
解决办法1
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
解决办法2 (好用)要写在最上。
<mvc:default-servlet-handler/>
解决办法3
<mvc:resources mapping="/images/" location="/images/**"/>
映射器
默认使用的是BeanNameUrlHandlerMapping
使用SimpleUrlHandlerMapping, 可以实现多个url指向同一个Controller
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="hello.do">myController</prop> // key指定路由 <prop key="my">myController</prop> <prop key="xx">myControl ler</prop> </props> </property> </bean>
适配器
SimpleControllerHandleAdapter
所有实现了Controller的Bean,均是通过该适配器进行适配,执行的。
HttpRequestHandlerAdapter
所有实现了HttpRequestHandler的Bean,均是通过该适配器进行适配,执行的。
处理器
AbstactController
继承自WebContentGenerator,它有setSupportedMethods方法,控制请求的方式,默认支持GET,POST
<bean id="/hello" class="com.xx.handlers.MyController">
<property name="supportedMethods" value="GET"/>
</bean>
视图解析器
默认的视图解析器 internalResourceViewResolver
该视图解析器用于完成对当前web应用内部资源的封装和跳转,而对于内部资源的查找规则是,将ModelAndView中指定的视图名与为视图解析器配置的前缀和后缀结合的方式,拼接成一个Web应用内部资源路径。拼接规则是前缀+视图名称+后缀。
缺陷:不能访问外部资源。对于内部资源的定义,只能定义一种格式的资源,存放在同一目录的同一文件类型的资源文件。
BeanNameViewResolver
将Bean名称与View绑定
<bean id="taobao" class="org.springframework.web.servlet.view.RedirectView"> <property name="url" value="http://www.taobao.com"/> </bean> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
return new ModelAndView("welcome");
xmlViewResolver
将View视图专门抽取出来,单独定义为一个xml。可以使用xmlViewResolver
<bean class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="location" value="classpath:myViews.xml"/>
</bean>
ResourceBundleViewResolver
将视图写到,properties文件中
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="myViews"/>
</bean>
baidu.(class)=org.springframework.web.servlet.view.RedirectView baidu.url=http://www.baidu/.com welcome.(class)=rg.springframework.web.servlet.view.JstlView welcome.url=/WEB-INF/jsp/welcome.jsp
视图解析器的优先级
视图解析器有一个order属性,专门用于设置多个视图解析器的优先级。数字越小,优先级越高,数字相同,先注册的优先注册。
注解式开发
基础
注册组件扫描器
<context:component-scan base-package="com.xx.handlers"/>
@Controller
@RequestMapping("/test") //请求uri命名空间的定义
public class MyController{
@RequestMapping(value = "/ok", method = RequestMethod.GET, params = {"name", "age"})
// method 请求方法的限定
// params 对请求参数的限定 !name 表示不能有name参数 age=23 表示参数必须带age其值必须为23 age!=25 必须带age其值不能为25
public ModelAndView getOk(){
return new ModelAndView("/WEB-INF/jsp/welcome.jsp");
}
}
接收请求中的参数
接收get post请求
@RequestMapping(value = "/pok", method = RequestMethod.POST) public ModelAndView postOk(String name, Integer age){ System.out.println(name); System.out.println(age); return new ModelAndView("/WEB-INF/jsp/welcome.jsp"); }
还可以像servlet中那样做,用HttpServeletRequest
中文乱码问题解决
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> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter>
校正求情参数名
@RequestMapping(value = "/pok", method = RequestMethod.POST) public ModelAndView postOk(@RequestParam(name = "rname") String name, Integer age){ return new ModelAndView("/WEB-INF/jsp/welcome.jsp"); }
Object接收
<form action="/NewWeb/test/pok" method="post"> <label>输入名称 <input name="name" type="text"> </label> <label>输入年龄 <input name="age" type="number"> </label> <label>输入学校 <input name="school.name" type="text"> </label> <label>输入地址 <input name="school.address" type="text"> </label> <input type="submit" value="提交"> </form>
@RequestMapping(value = "/pok", method = RequestMethod.POST) public ModelAndView postOk(User user){ System.out.println(user); return new ModelAndView("/WEB-INF/jsp/welcome.jsp"); }
路径变量
@RequestMapping(value = "/user/{name}", method = RequestMethod.GET) public ModelAndView getOk(@PathVariable("name") String name){ ModelAndView mv = new ModelAndView("/WEB-INF/jsp/welcome.jsp"); return mv; }
返回ModelAndView
返回string
内部资源
@RequestMapping(value = "/ok", method = RequestMethod.GET) public String getOk(){ return "/WEB-INF/jsp/welcome.jsp"; }
外部资源。 仍然要注册
@RequestMapping(value = "/ok02", method = RequestMethod.GET) public String getOk02(){ return "baidu"; }
返回Object
用 json 进行前后端交互。
将object数据转化为json数据,需要由http消息转换器httpmessageconverter完成。转换器的开启,需要注册
<mvc:annotation-driven/>
可以用map
@RequestMapping(value = "/do") @ResponseBody public Object getOk02(){ Map<String, User> map = new HashMap<String, User>(); map.put("user1", new User("张三", 23 )); map.put("user2", new User("李三", 21 )); return map; }
或者list
@RequestMapping(value = "/do") @ResponseBody public Object getOk02(){ List<User> list = new ArrayList<User>(); list.add(new User("qqq",23)); list.add(new User("vvv",21)); return list;
核心技术
重定向
重定向携带参数
一般通过HttpSession,或者ModelAndView的addObject方法
@RequestMapping(value = "/ok", method = RequestMethod.GET) public ModelAndView getOk(){ ModelAndView mv = new ModelAndView(); mv.addObject("user", "xxx"); mv.setViewName("redirect:do"); return mv; } @RequestMapping(value = "/do") @ResponseBody public Object getOk02(String user){ System.out.println(user); return user; }
@RequestMapping(value = "/ok", method = RequestMethod.GET) public ModelAndView getOk(User user,HttpSession session){ session.setAttribute("user", user); return new ModelAndView("redirect:do"); } @RequestMapping(value = "/do") @ResponseBody public Object getOk02(HttpSession session){ User user = (User) session.getAttribute("user"); return user; }
异常处理
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="/WEB-INF/error/error-page.jsp"/>
<property name="exceptionAttribute" value="ex"/>
<property name="exceptionMappings">
<props>
<prop key="com.xx.exception.NameException">/error/name_error.jsp</prop>
<prop key="com.xx.exception.AgeException">age_error.jsp</prop>
</props>
</property>
</bean>
error-page
<body>
<div>
error page
${ex.message }
</div>
</body>
自定异常处理器
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { ModelAndView mv = new ModelAndView(); mv.addObject("ex", e); mv.setViewName("/erro/error-page.jsp"); if(e instanceof NameException){ System.out.println("name error"); } if(e instanceof AgeException){ System.out.println("age error"); } return mv; }
<bean class="com.xx.exception.resolver"/>
注解式自定义异常处理器
@ExceptionHandler(NameException.class)
public ModelAndView resolveException(Exception e) {
ModelAndView mv = new ModelAndView();
mv.addObject("ex", e);
System.out.println(e.getMessage());
return mv;
}
改代码写在 ExceptionResolverController中,继承自BaseController(即MyController)
类型转换器
自定义类型转换器
public class MyDataConvert implements Converter<String, Date> {
@Override
public Date convert(String s) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
return sdf.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
注册类型转换器
<!-- 注册类型转换器--> <bean id="myDataConvert" class="com.lh.handlers.MyDataConvert"/> <!-- 注册转换服务对象--> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters" ref="myDataConvert"/> </bean> <mvc:annotation-driven conversion-service="conversionService"/>
文件上传
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"/>
<property name="maxUploadSize" value="1048576"/>
</bean>
@RequestMapping(value = "/test01", method = RequestMethod.POST) public ModelAndView doFile(MultipartFile photo, HttpSession session) throws IOException { if (!photo.isEmpty()){ String path = session.getServletContext().getRealPath("/images"); String fileName = photo.getOriginalFilename(); System.out.println(path); assert fileName != null; if (fileName.endsWith(".jpg") || fileName.endsWith(".png")){ File file = new File(path, fileName); photo.transferTo(file); } }else { return new ModelAndView("fail.jsp"); } return new ModelAndView("success.jsp"); }
拦截器
public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return false; // 执行false表示被拦截 } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
注册拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.xx.interceptors.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>