Springday05 SpringMVC访问静态资源操作请求域控制器方法返回值JSON数据交互RESTful风格文件上传异常处理拦截器
Posted halulu.me
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Springday05 SpringMVC访问静态资源操作请求域控制器方法返回值JSON数据交互RESTful风格文件上传异常处理拦截器相关的知识,希望对你有一定的参考价值。
目录
静态资源访问
前端静态资源的访问 —》 后端直接获取静态资源进行响应, 不走springmvc
前端访问jsp资源 —》 后端直接执行jsp, 不走springmvc
其他请求后端资源 —》 后端执行springmvc
映射路径设置为: “/”
"/“的作用:不拦截以”.jsp"的结尾路径, 其他所有请求路径全都拦截(通过其他设置实现静态资源不拦截)
<!--1.配置springmvc前端控制器(核心控制器)DispathcerServlet-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置价值springMVC.xml文件-->
<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>
<!--
映射路径设置为: “/”
"/"的作用:不拦截以".jsp"的结尾路径, 其他所有请求路径全都拦截(通过其他设置实现静态资源不拦截)
-->
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
springMVC中拦截请求路径是“/”,导致静态资源index.html访问不了。
原因:
2、自己项目配置的DispatcherServlet拦截的路径也是/, 会覆盖DefaultServlet。
3、DefaultServlet的作用: tomcat提供的默认servlet,专门用于处理静态资源。
方法一:(不推荐使用)
重新映射
<!--静态资源处理方案1:web.xml中将静态资源的处理交换给全局配置的默认的Servlet-->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>*.js</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
方法二:
SpringMVC也提供了解决方案用来解决上述静态资源访问不了的问题。
<!--
解决静态资源直接访问的方案2:通过标签<mvc:resources>解决
注意点:
1.mapping属性:配置映射的任何静态资源,注意必须是2个*号
2.location:配置直接访问的资源路径
第一个"/",代表直接访问webapp目录下的静态资源文件
第二个"classpath:static/",代表直接访问resources/static目录下的静态资源文件
第三个“/WEB-INF/”,代表访问webapp/WEB-INF/目录下的静态资源文件,转发跳转
由于
多个路径之间使用逗号隔开,路径必须以“/”结束
-->
<mvc:resources mapping="/**" location="/,classpath:static/,/WEB-INF/"></mvc:resources>
方法三:
<!--
解决静态资源直接访问的方案3:通过标签<mvc:default-servlet-handler/>交给tomcat默认的DefaultServlet处理
注意:
1.所有的静态资源都必须放在webapp目录下
2.不同的服务器,默认的Servlet名字都不一样,所以当前默认名字不是default的时候
default-servlet-name="default" ,如果是default可以不写,否则必须指明具体的名字
例如:webLogic服务器,就需要设置default-servlet-name="FileServlet"
-->
<mvc:default-servlet-handler default-servlet-name="default"></mvc:default-servlet-handler>
注意:
不同服务器的默认servlet的名字是不一样的。
SpringMVC操作请求域
- 方式1:原生servlet的api操作request对象
- 方式2:jdk的Map集合对象
- 方式3:springMVC提供的Model对象
- 方式4:springMVC提供的ModelMap对象
- 方式5:springMVC提供的ModelAndView对象【用的最多】
@Controller
@RequestMapping("/model")
public class ModeLController {
@RequestMapping("/requestData")
public ModelAndView requestData(HttpServletRequest request,
Map map,
Model model,
ModelMap modelMap
ModelAndView modelAndView){
/*
* 目标:操作请求域存储数据的5种方式
* 方式1:原生servlet的api操作request对象
* 方式2:jdk的Map集合对象
* 方式3:springMVC提供的Model对象
* 方式4:springMVC提供的ModelMap对象
* 方式5:springMVC提供的ModelAndView对象【用的最多】
*
* 5种方案的相同点:
* 都是可以写入请求域数据,数据格式都是键值对,本质都是Map
* 不同点
* Model是一个接口
* ModelMap是一个类
* ModelAndView: 不仅可以写入请求域数据还可以设置返回的视图名字
* Map是jdk,其他都是springMvc提供
*
* 小结:
* 任意一个就可以
*
* 如果想操作会话域或上下文域对象:必须使用servlet原生api操作
* 会话域: request.getSession()
* 上下文域: reqeust.getServletContext()
* */
/*方式1:原生servlet的api操作request对象*/
request.setAttribute("request_data","播仔");
/*方式2:jdk提供的Map对象*/
map.put("map_data","itheima");
/*方式3:springMVC提供的Model对象*/
//语法:model.addAttribute(String key,Object value);
model.addAttribute("mode_data","播妞");
/*方式4:springMVC提供的ModelMap对象*/
//语法:modelMap.addAttribute(String key,Object value);
modelMap.addAttribute("modelmap_data","狗娃");
/*方式5:springMVC提供的ModelAndView对象
* ModelAndView 既可以写入请求域数据又可以设置返回视图的名字,并且可以作为控制器方法返回值
* 写入请求域数据语法:modelAndView.addObject(String key,Object value);
* 设置返回视图的名字语法:modelAndView.setViewName("视图名字");
* */
//实例
ModelAndView modelAndView = new ModelAndView();
//写入请求域数据
modelAndView.addObject("modelAndView_data","itcast");
//设置视图名字
modelAndView.setViewName("success");
return modelAndView;
}
}
SpringMVC控制器方法返回值
控制器方法返回值类型:
1、返回String字符串
a、 返回页面名称字符串(视图名字)
b、返回转发字符串
c、 返回重定向字符串
2、返回void
3、返回ModelAndView对象
4、 返回任意对象。(配置@ResponseBody注解实现转换为json字符串返回)
@Controller
@RequestMapping("/return")
public class ReturnController {
@RequestMapping("/string")
public String returnString(){
/* 1. 返回页面名称字符串(视图名字)*/
//return "success";
/*
* 2. 返回转发字符串
* 介绍:如果想不受视图前缀与后缀的约束,可以使用返回转发字符串跳转到任意位置资源
* 格式: "forward:/转发的路径"
* 注意:转发的路径是完整的路径,必须带有前缀与后缀
* 转发跳转特点:跳转前后url不变
* */
//return "forward:/index.jsp";
/*
* 3. 返回重定向字符串
* 介绍:如果想不受视图前缀与后缀的约束,可以使用返回重定向字符串重定向跳转到任意位置资源
* 格式: "redirect:/重定向的路径"
* 注意:重定向的路径,不可以写项目路径,因为springmvc会自动加上项目路径
* 重定向跳转特点:跳转前后url会变
* */
return "redirect:/index.jsp";
}
@RequestMapping("/void")
public void returnVoid(HttpServletRequest request, HttpServletResponse response)throws Exception{
//应用场景:操作会话域、上下文域、响应头设置、响应行设置、cookie操作等原生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");
//获取img/6.jpg的输入流
InputStream inputStream = request.getServletContext().getResourceAsStream("/img/6.jpg");
//输出
IOUtils.copy(inputStream,response.getOutputStream());
}
}
交互JSON数据:@RequestBody与@ResponseBody
SpringMVC交互JSON数据需要依赖于jackson
<!--添加jackson支持包: springMVC框架操作json数据时调用的技术-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
@Controller
@RequestMapping("/json")
public class JsonController {
/*
* 注解@RequestBody
* 介绍:实现将前端传递过来的json字符串转换为java对象
* 使用的位置: 控制器方法的参数上,将请求体中json字符串转换为java对象赋值给参数
* 技术原理:使用jackson实现json字符串转换为java对象
* 注意:如果前端传递的不是json字符串,会发生415错误
* 注解@ResponseBody
* 介绍:实现将控制器方法返回值的java对象转换为json字符串
* 注意:如果控制器返回值的类型是String字符串,默认含有中文会乱码,需要设置
* @RequestMapping(value="/data",produces = "application/json;charset=utf-8")
* 解决中文乱码
* */
@RequestMapping(value="/data")
@ResponseBody
public User jsonData(@RequestBody User user){
System.out.println("name:"+user.getName());
System.out.println("id:"+user.getId());
return user;
}
//返回类型为字符串
@RequestMapping(value="/data2",produces = "application/json;charset=utf-8")
@ResponseBody
public String jsonData2(){
return "小一"; //这种直接返回字符串含有中文,如果不设置produces就会乱码
}
}
直接返回中文字符串乱码的问题
使用: @RequestMapping(produces = “application/json;charset=utf-8”)
ajax传递json数据
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<input type="button" value="发送异步请求(请求数据为json格式)" id="b1">
<%--导入jquery--%>
<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.min.js"></script>
<script>
/*目标1:发送异步请求通过post请求传递json字符串给服务器端*/
/*
* 异步传递数据格式:
* 格式1:"key1=value1&key2=value2..." 不是json字符串格式
* 格式2:{key1:value1,key2:value2} 这是json对象,不是json字符串,底层传递的格式与格式1是一样的
* 格式3【符合要求】: json字符串格式
* 第一步:拼接一个json字符串再发送
* 手动拼接:'{"id":100,"name":"播仔"}'
* 自动生成:JSON.stringify(json对象) 得到 json字符串
* 第二步:设置提交数据的类型, contentType:"application/json;charset=utf-8"
* */
//1.给按钮注册点击事件
$("#b1").click(function (){
//2.发送异步请求
$.ajax({
url:"${pageContext.request.contextPath}/json/data",
method:"post",
data:'{"id":100,"name":"播仔"}',
contentType:"application/json;charset=utf-8",
success:function(user){
//服务器返回的json字符串,jquery默认会将其转换为json对象,接收到的数据:{id:xx,name:xx}
alert(`id:\\${user.id},name:\\${user.name}`);
},
error:function(obj){
console.log(obj);
alert("服务器忙。。。");
}
});
});
</script>
</body>
</html>
注意:
data:’{“id”:100,“name”:“播仔”}’,
contentType:“application/json;charset=utf-8”,
使用单引号
RESTful风格编程
web.xml配置HiddenHttpMethodFilter 过滤器,让页面支持put、delete请求。
<!--配置HiddenHttpMethodFilter 过滤器-->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
通过post请求修改为put何delete
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
目标:使用RestFul风格提交请求,一个路径实现增删改查
请求路径:http://localhost:8080/项目路径/user
分别提交不同的请求类型:
get请求类型:查询数据
post请求类型:添加数据
put请求类型:修改数据
delete请求类型:删除数据
--%>
<h2>Get请求</h2>
<form action="${pageContext.request.contextPath}/user" method="get">
<input type="submit" value="Get查询用户列表请求">
</form>
<h2>Post请求</h2>
<form action="${pageContext.request.contextPath}/user" method="post">
<input type="submit" value="Post添加用户数据请求">
</form>
<h2>Put请求</h2>
<!--发送put请求注意:-->
<!--1. 表单的提交方式都是post-->
<!--2. 表单中要有一个隐藏域,名称是_method, 其值就是真正的请求方式。-->
<form action="${pageContext.request.contextPath}/user" method="post">
<input type="hidden" name="_method" value="put"/>
爱好:<input type="text" name="hobby" value="爱编程">
<input type="submit" value="Put修改用户数据请求">
</form>
<h2>Delete请求</h2>
<form action="${pageContext.request.contextPath}/user" method="post">
<input type="hidden" name="_method" value="delete"/>
<input type="submit" value="Delete删除用户数据请求">
</form>
</body>
</html>
@GetMapping("/{id}/{name}"),(@PathVariable(“id”) Integer id2,@PathVariable String name)
映射参数
@Controller
@RequestMapping("/user")
public class UserController {
//处理get查询请求
//@RequestMapping(method = RequestMethod.GET)
@GetMapping
public String findAll(){
System.out.println("处理了用户列表查询请求");
return "success";
}
//处理get查询id=100查询一个用户的请求
//@RequestMapping(method = RequestMethod.GET)
//路径模板映射配置:@GetMapping("/{名字1}/{名字2}")
//接收路径中模板占位符传递的数据注解:@PathVariable("名字") 获取占位符路径传递过来的值并赋值给控制器方法参数
// 注意:@PathVariable不设置名字的时候要去模板配置的名字要与方法参数变量名一样
@GetMapping("/{id}/{name}")
public String findById(@PathVariable("id") Integer id2,@PathVariable String name){
System.out.println("处理了用户列表查询请求");
System.out.println("路径中的id:"+id2+",路径中的name:"+name);
return "success";
}
//处理post添加请求
//@RequestMapping(method = RequestMethod.POST)
@PostMapping
public String add(){
System.out.println("处理了用户添加请求");
return "success";
}
/*
* 处理put和delete请求注意事项
* 后端处理这样的请求,控制器方法不可以转发跳转页面,否则正式服务器运行会报错, tomcat7的插件不会报错
* 控制器方法返回视图名字也是转发跳转,正式服务器会报错
* 错误信息:HTTP Status 405 – Method Not Allowed
* 含义:不支持的请求类型,
* 解决方案:只要不转发跳转就可以
* 方案1: 重定向跳转,浏览器会发出新的默认get请求,就不会报错
* 方案2: 不进行跳转,直接输出数据
* 例如:@ResponseBody, 就是直接输出数据,将控制器方法返回值的java对象转换为json字符串输出
*
* */
//处理put修改请求
//@RequestMapping(method = RequestMethod.PUT)
@PutMapping
public String update(String hobby){
System.out.println("处理了用户修改请求");
System.out.println("参数数据hobby:"+hobby);
return "redirect:/pages/success.jsp";
}
//处理delete删除请求
//@RequestMapping(method = RequestMethod.DELETE)
@DeleteMapping
@ResponseBody
public String delete(){
System.out.println("处理了用户删除请求");
return "hello";
}
}
正式服务器转发跳转put和delete会报错,这是因为转发跳转会有2次检查,第一次检查将post变成deltete,第二次再次检查的时候会报错
SpringMVC 实现文件上传
SpringMVC实现文件上传借用了apache的fileupload
<!--添加Apache文件上传支持包-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>文件上传</h2>
<%--
文件上传客户端要求三要素
1.必须使用form表单的post提交请求
2.form表单属性enctype="multipart/form-data"必须设置这样的值
3.form表单里面必须有文件域表单项元素
--%>
<form action="${pageContext.request.contextPath}/upload/uploadFile" method="post" enctype="multipart/form-data">
我在springMVC里配置了 静态资源访问 为啥还是访问不到