解决静态资源访问不了问题:如果你的DispatcherServlet拦截 .do这样的URL,就不存在访问不到静态资源的问题。如果你的DispatcherServlet拦截“/”,拦截了所有的请求,同时对.js,css,html等静态资源的访问也被拦截了。这里的斜杠,代表拦截页面的所有请求(不包含jsp页面)“/*拦截了所有请求”
方案1:在项目web.xml下重新配置Tomcat默认Servlet的路径
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>*.js</url-pattern>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
方案二:
SpringMVC有能力处理静态资源
mapping: 需要处理的访问路径
location: 交给哪个静态资源(文件或目录)去处理(物理路径)
<!--<mvc:resources mapping="/index.html" location="/index.html"/>-->
<mvc:default-servlet-handler/>
SpringMVC控制器方法参数:Model与ModelMap
作用: 可以往request域中存储数据。 request.setAttribute(key, value);
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 演示Model和ModelMap存入数据到request中
*/
@Controller
public class ModelController {
/**
* 使用Model存入数据到request中
*/
@RequestMapping("/model")
public String model(Model model){
//存入数据到request中
model.addAttribute("user1","小苍");
//转发页面
return "index";
}
/**
* 使用ModelMap存入数据到request中
*/
@RequestMapping("/modelMap")
public String modelMap(ModelMap modelMap){
//存入数据到request中
modelMap.addAttribute("user2","小泽");
//转发页面
return "index";
}
}
控制器方法返回值
控制器返回值的写法:
- 字符串
1.1 普通字符串(代表页面名称,不是完整路径)
1.2 转发字符串
1.3 重定向字符串 - void (原生的)
- ModelAndView
- Java对象 (转换为json字符串)
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* 演示控制器方法的返回值
* 1. 字符串
1.1 普通字符串(代表页面名称,不是完整路径)
1.2 转发字符串
1.3 重定向字符串
2. void (原生的)
3. ModelAndView
4. Java对象 (转换为json字符串)
*
*/
@Controller
@RequestMapping("/return")
public class ReturnController {
/**
* 1. 字符串 - 1.1 普通字符串(代表页面名称,不是完整路径)
*/
@RequestMapping("/string")
public String string(){
System.out.println("进入ReturnController的string方法");
//最终的页面路径: /pages/index.jsp
return "index";
}
/**
* 1. 字符串 - 1.2 转发字符串
* 规则:forward:转发的页面完整路径 例如: forward:/pages/index.jsp
*
* 注意: 普通字符串 vs forward字符串?
* 普通字符串:只能转发到指定前缀目录的页面
* forward字符串:可以转发到项目下的任意目录的任意文件
*
*
*/
@RequestMapping("/forward")
public String forward(){
System.out.println("进入ReturnController的forward方法");
return "forward:/index.html";
}
/**
* 1. 字符串 - 1.3 重定向字符串
* 规则: redirect: 重定向的页面完整路径
* 注意: redirect的好处
* 1)重定向到项目下的任何页面 redirect:/pages/index.jsp
* 2)重定向项目外的资源 : redirect:http://www.baidu.com
*/
@RequestMapping("/redirect")
public String redirect(){
System.out.println("进入ReturnController的redirect方法");
return "redirect:http://www.baidu.com";
}
/**
* 2. void (原生的)
* 通常不会在控制器直接转发或重定向,在项目中可以用在文件下载!!
*/
@RequestMapping("/void")
public void returnVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("进入ReturnController的returnVoid方法");
//转发
//request.getRequestDispatcher("/pages/index.jsp").forward(request,response);
//重定向
response.sendRedirect("/pages/index.jsp");
//文件的下载的思路
/**
* 1.读取需要下载的文件
* 2.获取到文件的输入流
* 3. 使用response的输出流把文件输出到用户浏览器
*/
/* File file = new File("xxxx");
InputStream in = new FileInputStream(file);
ServletOutputStream os = response.getOutputStream();
byte[] bytes = new byte[1024];
int len = 0;
//边读边写
while( (len = in.read(bytes))!=-1 ){
os.write(bytes,0,len);
}
os.close();
in.close();*/
}
/**
* 3. ModelAndView
* ModelAndView:Model+View 封装了Model的数据,也可以设置视图的信息
*/
@RequestMapping("/mv")
public ModelAndView mv(){
System.out.println("进入ReturnController的mv方法");
ModelAndView mv = new ModelAndView();
//设置model数据:底层:modelMap.addAttribute("key","value");
mv.addObject("user1","mv");
//设置视图信息
/**
* mv.setViewName("index"): /pages/index.jsp
* mv.setViewName("forward:/pages/index.jsp"): 转发页面
* mv.setViewName("redirect:/pages/index.jsp"): 重定向页面
*/
mv.setViewName("index");
return mv;
}
}
交互JSON数据:@RequestBody与@ResponseBody注解
@RequestBody
作用:在处理器方法形参上使用,把请求的json格式数据,转换成java对象。
@ResponseBody
作用:在处理器方法返回值上使用,或者方法上使用。把响应的java对象,转换成json格式数据。
@RequestBody : json字符串 -> Java对象
@ResponseBody: Java对象 -> Json字符串
ajax.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSON数据转发问题</title>
<script src="/js/jquery-3.3.1.min.js"></script>
</head>
<body>
<script>
//页面加载
$(document).ready(function(){
//以前写法:最终传递参数格式:id=10&username=eric 后台接收:request.getParameter("id")
/*$.ajax({
url:'/json',
//传输json字符串
data:{id:10,username:'eric'}
});*/
$("#btn").click(function(){
//现在写法
//发送post请求: 最终传递参数格式:{"id":"1001","username":"jack","age":"18"} 后台接收:???@RequestBody注解
$.ajax({
url:'/json',
type:'post',
//传输json字符串
data:'{"id":"1001","username":"jack","age":"18"}',
//contentType: 指定data的数据类型
contentType:'application/json;charset=utf-8',
//后台返回的数据类型
dataType:'json',
success:function(result){ // result: json对象
alert(result.id+"--"+result.username+"--"+result.age);
}
});
});
});
</script>
<input id="btn" type="button" value="发送json数据,获取json数据">
</body>
</html>
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;
/**
* 演示前后台交互json数据
*/
@Controller
public class JsonController {
/**
* @RequestBody: 专门用于接收页面传递的json格式的参数:{"id":"1001","username":"jack","age":"18"}
* 会把json格式的数据转换为Java对象
* 位置:必须用在参数里面
*
* @ResponseBody: 专门把后台的Java对象转换为Json格式数据并返回给页面
* 位置:在方法上面,也可以在返回值里面
*/
@RequestMapping("/json")
@ResponseBody
public User json(@RequestBody User user){ // 前端传递参数格式:{"id":"1001","username":"jack","age":"18"}
System.out.println("接收的用户信息:"+user);
//修改数据
user.setId(666);
user.setUsername("rose");
user.setAge(20);
return user;
}
}
SpringMVC文件上传
先导需要的依赖commons-fileUpload
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
/**
* 演示SpringMVC方式文件上传
*/
@Controller
public class Upload2Controller {
/**
* MultipartFile: SpringMVC封装了commons-fileUpload解析的文件内容
* 注意: 变量名称和页面的file组件的name一致!!!
*/
@RequestMapping("/upload2")
public String upload(HttpServletRequest request, String username, MultipartFile imgFile){
//在项目下创建upload目录,用于存储所有文件
//获取upload路径
String uploadPath = request.getSession().getServletContext().getRealPath("/upload");
File uploadFile = new File(uploadPath);
if(!uploadFile.exists()){
//新建目录
uploadFile.mkdir();
}
//普通字段
System.out.println("用户名:"+username);
//文件
//获取原来的文件名称
String fileName = imgFile.getOriginalFilename();
//随机生成文件名称,防止文件重名覆盖问题
String uuid = UUID.randomUUID().toString();
//文件后缀
String extName = fileName.substring(fileName.lastIndexOf("."));
String newFileName = uuid + extName; // uuid.jpg
//保存文件
try {
imgFile.transferTo(new File(uploadFile+"/"+newFileName));
} catch (IOException e) {
e.printStackTrace();
}
//默认自动删除缓存文件
return "index";
}
}
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
/**
* 演示SpringMVC方式文件上传
*/
@Controller
public class Upload2Controller {
/**
* MultipartFile: SpringMVC封装了commons-fileUpload解析的文件内容
* 注意: 变量名称和页面的file组件的name一致!!!
*/
@RequestMapping("/upload2")
public String upload(HttpServletRequest request, String username, MultipartFile imgFile){
//在项目下创建upload目录,用于存储所有文件
//获取upload路径
String uploadPath = request.getSession().getServletContext().getRealPath("/upload");
File uploadFile = new File(uploadPath);
if(!uploadFile.exists()){
//新建目录
uploadFile.mkdir();
}
//普通字段
System.out.println("用户名:"+username);
//文件
//获取原来的文件名称
String fileName = imgFile.getOriginalFilename();
//随机生成文件名称,防止文件重名覆盖问题
String uuid = UUID.randomUUID().toString();
//文件后缀
String extName = fileName.substring(fileName.lastIndexOf("."));
String newFileName = uuid + extName; // uuid.jpg
//保存文件
try {
imgFile.transferTo(new File(uploadFile+"/"+newFileName));
} catch (IOException e) {
e.printStackTrace();
}
//默认自动删除缓存文件
return "index";
}
}
配置springMVC.xml文件上传解析器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 1.控制器包扫描 -->
<context:component-scan base-package="com.huihui.controller"/>
<!-- 2.视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 3.springmvc注解驱动 -->
<mvc:annotation-driven/>
<!-- SpringMVC有能力处理静态资源 -->
<!--
mapping: 需要处理的访问路径
location: 交给哪个静态资源(文件或目录)去处理(物理路径)
-->
<!--<mvc:resources mapping="/index.html" location="/index.html"/>-->
<mvc:default-servlet-handler/>
<!-- 文件解析器 -->
<!--
注意:虽然CommonsMultipartResolver这个对象没有被其他bean引用,
但是springMVC默认就一定要起id别名,且名称一定要叫multipartResolver
-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置文件最大字节数:100KB-->
<property name="maxUploadSize" value="1024000"/>
</bean>
</beans>