是一种轻量级的,基于MVC的web应用层框架,对Servlet封装
MVC:
M:Model,模型层,指javaBean,作用是==处理数据==
javaBean:
实体类,业务处理,即Service,Dao
V:View,视图层,指工程中的html或jsp等页面,作用是与用户进行交互,==展示数据==
C:Controller,控制层,指工程中的servlet,作用是==接收请求==和==响应浏览器==
前端控制器(DispatcherServlet):接收请求,响应结果, 降低了组件之间的耦合性
2. 处理器映射器(HandlerMapping):根据URL去查找处理器
处理器适配器(HandlerAdapter):按照特定规则(HandlerAdapter要求的规则)去执行Handler
4. 处理器(Handler):即各个Controller(需要程序员去写代码处理逻辑的)
1.用户发起请求到前端控制器(DispatcherServlet)
2、前端控制器请求处理器映射器(HandlerMapping)去查找处理器(Handle):通过xml配置或者注解进行查找
3、找到Handle以后,处理器映射器(HandlerMapping)向前端控制器返回执行链(HandlerExecutionChain)(包括生成处理
器对象及处理器拦截器等)
4、前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)去执行处理器(==Handler,即Controller, 即Servlet层==)
5、处理器适配器(HandlerAdapter)去执行Handler中的方法
6、Handler执行完后,给处理器适配器返回ModelAndView
7、处理器适配器向前端控制器返回ModelAndView
8、前端控制器请求视图解析器(ViewResolver)去进行视图解析,解析成view
9、视图解析器(ViewResolver)向前端控制器返回View
10、前端控制器对视图进行渲染
11、前端控制器向用户响应结果
1、导入jar包
2、发起了一个请求
<a href="test">请求</a>
3、在web.xml中配置了核心控制器(前端控制器)
<servlet> <!--注册DispatcherServlet--> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定核心配置文件的位置 --> <init-param> <!--name值为固定内容--> <param-name>contextConfigLocation</param-name> <!--在src下配置的xml--> <param-value>classpath:springmvc.xml</param-value> </init-param> <!-- 启动tomcat就立即创建DispatcherServlet实例。数越小执行越早--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <!-- url-pattern:两种写法 1) *.do、 *.action、 *.mvc 2)斜杠 / --> <url-pattern>/</url-pattern> </servlet-mapping>
4、创建springmvc.xml核心配置文件
①:头部
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--各种配置--> </beans>
②:配置扫描
<!--开启mvc注解扫描 --> <mvc:annotation-driven/> <!--扫描controller包中所有的类,为创建controller对象 --> <context:component-scan base-package="com.bdqn.controller"></context:component-scan>
③:配置视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--前缀--> <!--jsp为放在WEB-INF下的文件:用于专门存放页面--> <property name="prefix" value="/WEB-INF/jsp/"></property> <!--后缀--> <property name="suffix" value=".jsp"></property> </bean>
5、创建Controller类
@Controller //创建Controller对象并放入到springmvc容器中 public class UserController{ @RequestMapping("/test") //配置请求映射路径 public String test(){ return "success";//返回的页面 } }
@RequestMapping()注解
1、位置
1、在类上:表示模块路径 2、在方法上:表示具体路径 (处理器方法、映射器方法)
2、属性
value="/路径":映射路径,斜杠可以省略,但不建议
method:请求方式
值:RequestMethod.GET 处理get请求
RequestMethod.POST 处理post请求
==注==:若没有method,则支持所有请求
<a href="user/del?id=1">删除</a> public String del(Integer id){ }
1、方法参数名和请求参数名==一致==的情况:
<a href="user/del?id=1&name=zs">删除</a> public String del(Integer id,String name){}
2、方法参数名和请求参数名==不一致==的情况,需要使用==@RequestParam==注解
public String showPage(@RequestParam(value="number",required=false,defaultValue="1")Integer curPage ){
@RequestParam注解:将请求参数绑定到方法参数上
value:接收的参数名
required:是否必须包含该参数,该参数内容是否可以为空, 默认为true(必须要传参数);false则相反
defaultValue:默认值,如果没有传参,则有默认值
3、以对象入参:请求参数必须和对象==实体类中的属性名一致==
public String add(User user) {}
public ModelAndView findAll(){ ModelAndView mv = new ModelAndView(); mv.addObject("user", user); //存储数据 mv.setViewName("student/list"); //存储视图 return mv; }
public String findAll(Model model){ model.addAttribute("user", user); //存储数据 return "student/list"; //返回视图 }
1、request:
public String 方法名(HttpServletRequest request){}
2、session:
public String 方法名(HttpSession session){}
3、response:
public void del(HttpServletResponse response) throws IOException{ response.setContentType("text/html;charset=utf-8"); //处理响应中文 //删除成功后,重新跳入到controller下的findAll方法中进行查询 response.getWriter().print("<script>alert('删除成功!');location.href='findAll';</script>"); }
public String findAll(Map<String,Object> map){ map.put("key",value); }
关键字:==redirect:==
public String 方法名(){ return "redirect:/stu/findAll"; }
在web.xml中配置
<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>
①:方法一
修改tomcat配置文件添加编码与工程编码一致,如下:
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
②:方法二
String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
如js、css、image、html等
原因:web.xml中配置了DispatcherServlet的url-pattern为“/”,导致所有的静态资源都交给了DispatcherServlet处理,而
DispatcherServlet不能处理静态资源的访问。所以导致静态资源的访问都是404。
1、第一种处理方式:
==需要依赖tomcat==
在springmvc.xml中配置: mvc:default-servlet-handler/
2、第二种处理方式: ==推荐==
在springmvc.xml中配置:
<mvc:resources location="/static/" mapping="/static/**"/><!--mvc:resoutces加入后框架会创建ResourceHttpRequestHandler对象,让该对象处理静态资源的访问问题,而不依赖tomcat服务器mapping:访问静态资源的url地址,使用通配符 **location:静态资源在项目中的目录位置-->
实现步骤:
1)在webapp下创建static文件夹,把images、js、css等都放入到该文件中
2)在springmvc中配置:
<mvc:resources location="/static/" mapping="/static/**"/>
3)页面使用:
<script type="text/javascript" src="static/js/jquery-1.12.4.js"></script> 相对路径 <img src="<%=basePath%>/static/images/read.jpg" alt="SpringMVC 最详细笔记必备知识点"/> 绝对路径 <img src="${pageContext.request.contextPath}/static/images/user/dongtu.gif" alt="SpringMVC 最详细笔记必备知识点"/> 绝对路径
方法一:
<%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>
方法二:
${pageContext.request.contextPath}
1、使用out输出流对象处理 + fastjson依赖
public void 方法名(HttpServletResponse response) throws IOException{ response.setContentType("text/html;charset=utf-8"); response.getWriter().print(返回的数据); (若返回类型为json,需要把对象转成json类型) }
2、使用@ResponseBody注解 + fastjson依赖
@RequestMapping(value="/路径",produces="text/html;charset=utf-8") @ResponseBody //通过response响应给用户,不再走视图解析器了,而是直接将数据写入到输出流中 public String 方法名(){ return 返回的数据; (若返回类型为json,仍需要把对象转成json类型) }
1、引入包:jackson-core-2.9.8.jar
2、controller处理:
1、处理返回text类型
@RequestMapping("/ajax") @ResponseBody//文件上传注解 public String 方法名(){ return str; }
2、处理返回json类型
public List<类型> 方法名(){ return list; } public 类型 方法名(){ return 对象; } public Map<类型,类型> 方法名(){ return map; }
3、处理返回html类型
public String 方法名(){ String str = "带有html标签的数据"; return str; }
①、表单提交格式必须是post提交
②、表单增加属性:enctype="multipart/form-data"
③、文本框增加name属性
④、提供文件域:
<form action="<%=basePath%>standardController/addON" method="post" enctype="multipart/form-data"> </form><input type="file" name="photo"/>
①:支持文件上传:commons-fileupload-1.4.jar
②:io流:commons-io-2.7.jar
$("[name=photo]").change(function(){ var val = $(this).val(); //获取当前文件的后缀 //substring:提取字符串中,介于两个指定下标之间的字符,设置一个值,即从那开始 //lastIndexOf():指定的字符串值最后出现的位置,从后往前查找 var zhui = val.substring(val.lastIndexOf(".")); if(zhui!=".jpg" && zhui!=".gif" && zhui!=".png" && zhui!=".bmp"){ alert("请选择正确的图片格式"); $(this).val("");//清空选中文件 } });
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
注意:
1)CommonsMultipartResolver:判断请求中是否包含文件,如果包含,则将请求的文件进行解析成MultipartFile,并传递给
controller
2)要求id必须是multipartResolver
@RequestMapping("/fileOn") public void fileOn(user u,MultipartFile photo,HttpSession session,HttpServletResponse response) throws IllegalStateException, IOException{ if(!photo.isEmpty()){//判断是否为空 //创建文件 String path=session.getServletContext().getRealPath("/static/updateFile/"); //获取当前文件的存储路径 System.out.println(path); File file=new File(path); //判断当前文件夹是否存在 if(!file.exists()){ //不存在创建 file.mkdirs(); } //文件名处理 //获取文件名 String filePD=FilenameUtils.getExtension(photo.getOriginalFilename()); //为文件取随机名;防止覆盖 String fileName=UUID.randomUUID().toString().replace("-", "").toUpperCase()+"."+filePD; //将文件名放到上方创建的updateFile中 file=new File(path,fileName); //文件上传 photo.transferTo(file); //将文件存入实体类对应列 u.setFileName(fileName); } int row=us.insertON(u); if(row!=0){ response.getWriter().print("<script>alert('插入成功');location.href='findAll'</script>"); }else{ response.getWriter().print("<script>alert('插入失败');history.back()</script>"); }
照片1:<input type="file" name="photos"><br/>照片2:<input type="file" name="photos"><br/>照片3:<input type="file" name="photos"><br/>
在循环外面经行文件创建
public void fileOn(user u,MultipartFile[] photos,HttpSession session,HttpServletResponse response){ //创建文件 String path=session.getServletContext().getRealPath("/static/updateFile/"); System.out.println(path); File file=new File(path); //判断当前文件夹是否存在 if(!file.exists()){ //不存在创建 file.mkdirs(); } for (int i = 0; i < photos.length; i++) { MultipartFile photo=photos[i]; if(!photo.isEmpty()){//判断是否为空 //文件名处理 //获取文件名 String filePD=FilenameUtils.getExtension(photo.getOriginalFilename()); //为文件取随机名;防止覆盖 String fileName=UUID.randomUUID().toString().replace("-", "").toUpperCase()+"."+filePD; //将文件名放到上方创建的updateFile中 file=new File(path,fileName); //文件上传 photo.transferTo(file); if(i==0){ u.setFileName1(fileName); }else if(i==1){ u.setFileName2(fileName); }else{ u.setFileName3(fileName); } } } int row=us.insertON(u); if(row!=0){ response.getWriter().print("<script>alert('插入成功');location.href='查询全部方法'</script>"); }else{ response.getWriter().print("<script>alert('插入失败');history.back()</script>"); }}
下载图片之外的文件等:
<a href="static/download/a.docx">下载doc</a>
下载图片:
<a href="static/download/read.jpg" download="read.jpg"> <img src="static/download/read.jpg" alt="SpringMVC 最详细笔记必备知识点" width="50" height="50"/> </a>
页面:
<a href="user/download?fileName=文件名">用文件流下载doc</a>
controller:
public void download(String fileName,HttpSession session,HttpServletResponse response) throws FileNotFoundException, IOException{ //文件路径为tomcate中的图片存储位置,自定义,依据文件上传创建的文件 String path = session.getServletContext().getRealPath("/static/updateFile/")+fileName;//获取文件路径 File f = new File(path); if(f.exists()){ //如果文件存在,则下载 //设置响应头,以附件形式进行下载(激活下载框,文件名会自动填充到下载框中) response.addHeader("Content-Disposition", "attachment;fileName="+fileName); //以流的形式对外输出,输出服务器上指定的File IOUtils.copy(new FileInputStream(path), response.getOutputStream()); } }
1、页面:
<a href="login/1/张三">请求</a>
2、controller接参:
//在此处接收时定义参数名 @RequestMapping("login/{id}/{name}") // @PathVariable注解:可以将 URL 中占位符参数绑定到控制器处理方法的入参中。 public String login(@PathVariable int id,@PathVariable String name){ //参数名id必须和{id}中的完全一致 System.out.println(id+"\t"+name); return "success"; } //如果参数的名字不一致,需要指定@PathVariable("name")中的关键字和{name}完全一致。 @RequestMapping("login/{id}/{name}") public String login(@PathVariable(value="id") int id,@PathVariable(value="name") String userName){ }
3、Rest风格处理文件名上传问题:
@RequestMapping("/download/{fileName:.+}")
Spring4.3中引进了@GetMapping、@PostMapping,来帮助简化常用的HTTP方法的映射,并更好地表达被注解方法的语义。
①:@GetMapping是一个组合注解,是@RequestMapping(method = RequestMethod.GET)的缩写。该注解将get请求映射到特定的处理方法上。
②:@PostMapping是一个组合注解,是@RequestMapping(method = RequestMethod.POST)的缩写。该注解将post请求映射到特定的处理方法上。