SpringMVC
1.什么是SpringMVC?
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他WEB MVC开发框架,如Struts(现在一般不用),Struts2(一般老项目使用)等。
Spring MVC是属于Spring 框架的WEB模块中的一个部分。
参考Spring的体系结构图
SpringMVC是web层的mvc开发框架,属于Spring框架的WEB模块中的一个部分。
2.SpringMVC的执行流程
1.启动服务器的时候配置在web.xml文件中的中央控制器【DispatcherServlet】被初始化完成,并且加载配置的springMVC的配置文件。
2.客户端浏览器发送http请求。
3.http请求被中央控制器【DispatcherServlet】拦截,转交给url解析器解析。
4.Url解析器解析http请求,得到具体的请求路径。
5.Url解析器将解析得到的具体的请求路径返回给中央控制器【DispatcherServlet】。
6.中央控制器【DispatcherServlet】将得到的具体的请求路径转交给控制器适配器。
7.控制器适配器根据具体的请求路径查找与之对应的请求处理类。
8.请求处理类就执行具体的请求处理,得到ModelAndView对象【1.数据。2.跳转地址】,将ModelAndView对象交给控制器适配器,控制器适配器将ModelAndView对象返回给中央控制器【DispatcherServlet】。
9.中央控制器【DispatcherServlet】将ModelAndView对象转交给视图解析器去解析。
10.视图解析器解析ModelAndView对象,得到一个具体的数据显示路径,将这个具体的数据显示路径返回给中央控制器【DispatcherServlet】。
11.中央控制器【DispatcherServlet】得到具体的数据显示路径之后,将路径所代表的资源转换执行成一个html数据。
将转换执行后的html数据返回给客户端浏览器。
3.请求的访问路径配置
1.web.xml文件中DispatcherServlet配置的
1.1 /
对应 http://127.0.0.1:8080/springmvc1/add
1.2 .do
对应 http://127.0.0.1:8080/springmvc1/add.do
2.springmvc配置文件中的控制器的name属性值
控制器的name属性值设置要与web.xml文件中DispatcherServlet配置的
的配置形式一致
2.1 web.xml文件中DispatcherServlet配置的/那么springmvc配置文件中的控制器的name属性值应该为“/xxxx”
2.2 web.xml文件中DispatcherServlet配置的.do那么springmvc配置文件中的控制器的name属性值应该为“/xxxx.do”
以后控制器的name属性值会被@RequestMapper注解的value属性代替
4.ModelAndView类
1.请求处理方法的返回值是ModelAndView类
2.组成ModelAndView类的第一部分是一个Model【模型】封装数据
第二部分是一个View【视图】展示数据的页面元素
3.ModelAndView类是用来封装数据,展示数据的页面元素。
4.构造方法ModelAndView()来创建ModelAndView类的对象
ModelAndView mav=new ModelAndView();
5.封装数据的方法addObject(attributeName, attributeValue)相当于setAttribute(key,value)
mav.addObject(“username”,“zhangsan”);
6.设置展示数据的页面元素的名称setViewName(viewName)
mav.setViewName("test");
mav.setViewName("test.jsp");
mav.setViewName("test.html");
mav.setViewName("控制器对应的请求处理路径");
mav.setViewName("test");---forword跳转[转发]
mav.setViewName("forward:test.jsp");
mav.setViewName("redirect:test.jsp");----sendRedirect跳转[重定向]
5.视图解析器
InternalResourceViewResolver------解析展示数据的页面元素
<!-- 视图解析器 -->
<!-- 利用请求处理类中的得到的视图名,通过视图解析器的前缀和后缀合并得到一个完整的页面元素的访问路径。 -->
<!-- prefix+视图名称+suffix : 完整的页面元素的访问路径 -->
<!-- prefix==http://localhost:8080/demo1/ -->
<!-- 视图名称:ModelAndView中setViewName("test")的参数test -->
<!-- suffix:后缀[.jsp] -->
<!-- http://localhost:8080/demo1/test.jsp -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=""></property>
</bean>
6.DispatcherServlet中央处理器设置加载SpringMVC配置文件的设置
我们在启动程序的时候需要加载SpringMVC配置文件,此时这个SpringMVC配置文件的位置可能有所不同,SpringMVC配置文件在不同的位置是DispatcherServlet中央处理器如何配置SpringMVC配置文件的位置。
1.通过init-param元素配置加载SpringMVC配置文件
2.SpringMVC配置文件在src/main/resources文件夹下的时候:
src/main/resources----->springmvcconfig.xml
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvcconfig.xml</param-value>
</init-param>
3.SpringMVC配置文件在WEB-INF文件夹下的时候:
src/main/webapp/WEB-INF----->springmvcconfig.xml
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/myspringmvc.xml</param-value>
</init-param>
4.如果我们不在web.xml文件中配置init-param元素配置加载SpringMVC配置文件
1.将SpringMVC配置文件放放置在WEB-INF文件夹下
2.SpringMVC配置文件,名称“-servlet.xml”
例如:myspringmvc-servlet.xml
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<servlet>
SpringMVC配置文件
src/main/webapp/WEB-INF-------[springmvc-servlet.xml]
注意:通常情况下我们把SpringMVC配置文件/资源文件【jsp/html】放置在WEB-INF文件夹
7.请求处理方法接收请求参数值
http请求:http://localhost:8080/mvc/user/login/zhangsan/123456
请求参数:/zhangsan/123456
1.@PathVariable 定义在方法上获取请求url路径上的参数数据
例如:
package com.click369.springmvc.handler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping(value="/user")
public class UserHandler {
//处理注册请求的方法
@RequestMapping(value="/register1/{username}/{mypass}",method=RequestMethod.GET)
public ModelAndView registerMethod1(@PathVariable("username")String name,
@PathVariable("mypass")String pass)throws Exception{
System.out.println("name=="+name);
System.out.println("pass=="+pass);
ModelAndView mav=new ModelAndView();
mav.addObject("myname",name);
mav.addObject("mypass",pass);
mav.setViewName("test");
return mav;
}
}
http请求:http://localhost:8080/springmvcdemo1/test/my?name=zhangsan&password=123456
请求参数:name=zhangsan&password=123456
2.@RequestParam 定义在方法上,获取请求中通过key=value方式传递的参数数据
例如:get方式提交请求
//处理注册请求的方法
@RequestMapping(value="/register2",method=RequestMethod.GET)
public ModelAndView registerMethod2(@RequestParam("username")String name,
@RequestParam("password")String pass)throws Exception{
System.out.println("name=="+name);
System.out.println("pass=="+pass);
ModelAndView mav=new ModelAndView();
mav.addObject("myname",name);
mav.addObject("mypass",pass);
mav.setViewName("test");
return mav;
}
测试:http://localhost:8080/mvc/user/register2?username=lisi&password=000000
post方式提交请求
//处理注册请求的方法
@RequestMapping(value="/register3",method=RequestMethod.POST)
public ModelAndView registerMethod3(@RequestParam("username")String name,
@RequestParam("password")String pass)throws Exception{
System.out.println("name=="+name);
System.out.println("pass=="+pass);
ModelAndView mav=new ModelAndView();
mav.addObject("myname",name);
mav.addObject("mypass",pass);
mav.setViewName("test");
return mav;
}
3.HttpServletRequest对象接收数据
例如:
//处理注册请求的方法
@RequestMapping(value="/register4",method=RequestMethod.POST)
public ModelAndView registerMethod4(HttpServletRequest req)throws Exception{
String name=req.getParameter("username");
String pass=req.getParameter("password");
ModelAndView mav=new ModelAndView();
mav.addObject("myname",name);
mav.addObject("mypass",pass);
mav.setViewName("test");
return mav;
}
4.在请求处理方法中定义对应参数的变量,变量的名称与页面元素的name属性值相同
//处理注册请求的方法
@RequestMapping(value="/register5",method=RequestMethod.POST)
public ModelAndView registerMethod5(String username,String password)throws Exception{
//String name=req.getParameter("username");
//String pass=req.getParameter("password");
ModelAndView mav=new ModelAndView();
mav.addObject("myname",username);
mav.addObject("mypass",password);
mav.setViewName("test");
return mav;
}
8.SpringMVC的文件上传和下载
1.需要使用Apache的commons-fileupload组件【文件上传组件】
2.需要配置一个文件上传的视图解析器CommonsMultipartResolver
3.创建上传页面
1.表单的提交方式method一定是post
2.表单中的enctype属性一定是multipart/form-data
3.表单中的文件上传元素
4.创建文件上传的控制器
例如:
Pom.xml
<!-- 配置commons-fileupload的依赖 -->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
springmvc.xml
<!-- 上传文件的视图解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="104857600" />
<property name="maxInMemorySize" value="4096" />
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
Upload.jsp
<body>
<center>
<form action="upload" method="post" enctype="multipart/form-data">
<input type="file" name="myfile"/><br>
<input type="submit" value="上传文件">
</form>
</center>
</body>
TestUploadHandler.java
package com.click369.controller;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class UploadController {
@RequestMapping(value="/upload")
public ModelAndView uploadMethod(HttpServletRequest request)throws Exception{
ModelAndView mav=new ModelAndView();
//将当前类中的ServletContext对象转换成CommonsMultipartResolver
ServletContext servletContext=request.getSession().getServletContext();
CommonsMultipartResolver commonsMultipartResolver =new CommonsMultipartResolver(servletContext);
//检查form中是否有enctype="multipart/form-data"
if(commonsMultipartResolver.isMultipart(request)){
//将HttpServletRequest对象变成多部分MultipartHttpServletRequest
MultipartHttpServletRequest multipartreq=(MultipartHttpServletRequest)request;
//从MultipartHttpServletRequest对象中得到文件名称
Iterator<String> itname=multipartreq.getFileNames();
//变量Iterator
while(itname.hasNext()){
//得到文件名称
String nameshuxing=itname.next().toString();
//根据文件名称得到具体文件
MultipartFile multipartfile=multipartreq.getFile(nameshuxing);
String newfilename=System.currentTimeMillis()+multipartfile.getOriginalFilename().substring(multipartfile.getOriginalFilename().lastIndexOf("."));
if(multipartfile!=null){
// 获取项目的根目录
String realPath = servletContext.getRealPath("/uploadpic");
File uploadpicdir = new File(realPath);
if(!uploadpicdir.exists()){
//创建保存图片的文件夹路径
uploadpicdir.mkdirs();
}
String path=uploadpicdir.getAbsolutePath()+File.separator+newfilename;
//开始上传
multipartfile.transferTo(new File(path));
}
String reqURL=request.getRequestURL().toString();
reqURL=reqURL.substring(0,reqURL.lastIndexOf("/"));
reqURL=reqURL+"/uploadpic/"+newfilename;
}
mav.setViewName("success.html");
}else{
mav.setViewName("error.html");
}
return mav;
}
}
SpringMVC的文件下载:
例如:
<a href="dowload?filename=Java学习之路.txt">下在Java学习之路.txt</a>
@RequestMapping(value="/dowload")
public ResponseEntity<byte[]> dowloadMethod(HttpServletRequest req)throws Exception{
String filename=req.getParameter("filename");
String realPath = req.getSession().getServletContext().getRealPath("/uploadpic");
File uploadpicdir = new File(realPath);
File file=new File(uploadpicdir,filename);
System.out.println(file.getAbsolutePath());
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("attachment",filename);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.CREATED);
}
9.@Controller/@RequestMapping/@Service/@RestController/@Component/
@RequestBody/@ResponseBody**
@Controller用于标记一个类,使用它标记的类就是一个SpringMVC Controller 对象,即一个控制器类。Spring 使用扫描机制查找应用程序中所有基于注解的控制器类。
@RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
1、 value, method;
value: 指定请求的实际地址,指定的地址可以是URI Template 模式(后面将会说明);
method: 指定请求的method类型, GET、POST、PUT、DELETE等;
2、 consumes,produces;
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
3、 params,headers;
params: 指定request中必须包含某些参数值是,才让该方法处理。
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
@Service – service标注业务层组件
这个注解是写在类上面的,标注将这个类交给Spring容器管理,spring容器要为他创建对象
@RestController注解,相当于@Controller+@ResponseBody两个注解的结合,返回json数据不需要在方法前面加@ResponseBody注解了,但使用@RestController这个注解,就不能返回jsp,html页面,视图解析器无法解析jsp,html页面
使用@RestController注解,则不需要特意在方法前加@ResponseBody注解,而如果使用@Controller注解,则需要在直接返回json数据的方法前加上@ResponseBody注解,不然调用方法时会报404错。
@Component是一个元注解,意思是可以注解其他类注解,如@Controller @Service @Repository @Aspect。官方的原话是:带此注解的类看为组件,当使用基于注解的配置和类路径扫描的时候,这些类就会被实例化。其他类级别的注解也可以被认定为是一种特殊类型的组件,比如@Repository @Aspect。所以,@Component可以注解其他类注解。
@RequestBody的作用其实是将json格式的数据转为java对象。
@ResponseBody
需要用异步请求(AJAX)传数据给后台时,后台通过接收前台传来的数据,到数据库增、删、改、查后返回给前台一个对象或集合,经过接收方法上@ResponseBody的注解后直接将数据转换成json格式传给前台,如果没有@ResponseBody注解转换传到前台页面将会得到一个Object对象。