Spring MVC
[TOC]
配置文件
配置核心控制器
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- SpringMVC的配置文件,在src目录下 -->
<param-value>classpath:springMVC-servlet.xml</param-value>
</init-param>
<!-- 启动顺序:表示启动容器时初始化该Servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<!-- 拦截所有.do请求 -->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
解决post中文乱码
<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>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Spring MVC基本配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
</beans>
servlet 扫描器
<!-- servlet扫描器 , 扫描指定包下的所有类 -->
<context:component-scan base-package="com.zzsong.controller"></context:component-scan>
视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/index/" />
<property name="suffix" value=".jsp" />
</bean>
文件上传解析器
<!-- 文件上传的 解析器的配置 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 最大缓存大小 -->
<property name="maxInMemorySize">
<value>40960</value>
</property>
<!-- 上传最大限制 -->
<property name="maxUploadSize">
<value>10485760000</value>
</property>
<!-- 上传文件编码 -->
<property name="defaultEncoding">
<value>UTF-8</value>
</property>
</bean>
JSON解析器
<!-- JSON解析器 -->
<bean id="stringConverter"
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
<bean id="jsonConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="stringConverter" />
<ref bean="jsonConverter" />
</list>
</property>
</bean>
拦截器
-
拦截器的配置
<!-- 配置拦截器 --> <mvc:interceptors> <mvc:interceptor> <!-- 设置拦截路径 --> <mvc:mapping path="/**" /> <!-- 拦截器完全限定名 --> <bean class="com.zzsong.interceptor.MyInterceptor"> <!-- 拦截器内存储不拦截的路径 --> <property name="allowpath"> <list> <value>hello.do</value> <value>login.do</value> </list> </property> </bean> </mvc:interceptor> </mvc:interceptors>
-
拦截器的使用
实现接口的方式
public class MyInterceptor implements HandlerInterceptor { public List<String> allowpath; public List<String> getAllowpath() { return allowpath; } public void setAllowpath(List<String> allowpath) { this.allowpath = allowpath; } //整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion。 @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { } // 后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。 @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { } // 预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器 //返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应; @Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { String servletPath = arg0.getServletPath(); for (String string : allowpath) { if (servletPath.contains(string)) { return true; } } arg1.sendRedirect("login.do"); return true; } }
继承类的方式
public class MyInterceptor extends HandlerInterceptorAdapter { public List<String> allowpath; public List<String> getAllowpath() { return allowpath; } public void setAllowpath(List<String> allowpath) { this.allowpath = allowpath; } // 预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器 //返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String servletPath = request.getServletPath(); for (String string : allowpath) { if (servletPath.contains(string)) { return true; } } response.sendRedirect("login.do"); return true; } }
使用方法
基本使用方式
@Controller
public class MyController {
@RequestMapping("/login.do")
public String login() {
return "forward:/hello.do";
}
}
窄化请求映射
package cn.javass.chapter6.web.controller;
@Controller
@RequestMapping(value="/user") //①处理器的通用映射前缀
public class HelloWorldController2 {
@RequestMapping("/login.do") //②相对于①处的映射进行窄化
public String login() {
return "forward:/hello.do";
}
}
转发到其他servlet
/**
* 转发到其他servlet
*/
@RequestMapping("/login.do")
public String login() {
return "forward:/hello.do";
}
重定向到其他servlet
/**
* 重定向到其他servlet
*/
@RequestMapping("/login.do")
public String login() {
return "redirect:/hello.do";
}
带参转发
-
方式一
@RequestMapping("/hello.do") public ModelAndView index() { ModelAndView mv = new ModelAndView(); StuInfo s = new StuInfo(); s.setName("sdafas"); s.setPsw("21412"); //等同于request.setAttribute mv.addObject("msg", s); //将需要跳转到JSP名放入 mv.setViewName("hello"); return mv; }
-
方式二
@RequestMapping("/hello.do") public String index(ModelMap mm) { StuInfo s = new StuInfo(); s.setName("sdafas"); s.setPsw("21412"); mm.addAttribute("msg", s); return "hello"; }
文件上传
@RequestMapping("/upload.do")
public String upload(@RequestParam("file") CommonsMultipartFile cf[], HttpServletRequest
request, String name) {
String path = request.getServletContext().getRealPath("/");
for (int i = 0; i < cf.length; i++) {
String fileName = cf[i].getOriginalFilename();
try {
cf[i].transferTo(new File(path, fileName));
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
}
return "forward:/hello.do";
}
AJAX
-
直接返回字符串
@RequestMapping("/account.do") @ResponseBody public void account(String account, HttpServletResponse response) throws IOException { PrintWriter writer = response.getWriter(); if ("123".equals(account)) { writer.print("ok"); } else { writer.print("err"); } writer.close(); }
-
返回集合或对象
@RequestMapping("/getstu.do") @ResponseBody public List<StuInfo> getstu() throws IOException { List<StuInfo> stus = new ArrayList<>(); StuInfo s1 = new StuInfo("小红", "123"); StuInfo s3 = new StuInfo("小明", "456"); stus.add(s1); stus.add(s3); return stus; }
-
返回JSON
需要使用相关的JSON处理jar包
@RequestMapping("/getstu.do") @ResponseBody public String getstu() throws IOException { List<StuInfo> stus = new ArrayList<>(); StuInfo s1 = new StuInfo("小红", "123"); StuInfo s3 = new StuInfo("小明", "456"); stus.add(s1); stus.add(s3); return JSON.toJSONString(stus); }