Spring MVC
Spring MVC
MVC:View(视图)、Controller(控制器)、Model(模型)
Spring MVC的核心Controller控制器(相当于中介),用于处理请求,产生响应。
Spring MVC基于Spring IOC容器运行,所有对象陂IOC管理。
Spring MVC环境配置
Maven依赖spring-webmvc
web.xml配置DispatcherServlet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<!-- DispatchServlet -->
<servlet>
<servlet-name>springmvc</servlet-name>
<!--
Dispatcherservlet是spring MVC最核心的对象
Dispatcherservlet用于拦截Http请求,并根据请求的URL调用与之对应的Controller方法,来完成Http请求的处理
-->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--applicationContext.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<!-- 在web应用启动时自动创建Spring IOC容器并初始化DispatchServlet -->
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--"/”代表拦截所有请求-->
<url-pattern>/</url-pattern>
</servlet-mapping>配置applicationContext的mvc标记
1
2
3
4
5
6
7
8
9
10
11
12
13<!--
context:component-scan 标签作用
在Spring Ioc初始化过程中,自动创建并管理com.codewhale及子包中拥有以下注解的对象.
@Repository
@Service
@Controller
@Component
-->
<context:component-scan base-package="com.codewhale"></context:component-scan>
<!--启用Spring Mvc的注解开发模式-->
<mvc:annotation-driven/>
<!--将图片/JS/CSS等静态资源排除在外,可提高执行效率-->
<mvc:default-servlet-handler/>开发Controller控制器
1
2
3
4
5
6
7
8
public class TestController{
// 通过localhost/t访问
//直接向响应输出字符串数据,不跳转页面
public String Test(){
return "Yes!";
}
}
Spring MVC数据绑定
URLMapping(URL映射)
URL Mapping指将URL与Controller方法绑定
通过将URL与方法绑定,SpringMVC便可通过Tomcat对外暴露服务
Controller方法参数接收
接收请求参数的常用做法
使用Controller方法参数接收
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<form action="/m1" method="post">
<input name="username"/>
<input name="password"/>
</form>
-----------------------------------------------------------------
public String postMapping(String username , Long password){
return username + ":" + password;
}
//@RequestParam 参数映射
public String postMapping( String managerName){
return managerName;
}使用Java Bean接收数据
1
2
3
4
5
public String postMapping(User user){
return user.getUsername() + ":" + user.getPassword;
}可以通过Map或者List集合对复合数据进行接收,但是Map只能接收单一数据,想要接收复合数据(如复选框数据)则需要使用List集合进行接收。
关联对象赋值
复杂表单
1
2
3
4
5
6用户名:<input name="username">
密码: <input name="password">
姓名:<input name="idcard.name">
身份证:<input name="idcard.idno">
过期时间:<input name="idcard.expire">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// IdCard类
public class IdCard{
private String name;
private String dino;
private String exprire;
// 以下set/get方法省略....
}
// From表单类
public class From{
private String username;
private String password;
private IdCard idcard = new IdCard();
// 以下set/get方法省略....
}日期类型转换
使用@DateTimeFormat注解对日期参数进行格式化。
1
全局默认日期转换
创建一个转换器类进行转换。
1
2
3
4
5
6
7
8
9
10
11public class MyDateConverter implements Converter<String, Date> {
public Date convert(String s){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date d = sdf.parse(s);
return d;
} catch(ParseException e) {
return null;
}
}
}1
2
3
4
5
6
7
8
9
10<!-- applicationContext.xml配置文件中配置转换器类 -->
<mvc:annotation-driven conversion-service="conversionService">
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.codewhale.converter.MyDateConverter"/>
</set>
</property>
</bean>
Web应用中文乱码问题解决
Tomcat默认使用字符集ISO-8895-1,属于西欧字符集,所以中文会出现乱码问题,只需要将该字符集转换成UTF-8即可解决。
Controller中请求和响应都需要设置UTF-8字符集。
Get请求乱码 - 在Tomcat配置文件(server.xml)中的增加URlEncoding属性,Tomcat 8.0版本之后默认使用UTF-8。
Post请求乱码 - web.xml配置CharacterEncodingFilter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<!-- web.xml配置文件中配置filter -->
<filter>
<filter-name>characterFilter</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>characterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>Response响应乱码 - Spring配置StringHttpMessageConverter
1
2
3
4
5
6
7
8
9
10
11
12
13<!-- applicationContext.xml配置文件中配置 -->
<mvc:annotation-driven conversion-service="conversionService">
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<!-- response.setContentType("text/html;charset=utf-8") -->
<value>text/html;charset=utf-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
响应输出结果
@ResponseBody - 产生响应文本
- @ResponseBody直接产生响应体的数据,过程不涉及任何视图
- @ResponseBody可产生标准字符串/JSON/XML等格式数据
- @ResponseBody被StringHttpMessageConverter所影响
ModelAndView - 利用模板引擎渲染输出
ModelAndView对象是指”模型(数据)与视图(界面)”对象
通过ModelAndView可将包含数据对象与模板引擎进行绑定
SpringMVC中默认的View是JSP,也可以配置其他模板引擎
1
2
3
4
5
6
7
8
public ModelAndView showView(Integer id) {
ModelAndView mav = new ModelAndView("/text.jsp");
User user = new User();
user.setId(id);
mav.addObject("u", user)
return mav;
}text.jsp代码:
1
<h1>${u.id}</h1>
ModelAndView核心
mav.addObject()方法设置的属性默认存放在当前请求中
默认ModelAndView使用请求转发(forward)至页面
重定向使用 new ModelAndView(“redirect:/index.jsp”)
重定向和请求转发的区别,数据关联不大时使用重定向(例如注册页面注册成功跳转到首页时)。
相对路径:text.jsp
绝对路径(推荐):/text.jsp
String与ModelMap
1
2
3
4
5
6
7
8
9
10//Controller方法返网string的情况
//1.方法被@ResponseBody描述,SpringMvc直按响应String字符串本身
//2.方法不存在@Responsedody,则SpringMVc处理String指代的视图(页面)
public String showView(Integer id, ModelMap modelMap){
String view = "/test/test.jsp";
User user = new User();
user.setId(id);
modelMap.addAttribute("u", user);
return view;
}
SpringMVC整合Freemarker
pom.xml中引入依赖
1
2
3
4
5
6
7
8
9
10<dependency>
<groupld>org.freemarker</groupld>
<artifactld>freemarker</artifactld>
<version>2.3.28</version>
</dependency>
<dependency>
<groupld>org.springframework</groupld>
<artifactld>spring-context-support</artifactld>
<version>5.1.9.RELEASE</version>
</dependency>启用Freemarker模板引擎
1
2
3
4
5
6<bean id="ViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<!--设置响应输出,并解决中文乱码 -->
<property name="contentType" value="text/html;charset=utf-8"></property>
<!--指定Freemarker模板文件扩展名 -->
<property name="suffix" value=".ftl"/>
</bean>配置Freemarker参数
1
2
3
4
5
6
7
8
9
10
11<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<!--设置模板保存的目录-->
<property name="templateLoaderPath" value="/WEB-INF/ftl"/>
<!--其他模板引擎设置-->
<property name="freemarkerSettings">
<props>
<!--设置Freemarker脚本与数据渲染时使用的字符集-->
<prop key="defaultEncoding">UTF-8</prop>
</props>
</property>
</bean>
RESTful开发风格
开发规范
- 使用URL作为用户交互入口
- 明确的语义规范(GET | POST | PUT | DELETE)
- 只返回数据(JSON | XML),不包含任何展现
RestController注解
该注解可以代替方法上的@Response注解,简化开发。
路径变量
1
2
3
4
5// Get /test/1
public String doGetRequest( Integer id){
return id;
}简单请求与非简单请求
简单请求是指标准结构的HTTP请求,对应GET/POST请求
非简单请求是复杂要求的HTTP请求,指PUT/DELETE、扩展标准请求
两者最大区别是非简单请求发送前需要发送预检请求JSON序列化
Jackson用于JSON序列化。引入依赖后自动开启无需配置。
使用时需同时导入jackson-core、jackson-databind和jackson-annotations三个依赖。
对于日期类型的数据,需要对该类型进行格式化。
1
2
private Date birthday;
跨域资源访问问题(CORS)
CORS是一种机制,使用额外的HTTP头通知浏览器可以访问其他域
URL响应头包含 Access-Control-*指明请求允许跨域SpringMVC解决跨域访问
@CrossOrigin - Controller跨域注解
1
2// maxAge参数:预检请求进行缓存,减轻服务器压力,因为每一个非简单请求会发送两个请求(一个预检请求,一个实际请求)
<mvc:cors> - Spring MVC全局跨域配置
1
2
3
4
5
6
7<mvc:cors>
<mvc:mapping path="/**"
allowed-origins="http://example.com"
allowed-methods="GET, POST, PUT, DELETE"
allowed-headers="*"
allow-credentials="true"/>
</mvc:cors>
Spring MVC拦截器
拦截器(lnterceptor)用于对URL请求进行前置/后置过滤
Interceptor与Filter用途相似,但实现方式不同Interceptor底层就是基于Spring AOP面向切面编程实现
拦截器开发流程
Maven依赖servlet-api
1
2
3
4
5
6
7<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<!-- 只在开发编译时引用,不和打包后的冲突 -->
<scope>provided</scope>
</dependency>实现HandlerInterceptor接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class MyInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(request.getRequestURL() + "-准备执行");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println(request.getRequestURL() + "-目标处理成功");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println(request.getRequestURL() + "-相应内容已产生");
}
}HandlerInterceptor接口:
- preHandle - 前置执行处理
- postHandle - 目标资源已被Spring MVC框架处理
- afterCompletion - 响应文本已经产生
applicationContext.xml中配置过滤地址
1
2
3
4
5
6<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.codewhale.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>排除某些资源拦截(如ico、jpg、gif、js等)
1
2
3
4
5
6
7
8
9
10
11
12
13<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/**.ico"/>
<mvc:exclude-mapping path="/**.jpg"/>
<mvc:exclude-mapping path="/**.gif"/>
<mvc:exclude-mapping path="/**.js"/>
<mvc:exclude-mapping path="/**.css"/>
<!-- 将该目录下所有资源进行排除 -->
<mvc:exclude-mapping path="/resources/**"/>
<bean class="com.codewhale.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
应用:”用户流量“拦截器
电商:可通过拦截器获取到用户信息,针对某个产品的受众进行分析等等。
LogBack配置
logback.xml配置
additivity参数:设为false,则只在配置的指定文件中输出,反之则会向控制台中也输出一份。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<configuration>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%thread] %d %level %logger{10} - %msg%n</pattern>
</encoder>
</appender>
<appender name="accessHistoryLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>d:/logs/history.%d.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>[%thread] %d %level %logger{10} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="console"/>
</root>
<logger name="com.codewhale.interceptor.MyInterceptor" level="INFO" additivity="false">
<appender-ref ref="accessHistoryLog"/>
</logger>
</configuration>logback使用
1
2private Logger logger = LoggerFactory.getLogger(此类名称.class);
logger.info("信息");
Spring MVC处理流程





