拒绝一切套路SpringMVC入门教程总结

开始

搭建SpringMVC环境

导入SpringMVC基础包

创建SpringMVC配置文件 spring-mvc.xml

在src目录下创建spring-mvc.xml配置文件,配置自动扫描Controller路径,加入InternalResourceViewResolver视图名称解析器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">

<!-- 自动扫描Controller -->
<context:component-scan base-package="com.xiaojiling.web"/>
<mvc:default-servlet-handler />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/View/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
</beans>

在web.xml中添加SpringMVC的配置

在web.xml中加入Dispatcherservlet前端控制器来拦截匹配的请求

1
2
3
4
5
6
7
8
9
10
11
12
13
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

建立Controller和jsp文件

新建路径com/xiaojiling/web 在路径下创建TestCon.java控制器类

并编写其中代码

1
2
3
4
5
6
7
8
@Controller
@RequestMapping("/Test")
public class TestCon {
@RequestMapping("/getHello")
public String getHello(){
return "Hello";
}
}

在WEB_INF下新建目录View在目录中新建Hello.jsp,并在body当中加入内容”你好”。

启动tomcat访问项目

启动tomcat并在本地访问你的项目

  • http ://localhost:8080/项目/Test/getHello

常用注解

@Controller
@RequestMapping
@RequestParam
@RequestBody
@ResponseBody
@ModelAttribute
@PathVariable
@ExceptionHandler
@ControllerAdvice

常用用法

示例

1
2
3
4
5
@RequestMapping(value="/{showIds}/iii",method = RequestMethod.POST)
public String getHello(@PathVariable String showIds){
System.out.println("将URL中占位符的值绑定到showIds上"+showIds);
return "Hello";
}

注解解释

@Controller 负责注册一个bean到spring上下文当中。
@RequestMapping用于处理请求地址映射,可注解在类上或方法上,注解在类上表示类中所有响应请求的方法都是以该注解地址作为父路径。
@RequestParam注解在参数上将指定的请求参数赋值给方法中的形参。如果不带注解同样可以赋值进去,可以通过@RequestParam(“id”)方式指定获取的参数。
@RequestBody注解接收json格式的字符串。
@ResponseBody注解可将方法的返回值以特定格式写入到response的body区域,进而将数据返回给客户端。当方法上面没有写ResponseBody,底层会将方法的返回值封装为ModelAndView对象。
@ModelAttribute
在方法上使用此注解,会在Controller每个方法执行之前都执行此方法。
在方法参数上使用此注解,可以从隐含对象中获取此参数的数据。
@PathVariable绑定URL当中占位符的值到参数当中。
@ExceptionHandler注解到方法上,Controller中其他方法出现异常后会执行该方法。
@ControllerAdvice注解在类上,使这个类成为全局Controller的异常处理类。

@ModelAttribute

在Controller中方法上加入此注解会在执行Controller之前执行此方法。下面方法中会隐含的将user对象存放于Model中

1
2
3
4
5
@ModelAttribute
public User helloModelA(@RequestParam(required = false) String name){
User user = new User(name);
return user;

@InitBinder处理Data类型参数

页面传递的某些数据是Date、Integer、Double等类型的时候,如果这些数据不做处理的话将无法绑定到参数上。

1
2
3
4
5
6
7
8
9
10
11
12
@InitBinder  
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}

@RequestMapping("/showData")
public String showData(Date date){
System.out.println(date);
return "Hello";
}

@ResponseBody注解返回json格式字符串

1
2
3
4
5
6
7
8
@RequestMapping(value = "getUser")
@ResponseBody
publicy User getUser(){
User user = new User()
user.setId(1);
user.setName("Wei");
return user;
}

添加 @ResponseBody注解后,此时我们不用做任何处理user对象会转换为json格式字符串。

@ExceptionHandler和@ControllerAdvice处理Controller异常

在View下定义error.jsp作为异常返回页面。在访问getError后会产生异常
java.lang.ArrayIndexOutOfBoundsException此时注解 @ExceptionHandler发挥作用返回异常页面,并且产生的异常一块儿返回过去。

1
2
3
4
5
6
7
8
9
10
11
   @ExceptionHandler
public ModelAndView exceptionHandler(Exception e){
ModelAndView modelandview = new ModelAndView("error");
modelandview.addObject("errMsg", e);
return modelandview;
}
@RequestMapping("/getError")
public void getError(){
int[] arr={1,2,3};
System.out.println(arr[3]);
}

@ControllerAdvice 定义全局异常处理类

1
2
3
4
5
6
7
8
9
 @ControllerAdvice
public class GetErrorController {
@ExceptionHandler
public ModelAndView errorHandler(Exception e){
ModelAndView modelandview = new ModelAndView("error");
modelandview.addObject("errMsg", e);
return modelandview;
}
}

注意:当代码当中有需要我们手动捕获的异常时候 @ExceptionHandler的结果似乎就变得不太明了。
如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
	@RequestMapping("/getError")
public void getError(){
String s = "kk";
try {
Date ss = new SimpleDateFormat().parse(s);
System.out.println(ss);
} catch (ParseException e) {
System.out.println("进入此异常块儿");
e.printStackTrace();
}
}

@ExceptionHandler
public ModelAndView exceptionHandler(Exception e){
ModelAndView modelandview = new ModelAndView("error");
System.out.println("这是异常信息"+e);
modelandview.addObject("errMsg", e);
return modelandview;
}

代码new SimpleDateFormat().parse(s) 需要我们手动捕获异常,如果在这里加入try catch语句,上面代码在异常之后会被catch语句捕获,而不会进入@ExceptionHandle注解的方法。

如果在异常方法上加入throws Exception抛出异常,则会进入@ExceptionHandle注解的方法。
当然在实际当中这类代码我们不会写在Controller里。

另一种处理全局异常的方法,在SpringMVC配置文件中加入配置

1
2
3
4
   <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="/error" />
<property name="exceptionAttribute" value="ex"></property>
</bean>

配置一个自己的拦截器

新建类MyInterceptor,并实现HandlerInterceptor接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MyInterceptor implements HandlerInterceptor{

@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
}

@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
}

@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("preHandle");
return true;
}

}

在SpringMVC配置文件中添加配置

1
2
3
4
5
6
7
</bean> 
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/Test/**"/>
<bean class="com.xiaojiling.web.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>

HandlerInterceptor接口定义了三个方法 preHandle、postHandle、afterCompletion。

preHandle当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。
postHandle调用Controller之后,进行渲染页面之前被调用。
afterCompletion调用完Controller接口,渲染页面之后调用。返回true的拦截器都会调用该拦截器的afterCompletion方法,这个方法的主要作用是用于进行资源清理工作的。

Spring整合SpringMVC

在src下添加Spring配置文件spring-context.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
>
<context:component-scan base-package="com.xiaojiling.service">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>

</beans>

在web.xml中添加spring的配置

1
2
3
4
5
6
7
 <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-context.xml</param-value>
</context-param>

在SpringMVC配置文件中加入一些配置,防止spring和springmvc对同一个对象进行管理

1
2
3
4
5
6
7
</mvc:interceptors>
<context:component-scan base-package="com.xiaojiling.web">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>

添加实体类User

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class User {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

添加UserService类

1
2
3
4
5
6
@Service
public class UserService {
public void get(){
System.out.println("get User");
}
}

添加UserController类

1
2
3
4
5
6
7
8
9
10
11
12
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;

@RequestMapping("/get")
public String get(){
userService.get();
return "hello";
}
}

项目如下

在浏览器上访问

控制台打印结果

SpringMVC运行流程图

在别人博客上找到的一张流程图

0%