搭建
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!--1.spring的中央控制器DispatcherServlet-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--加载spring的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--设置servlet在服务器启动时创建-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<!--
servlet的路径:/ 拦截所有请求,但是不包含jsp页面,依然拦截静态资源【推荐】
servlet的路径:/* 拦截所有请求,并且包含jsp
-->
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--2.处理乱码的过滤器-->
<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>
</web-app>
servlet的路径:/ 拦截所有请求,但是不包含jsp页面,依然拦截静态资源【推荐】
servlet的路径:/* 拦截所有请求,并且包含jsp
原因
自己配置的中心控制器覆盖了默认的DefultServlet
Default是Tomcat默认提供的servlet,用来专门处理静态资源
处理方案
方案一:
配置servlet映射
<!--将静态资源的请求还是交给DefaultServlet去处理-->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>*.htm</url-pattern>
<url-pattern>*.js</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>*.jpg</url-pattern>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
方案二:
方式1:mapping 映射路径,就是访问路径。location 访问路径对应的真实路径。-->
<mvc:resources mapping="/pages/**" location="/pages/"/> <mvc:resources mapping="/index.html" location="/index.html"/>
方式二:推荐写法
<mvc:default-servlet-handler></mvc:default-servlet-handler>
Model与ModelMap
作用:可以往请求域中
springmvc优化请求域的三种方式
方式一:Model 方法addAttribute,是一个接口
方式二:modelMap addAttribute与model一模一样,是一个类
方式三:modelAndView 必须在控制器内自己手动实例化对象,既可以先请求域中写入数据,又可以设置返回的视图名字,
方法setViewName设置视图名字
package com.itheima.controller.a_model;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* @author 黑马程序员
*/
@Controller
@RequestMapping("/model")
public class ModelController {
@RequestMapping("/request")
public String request(HttpServletRequest request, HttpSession session){
//使用servlet的api进行操作请求域数据
request.setAttribute("request_data","播仔");
//注意:如果操作会话域session、全局域servletContext都是一样的操作
//session.getServletContext()
return "success";
}
/*
* springMVC优化请求域的操作方式
* 1.Model 【用的较多】
* 2.ModelMap
* 3.ModelAndView
*
* 注意:Model与ModelMap操作请求域功能一样
* model是一个接口,ModelMap是一个类
*
* ModelAndView 必须在控制器方法内自己手动实例对象,不像上面2个可以直接方法参数定义
* */
@RequestMapping("/model")
public String model2(Model model){
//使用model往请求域中写入数据
model.addAttribute("model_data","播妞");
return "success";
}
@RequestMapping("/modelmap")
public String modelMap(ModelMap modelMap){
//使用ModelMap往请求域中写入数据
modelMap.addAttribute("modelmap_data","狗娃");
return "success";
}
@RequestMapping("/modelAndView")
public ModelAndView modelAndView(ModelMap modelMap){
//实例ModelAndView: 既可以向请求域中写入数据,又可以设置返回的视图名字
ModelAndView modelAndView = new ModelAndView();
//设置视图名字
modelAndView.setViewName("success");
//写入请求域数据
modelAndView.addObject("model_and_view","黑马");
return modelAndView;
}
}
交互json数据
先添加json相关的依赖包
<!--添加jackson支持包: springMVC框架操作json数据时调用的技术-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
jsp异步请求例子
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>发送异步请求</title>
</head>
<body>
<input type="button" value="发送异步请求" id="b1">
<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.min.js"></script>
<script>
//目标:前端发送异步请求,传递json字符串请求数据给后端
//1.给按钮注册点击事件
$("#b1").click(function () {
//2.发送异步请求
//2.1 准备发送的json数据
//json字符串格式:'{"key1":value1,"key2":value2,...}' 注意里面的key必须有双引号括起来
//第一种使用json字符串:自定义字符串格式数据
//let jsonStr = '{"id":100,"name":"播仔"}';
//第二种使用json字符串:将json对象转换为json字符串,推荐方式
// 语法:JSON.stringify(json对象) 返回值是json字符串
let jsonObj = {name:"播仔",id:100};
let jsonStr = JSON.stringify(jsonObj);
//2.2 发送异步请求,传递json字符串
$.ajax({
url:"${pageContext.request.contextPath}/json/jsonData",
//data: {name:"播仔",id:100}, //看着传递的json数据,起始本质是通过请求体传递原生格式:"key1=value1&key2=value2..."
data: jsonStr, //看着传递的json数据,起始本质是通过请求体传递原生格式:"key1=value1&key2=value2..."
contentType:"application/json;charset=utf-8", //设置请求传递json字符串格式数据与码表,如果不设置,传递的数据依然是原生key=value的格式
method:"post",
dataType:"json", //设置返回的数据类型为json字符串
success:function (user) {
//user是返回的json对象数据
alert("name:"+user.name+",id="+user.id);
}
})
});
</script>
</body>
</html>
控制器
package com.itheima.controller.c_json;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author
*/
@Controller
@RequestMapping("/json")
public class JsonController {
@RequestMapping(value = "/jsonData",produces ="application/json;charset=utf-8" )
@ResponseBody //作用:将控制器方法返回值转换为json字符串给前端
public User jsonData(@RequestBody User user){
//@RequestBody 会将请求体中的json字符串转换为java对象,
// 注意:1.如果json中含有中文,需要设置@RequestMapping中的produces接收数据类型与码表
// 2.前端传递过来的json字符串中的属性名 与 封装JAVA对象中的属性名一样才可以封装
System.out.println("进入ajaxData方法接收到的用户数据:"+user);
//修改user对象的数据
user.setId(200);
user.setName("播妞");
return user;
}
}
总结:在发送请求中需要设置传递json字符串格式和码表,如果不设置,数据将会是原生格式,
produces ="application/json;charset=utf-8" 可以处理乱码问题
RequestBody:将请求体中的json数据转换为java对象,在对象前面定义
responseBody:将控制器的返回值转化为json数据给前端页面展示S
控制器方法返回值
1. 返回String
2. 字符串
1. 返回页面名称字符串
eg:return "success" 经过视图解析器拼接
返回转发字符串
return "forward:完整路径
转发只能跳转到服务器当前内部资源
返回重定向字符串
语法:"redirect:完整重定向路径"
其中springmvc回自动补全项目路径
可以跳转到外部资源,比如http:/www.baidu.com
里面中的第一个"/",代表跳转但前项目类的资源地址
3. 返回void
//返回void
@RequestMapping("/void")
public void returnString(HttpServletRequest request, HttpServletResponse response){
try {
//使用原生servlet的api的应用场景
//1.转发
//request.getRequestDispatcher("/index.jsp").forward(request,response);
//2.重定向
//response.sendRedirect(request.getContextPath()+"/index.jsp");
//3.附件下载
//设置响应头:通知浏览器进行附件下载
response.setHeader("content-disposition","attachment;filename=6.jpg");
//获取当前项目“/down/6.jpg”的输入流
InputStream inputStream = request.getServletContext().getResourceAsStream("/down/6.jpg");
//使用commons-io工具类将收入流通过response的输出流输出给浏览器
IOUtils.copy(inputStream,response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
4. 返回ModelAndView对象
5. 返回任意对象。(配置@ResponseBody注解)
RestFul风格的URL
RestFul就是一个URl地址,是一种地址编风格
特点:更简洁,更有层次感,借助了不同的http请求(get/post/put/delete)
的方法来区分不同业务操作,更易于浏览器实现缓存
浏览器的同步请求:可以提交Post和Get,默认为Get,无法提交PUT与de'lete请求
js异步请求: 可以提交get/post/put/delete
1. 如果要用restful风格的url地址,可以直接用,不用做任何操作或配置等。
2. 配置HiddenHttpMethodFilter与restful没有关系, 主要是为了让页面支持put、delete请求而已。
3. 总结两点问题:
1. 使用HiddenHttpMethodFilter过滤请求,主要是为了让页面支持put、delete请求
2. put、delete请求, 只支持返回json类型的数据
一个地址可以表示多次请求(直接在方法上定义 “请求类型”,另外可以在括号里设置value的值) 而方法的形参需要用@PathVariable来表明接收
实现文件上传
用到了Apache的文件上传组件实现
实现
-------------------------------------------------------------------------------
1.导入上传依赖
<!--添加Apache文件上传支持包-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
---------------------------------------------------------------------------------
2. jsp页面
<%--
文件上传客户端要求三要素
1.必须使用form表单的post提交请求
2.form表单属性enctype的值必须为multipart/form-data"
3.form表单里面必须有文件域表单项元素,就是submit
--%>
表单实例
<form action="${pageContext.request.contextPath}/upload/uploadFile" method="post" enctype="multipart/form-data">
<input type="file" name="imgFile">
<input type="submit" value="文件上传">
</form>
--------------------------------------------------------------------------------------
3.编写控制类
@Controller
@RequestMapping("/upload")
public class UploadController {
/*
* 目标:将客户端上传的文件上传到服务器端项目内“upload/2020-10-26/xxxxx.jpg”
*
* 服务器端SpringMVC使用apache的File-upload组件实现文件上传
* 1.控制器的方法参数 MultipartFile类型,参数名必须为表单文件域元素的name属性值
* eg:<input type="file" name="imgFile">, 所以参数:MultipartFile imgFile
*
* MultipartFile的作用:可以获取上传文件的名称,文件的输入流
* */
@RequestMapping("/uploadFile")
public String uploadFile(MultipartFile imgFile, HttpServletRequest request){
try {
//1.定义上传文件的唯一名字
//1.1 获取客户端文件的扩展名(后缀名)
String clientFileName = imgFile.getOriginalFilename(); //获取客户端上传文件名
String fileExtName = clientFileName.substring(clientFileName.lastIndexOf("."));
//1.2 生成一个唯一值(UUID)
UUID uuid = UUID.randomUUID();
//1.3 拼接文件名
String fileName = uuid + fileExtName;
//2.判断上传目录“upload/2020-10-26”是否存在,不存在则创建
//2.1 获取当前日期
String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
//2.2 获取当前项目内“upload/2020-10-26”目录的绝对路径(磁盘路径)
String path = request.getServletContext().getRealPath("/upload/" + date);
//2.3 判断目录是否存在,不存在创建
File file = new File(path);
if(!file.exists()){
file.mkdir();
}
//3.上传
imgFile.transferTo(new File(path,fileName));
return "success";
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
注意事项:控制器的方法参数 MultipartFile类型的参数名,必须与表单上文件域的name一样
MultipartFile的作用:可以获取上传文件的名称,文件的输入流
要用请求域获取上下文域,直接上下文域没用
-------------------------------------------------------------------------------------------------------------------------------
4.配置spring
<!--
创建文件上传解析器创建文件上传对象
" 文件上传解析器对象的id属性值=“multipartResolver”,必须为这个值",否则无法解析
maxUploadSize:设置上传文件的大小,单位字节,如果限制文件上传大小为10M=1024*1024*10
--
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="#{1024*1024*10}"></property>
</bean>
----------------------------------------------------------------------------------------
**部署文件上需要查看是否有这个文件**