Spring MVC 编程基础
Spring MVC 编程基础
1. Spring MVC 概述
2. Spring MVC 编程基础
2.2.1. 创建Maven WEB 项目并添加Spring MVC 依赖
2.2.2. 添加Spring MVC配置文件并进行基本配置
3. Spring MVC 请求处理
4. Spring MVC 响应处理
1.简介
1. 1.Spring MVC 概述
企业级应用中的软件的分层的基本架构

说明:分层架构的本质是分而治之,已达到分解问题复杂性的目的,从而更好的进行设计与实现。Ss
基于servlet,jsp,javabean技术实现的MVC架构,具体架构图如下:

Spring MVC是MVC架构模式的一种完美实现,它简化了Java WEB 中基于MVC架构的编程过程,是Spring中的WEB应用模块。
Spring MVC 底层核心架构图及工作流程(先了解,写完项目案例再重点强化)

Spring MVC 中的核心组件:
1)DispatcherServlet (前端控制器, 处理请求的入口)
2)HandlerMapping (映射器对象, 用于管理url与对应controller的映射关系)
3)Interceptors(拦截器,实现请求响应的共性处理)
4)Controller (后端控制器, 负责处理请求的控制逻辑)
5)ViewResolver(视图解析器,解析对应的视图关系:前缀+view+后缀)
备注:假如希望了解Spring MVC的详细处理流程可以基于断点调试法进行跟踪。
2.Spring MVC 编程基础
-
Step01:创建maven web 项目并解决项目中的错误问题
-
Step02:添加Spring MVC项目核心依赖
-
Step03:配置Spring MVC项目核心组件
-
Step04:创建Spring MVC 后端控制器及页面
-
Step05:部署及测试spring mvc 项目应用。
2.2.1.创建Maven WEB 项目并添加Spring MVC 依赖
Step01:创建maven web项目
1)项目名 CGB-SPRING-MVC-01


2)Web项目打包方式为war方式

Step02:配置maven web项目
1)生成web.xml

2)Web项目的target runtimes为tomcat

3)Web 项目的编译版本为JDK1.8

Step03: 添加Spring MVC项目依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
</dependencies>
在项目的resources的目录中添加核心配置文件(例如spring-configs.xml)并进行基本配置
<?xmlversion="1.0"encoding="UTF-8"?>
<beansdefault-lazy-init="true"
xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/aop_
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd_
http://www.springframework.org/schema/util_
http://www.springframework.org/schema/util/spring-util-4.3.xsd_
http://www.springframework.org/schema/data/jpa_
http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd_
http://www.springframework.org/schema/context_
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!--配置组件扫描 -->
<context:component-scanbase-package="com.jt"/>
<!—启用MVC默认配置 (@RequestMapping) -->
<mvc:annotation-driven/>
<!-- 配置视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<propertyname="prefix"value="/WEB-INF/pages/"/>
<propertyname="suffix"value=".jsp"/>
</bean>
</beans>
说明:配置文件的名字可以自己指定。
打开web.xml,配置DispatcherServlet对象
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-configs.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>\*.do</url-pattern>
</servlet-mapping>
前端控制器是spring mvc处理请求的入口,是springmvc的核心,这个控制器一般需要在服务器启动时即初始化。
其中
- load-on-startup 表示启动时则加载此servlet,数字越小优先级越高.
- init-param 中的参数名不能变(此名字在DispatcherServlet父类中定义)
编写Spring MVC后端控制器
@Controller
@RequestMapping("/")
public class HelloController{
@RequestMapping("doSayHello")
public ModelAndView doSayHello(String msg) {
ModelAndView mv= new ModelAndView("hello");
mv.addObject("message", "helloworld");
return mv;
}
}
其中:
-
通过@RequestMapping注解定义url到controller具体方法的映射,这个映射信息会被存储,一般是存储到一个HandlerMapping对象中.
-
ModelAndView对象为一个模型与视图对象,内置一个map对象,主要用于封装业务数据和视图名。
-
ModelAndView构造方法中传递的为视图名,addObject方法可以以key/value形式存储数据。
-
ModelAndView 对象返回时会被spring mvc自动存储到请求作用域,在对应的视图页面可以直接从此作用域获取对应的值。
在项目的WEB-INF/pages文件夹下创建hello.jsp文件,然后设置其内容,例如
<body>
<h1>${message}</h1>
</body>
说明:WEB-INF目录下的资源不能允许通过浏览器地址栏直接访问。
将项目部署到tomcat,然后启动运行,在地址栏输入具体url访问对应controller对象。
问题分析:
-
tomcat启动时出现ClassNotFoundException,而这个class又不是我们自己的类,此时要重新maven update,重新发布(右键tomcat 重新publish),多次尝试还是不可以,此时重启eclipse。
-
404异常,一般表示服务端资源没找到,首先检测访问路径是否正确,然后还可以在项目的部署目录中去查找对应的资源,必须确保资源是存在的,假如资源不存在,说明代码没有正常编译。(很常见)
-
如何解决这种项目不编译的问题?
-
停止tomcat将tomcat下的项目移除,并clean你的tomcat服务器(两个clean)
-
对项目进行maven clean操作(清除原先编译结构,然后重新编译)
-
再次对项目进行clean操作(菜单栏中的project clean)
-
重新部署项目,启动tomcat运行
-
假如经历了以上几个步骤,还没解决此问题,重启eclipse再试
说明:假如你的eclipse经常出现类似问题,换jdk。
-
-
运行项目时尽量不要右键运行选在run as /run on server
项目的请求处理流程结构及过程解析:

-
客户端向服务服务端发请求
-
服务端对请求信息进行过滤(Filter)
-
请求到达前端控制DispatcherServlet
-
前端控制器基于url在HandlerMapping中的映射找请求执行链
-
执行执行链中的拦截器(Interceptor)方法
-
执行执行链中的控制器(Controller)方法
-
对象控制层返回的视图进行解析
-
向客户端返回一个响应结果。
3.Spring MVC 请求处理
实际项目中我们要借助@RequestMapping注解定义映射路径。其注解应用位置
- 类定义处: 提供初步的请求映射信息。
- 方法定义处: 提供进一步的细分映射信息
@RequestMapping(value={"/doSayHello", "/user/doSayWelcome"})
多个URL路径可以映射到同一个处理器的功能处理方法。
REST即表述性状态传递(英文:Representational State Transfer,简称REST),是一种软件架构编码风格,是基于网络应用进行设计和开发的编码方式。可以降低开发的复杂度,提高程序的可伸缩性。例如:
@RequestMapping("/msg/{xxx}")
请求的URL可以是"/msg/hello"或"/msg/welcome"
@RequestMapping("/msg/{id}/create")
请求的URL可以是"/users/1/create"。
@RequestMapping("/msg/{mId}/topics/{tId}")
这样也是可以的,请求的URL可以是"/users/10/topics/12"。
说明:通过@PathVariable可以提取URI模板模式中的{×××}中的×××变量。
http://localhost:8080/项目名/doUpdate/1.do
项目中Controller层对象的每个方法默认可以处理任意方式的请求,假如要指定控制层方法只能处理GET或只能处理POST请求,那该如何实现呢?
借助@RequestMapping注解中的method属性指定具体的请求处理方式,例如
@RequestMapping(value="doSaveObj", method=RequestMethod.POST)
public String doSaveObject(Object obj){
}
知识点扩展:
-
@GetMapping 注解应用(定义的映射只能处理get请求)
-
@PostMapping 注解应用(定义的映射只能处理post请求)
项目中还可在控制层方法上借助@RequestMapping注解中的method属性指定使用哪几种方式处理请求。
@RequestMapping(value="doSaveObj", method={RequestMethod.POST,RequestMethod.GET})
public String doSaveObject(Object obj){
}
提示:一般浏览器只支持GET或POST方式。
请求映射方法中可以直接使用ServletAPI 中的对象获取参数数据,例如
HttpServletRequest,HttpSession对象等,例如:
@RequestMapping(value="withRequest",method=RequestMethod.GET )
@ResponseBody
public String withRequest(HttpServletRequest request){
System.out.println(request.getRequestURI());
return"Obtainer 'foo' query parameter value '"+request.getParameter("gid")+"'";
}
提示:@ResponseBody注解作用:该注解作用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区,使用情况:返回的数据不是Html标签的页面,而是其他数据格式的数据时,(如Json、xml,普通文本等)使用;
SpringMVC 请求一个控制层资源时,可以在对应方法中直接使用参数变量接收参数数据,但参数变量的类型建议为对象类型。
使用String类型变量接受请求参数的值:
@RequestMapping(value="withStringParam",method=RequestMethod.GET )
@ResponseBody
public String withStringParam(@RequestParam String foo) {
return"Obtained 'foo' query parameter value '" + foo + "'";
}
提示:@RequestParam注解用于接收请求参数中名字为foo的参数值,假如请求参数名与方法中的参数名一致,@RequestParam注解可以省略。假如不一致则可以使用@RequestParam注解定义新的参数名直接接收页面数据,然后传递给方法名,还有就是请求参数中包含特殊字符时,需要借助@RequestParam注解对参数进行声明。例如
@RequestMapping(value="withStringParam", method=RequestMethod.GET )
@ResponseBody
public String withStringParam(
@RequestParam(value="param-01",required= false ) String foo) {
return"Obtained 'foo' query parameter value '" + foo + "'";
}
提示:required=false表示,参数可以不存在,假如为true(默认),参数不存在时会抛出异常(400异常)。
使用Date类型变量接受请求日期参数的值:
@RequestMapping(value="withDateParam")
@ResponseBody
public String withDateParam(Date birthday) {
return"Obtained date parameter value '" + birthday + "'";
}
Spring MVC 默认支持yyyy/MM/dd格式日期转换,假如日期格式不匹配会报400异常
使用Integer类型的可变参数或数组接收请求数据
@RequestMapping(value="withVarParam")
@ResponseBody
public String withVarParam(Integer… ids) {
return"Obtained ids parameter value '" + ids + "'";
}
当请求中多个参数时可以通过在方法中定义多个参数接收参数数据,也可以利用一个javabean对象接收多个参数数据以简化多个参数变量的定义。
@RequestMapping(value="withParamGroup",method=RequestMethod.GET )
@ResponseBody
public String withParamGroup(SysLog entity) {
return"Obtained javabean parameter group " + entity;
}
提示:当使用javabean接收请求参数数据时,bean中需要有与参数名对应的set方法。
说明: 通过map接收页面参数时,需要使用@RequestParam注解声明
@RequestMapping("doMap02")
public String withParamGroup (
@RequestParam Map<String,Object> map) {
return"Obtained map parameter group " + map;
}
提示:此时的map不能再作为响应数据的封装对象
SpringMVC请求资源路径的URL可以通过{XXX}形式指定动态的URL,动态URL中的这个可变参数的值可以直接注入到方法对应的参数中。
@RequestMapping(value="path/{var}",method=RequestMethod.GET )
@ResponseBody
public String withPathVariable(@PathVariable String var) {
return"Obtained 'var' path variable value '" + var + "'";
}
通过@PathVariable注解指定参数变量var获取请求url中{var}数据
当服务端要获取客户端请求头中数据信息时,可通过@RequestHeader即可将请求头中
的属性值绑定到处理方法的入参中,例如获取请求中Accept属性的值,然后传入到对应方法的参数中。
@RequestMapping(value="header", method=RequestMethod.GET )
@ResponseBody
public String withHeader(@RequestHeader String Accept) {
return"Obtained 'Accept' header '" + Accept + "'";
}
假如希望在此方法中直接从cookie取值,可以定义参数时使用@CookieValue对参数进行修饰,参数名一般要与cookie对象中的key相同
@RequestMapping(value="withCookie")
@ResponseBody
public String withCooke(
@CookieValue String JSESSIONID) {
return"Obtained COOKIE Value '" + JSESSIONID + "'";
}
提示:方法中的参数名需要与请求头参数中某个参数名相同,具体请求头相关信息可以在浏览器控制台查看。
当应用中要获取请求中所有数据时可以在请求方法中定义一个HttpEntity
@RequestMapping(value="entity", method=RequestMethod. **POST** )
public @ResponseBody String withEntity(
HttpEntity<String> entity) {
return"Posted request body " + entity.getBody() + "
headers = " + entity.getHeaders();
}
如上写法:了解
4.Spring MVC 响应处理
4.1.响应数据封装
4.1.1.Servlet API 对象(了解)
将请求数据直接封装到Request 对象
@RequestMapping("doResponse01")
public String doResponse01(HttpServletRequest request) {
request.setAttribute("data", "hello..");
return"response";
}
在response.jsp页面可以直接借助${data}方式获取数据。
当方法中直接返回一个页面时,默认执行的是请求转发,假如需要实现重定向,
可以在返回的地址后添加redirect,例如
return "redirect:responseUI.do"; 其中responseUI.do对应一个请求url.
@RequestMapping("doResponse02")
public String doResponse02(HttpServletRequest request) {
request.setAttribute("data", "hello..");
return"redirect:responseUI.do";
}
在如上方法中可以重定向到一个responseUI对应的新的URL。
@RequestMapping("responseUI")
public String responseUI() {
return"response";
}
在新的请求中不能直接获取上一个请求作用域的数据。
回顾请求转发与重定向:
1)请求转发(forward)

- 3)重定向(redirect)

在对服务端响应数据进行封装时,可以直接在方法参数中定义一个ModelAndView类型的参数,借助ModelAndView对象封装响应数据.
@RequestMapping("doModelAndView")
public ModelAndView doModelAndView(ModelAndView mv) {
//ModelAndView mv=new ModelAndView();
mv.addObject("data", "model and view");
mv.setViewName("response");//view
return mv;
}
提示:ModelAndView 对象由Spring创建,并可以将数据存储到ModelAndView对象的ModalMap类型的属性中(可参考源代码).
将响应数据直接封装为model中。
@RequestMapping("doModel")
public String doModel(Model model) {
model.addAttribute("data", "modal");
return"response";
}
当我们返回具体view时,系统底层会自动将model对象存储到request作用域。
将响应数据封装到Map中(我建议假如使用map对数据进行封装,可直接采用model对象)。
@RequestMapping("doMap01")
public String doMap01(Map<String,Object> map) {
map.put("data", "map..");
return"response";
}
4.2.响应数据转换JSON(重点)
4.2.1.JSON 应用概述
JSON(JavaScript Object Notation):一种轻量级数据交换格式,通常作为客户端与服务端进行数据交互的一种标准。
企业级Java项目数据传输方式:

reponse.getWriter().write(jsonStr);
客户端访问服务端时,服务器从数据库取出数据进行封装,然后再将对象转换为json串,通过网络传输到客户端。
spring 中默认支持jackson应用的,但使用时需要添加jackson依赖,例如
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.5</version>
</dependency>
创建Controller中例如ResponseController,然后在类中添加对应方法。例如
将Map对象内容转换为字符串(spring底层会直接访问jackson api将对象转换为字符串)
@RequestMapping("doMap")
@ResponseBody
public Map<String,Object> doMap(){
Map<String,Object> map= new HashMap<>();
map.put("id", 100);
map.put("name", "AAA");
return map;
}
将JavaBean对象转换为JSON串
@RequestMapping("doUser")
@ResponseBody
public SysLog doLog(){
SysLog log= new SysLog ();
log.setId(100);
log.setUsername("CCC");
log.setIP("192.168.1.12");
return log;
}
将Java List集合转换为JSON串。
@RequestMapping("doList")
@ResponseBody
public List<SysLog> doList(){
List<SysLog> list= new ArrayList<>();
SysLog log= new SysLog ();
log.setId(100);
log.setUsername("CCC");
log.setIP("192.168.1.12");
list.add(log);
log= new SysLog ();
log.setId(100);
log.setUsername("CCC");
log.setIP("192.168.1.12");
list.add(log);
return list;
}
备注:将来controller中数据来自服务端数据。

浙公网安备 33010602011771号