<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.azuregroupId>
<artifactId>day56project_SpringMVC_day2artifactId>
<version>1.0-SNAPSHOTversion>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.0.2.RELEASEversion>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>servlet-apiartifactId>
<version>2.5version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jsp-apiartifactId>
<version>2.0version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
dependencies>
project>
<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">
<servlet>
<servlet-name>DispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springMVC.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>DispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
<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">
<context:component-scan base-package="com.azure">context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/">property>
<property name="suffix" value=".jsp">property>
bean>
<mvc:annotation-driven>mvc:annotation-driven>
beans>
由于在web.xml中前端控制器的拦截规则是/
,动态资源(jsp)不会被拦截,而静态资源(如html、css、js等)默认不能访问。
tomcat服务器访问任何资源都是通过servlet把资源返回到浏览器客户端。
而访问静态资源不是使用servlet程序,而是默认通过DefaultServlet(缺省servlet)把静态资源返回到客户端中。该缺省servlet在tomcat服务器启动时默认就建立:
而我们在项目中配置拦截的路径是/
,则所有的资源都会进入我们项目新建的dispatcherServlet,而不会经过DefaultServlet,从而导致静态资源无法被返回。
所以解决方式有两种:修改放行资源路径,重新配置DefaultServlet.
/pages/*
和/panges/**
两种写法的差别
<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">
<context:component-scan base-package="com.azure">context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/">property>
<property name="suffix" value=".jsp">property>
bean>
<mvc:annotation-driven>mvc:annotation-driven>
<mvc:resources mapping="/index.html" location="/index.html"/>
<mvc:resources mapping="/pages/**" location="/pages/"/>
<mvc:resources mapping="/css/**" location="/css/"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/image/**" location="/image/"/>
beans>
<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">
<servlet>
<servlet-name>DispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springMVC.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>DispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>defaultservlet-name>
<url-pattern>*.htmlurl-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>defaultservlet-name>
<url-pattern>*.jsurl-pattern>
servlet-mapping>
web-app>
@Controller
public class ModelController {
/*Model作为方法参数*/
@RequestMapping("/model")
public String model(Model model) {
model.addAttribute("JoJo","StarPlatinum" );
return "success";
}
/*ModelMap作为方法参数*/
@RequestMapping("/modelMap")
public String modelMap(ModelMap modelMap) {
modelMap.addAttribute("Dio","TheWorld" );
return "success";
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
success
success!!
${requestScope.JoJo}<%--从request域中获取数据--%>
${requestScope.Dio}
相同点:
request.setAttribute()
方法;不同点:
/**
* 注解@SessionAttributes
* 1.自动把Model或者ModelMap中的数据放入session
* 2.属性:
* names = {"JoJo","Dio"}, 把Model或者ModelMap中指定名称的key的数据,自动放入session
* types = Integer.class 把Model或者ModelMap中指定类型的数据,自动放入session
*/
@Controller
@SessionAttributes(names = {"JoJo","Dio"},types = Integer.class)
public class SessionAttributesController {
@RequestMapping("/sessionModel")
public String sessionModel(Model model) {
model.addAttribute("JoJo","StarPlatinum");
model.addAttribute("Dio","TheWorld");
model.addAttribute("num1",831143);
model.addAttribute("num2","12345");//不满足存入的条件,该条数据不会存入session
return "success";
}
@RequestMapping("/sessionModelMap")
public String sessionModelMap(ModelMap modelMap) {
modelMap.addAttribute("JoJo","StarPlatinum");
modelMap.addAttribute("Dio","TheWorld");
return "success";
}
/*清除session的数据
* 1.使用原始的session.setAttribute方法存入的,只能使用原始的方法清除;
* 2.使用springMVC提供的方法自动存入的(即上面代码),只能使用@SessionAttributes注解清除.
* 注意:方法的参数是SessionStatus,这个对象提供setComplete()方法清空自动存入session的数据,
* 而原始方法存入的不会被清除
*/
@RequestMapping("/del")
public String del(SessionStatus sessionStatus){
// 清空通过@SessionAttributes注解自动放入session中的数据
sessionStatus.setComplete();
return "success";
}
}
success!!
从request域中获取数据
${requestScope.JoJo}
${requestScope.Dio}
从session域中获取数据
${sessionScope.JoJo}
${sessionScope.Dio}
${sessionScope.num1}
${sessionScope.num2}
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.9.0version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.9.0version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.0version>
dependency>
/js/**
的资源
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajaxtitle>
<script src="../js/jquery-3.3.1.min.js" type="text/javascript">script>
<script>
$(function(){
$("#ajaxPost").click(function(){
$.ajax({
// 请求类型,这里必须为post,否则无法使用requestBody
type : "post",
// 请求地址
url : "/responseBodyJson",
// 发送给后台的ajax请求数据
data:'{"id":100,"name":"jack","money":9.9}',
dataType:"json",
// 请求格式与编码,避免乱码
contentType:"application/json;charset=utf-8",
success : function(jsn){
alert("jsn="+jsn+"; jsn.id="+jsn.id+"; jsn.name="+jsn.name+"; jsn.money="+jsn.money);
}
});
});
});
script>
head>
<body>
<h2>RequestBody获取请求JSON格式数据 & ResponseBody自动把对象转json并响应h2>
<button id="ajaxPost">测试ajax请求json与响应jsonbutton>
body>
html>
public class Account {
private int id;
private String name;
private double money;
@Controller
public class JsonController {
@RequestMapping("/responseBodyJson") //注意与页面的ajax中的url保持一致
@ResponseBody //表示方法返回json格式(自动把返回对象转json格式)
public Account json(@RequestBody Account account) { //作用在方法参数中用以获取请求体的数据封装到形参中
System.out.println("请求的数据为:" + account);
//返回的数据
account.setId(11);
account.setName("JoJo");
account.setMoney(10086);
return account;
}
}
资源(Resources):URI是每个资源独一无二的标识符;
表现层(Representation) : 把资源具体呈现出来的形式;
状态转化(State Transfer):简单而言:是表现层状态转化,有四种操作。GET:用来获取资源,POST:用来新建资源,PUT:用来更新资源,DELETE:用来删除资源;
共7种:
而jsp、html仅支持其中的get,post方式。如果要使用其他方式,需要使用特定方法开启。
如果使用同一个地址表示crud方法:
非restful方法:需要在访问路径中表明crud的方法,eg:http://localhost:8080/Order?type=add/update/delete/find
restful方法:不需要在访问路径中表明crud的方法,只需要在提交表单的时候使用不同的提交方式,而不同crud方法可以使用同一个地址,eg:http://localhost:8080/Order
_metheod
请求参数,即我们需要的请求方式
<filter>
<filter-name>hiddenHttpMethodFilterfilter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilterfilter-class>
filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
_method
参数
<html lang="en">
<head>
<meta charset="UTF-8">
<title>restful_testtitle>
head>
<body>
<form action="http://localhost:8080/restful/100" method="post">
<input type="hidden" name="_method" value="post">
<input type="submit" value="post提交(添加)">
form>
<form action="http://localhost:8080/restful/200" method="post">
<input type="hidden" name="_method" value="get">
<input type="submit" value="get提交(查询)">
form>
<form action="http://localhost:8080/restful/300" method="post">
<input type="hidden" name="_method" value="put">
<input type="submit" value="put提交(修改)">
form>
<form action="http://localhost:8080/restful/400" method="post">
<input type="hidden" name="_method" value="delete">
<input type="submit" value="delete提交(删除)">
form>
body>
html>
@PathVariable
获取占位符值@Controller
public class restfulController {
/**
* 1.处理post请求
* 2.请求地址:http://localhost:8080/restful/100,id不能在代码中写死,需要使用占位符
* 占位符的写法{占位符名}
* 3.在控制类的方法参数中使用@PathVariable注解获取占位符的值,并赋值到被注解的参数中
*/
@RequestMapping(value = "/restful/{id}",method = RequestMethod.POST)
public String save(@PathVariable("id") int id) {
System.out.println("save:" + id);
return "success";
}
/**
* 1.处理get请求
* 2.请求地址:http://localhost:8080/restful/100,id不能在代码中写死,需要使用占位符
* 占位符的写法{占位符名}
*/
@RequestMapping(value = "/restful/{id}",method = RequestMethod.GET)
public String get(@PathVariable("id") int id) {
System.out.println("get:" + id);
return "success";
}
/**
* 1.处理put请求
* 2.注意:put请求不能使用跳转,需要返回json格式的字符串
* 否则会报405:JSPs only permit GET POST or HEAD
* 为何会报错?
* 因为返回的字符串是以put方式,而返回的页面jsp不支持put方式,导致无法识别而报错
*/
@RequestMapping(value = "/restful/{id}",method = RequestMethod.POST)
public String put(@PathVariable("id") int id) {
System.out.println("put:" + id);
return "success"; //注意,这里返回的是json字符串,而不会跳转到success.jsp
}
/**
* 1.处理delete请求
* 2.注意:delete请求不能使用跳转,需要返回json格式的字符串
*/
@RequestMapping(value = "/restful/{id}",method = RequestMethod.DELETE)
@ResponseBody //表示返回值自动转为json格式数据
public String delete(@PathVariable("id") int id) {
System.out.println("delete:" + id);
return "[{\"id\":\"11\",\"name\":\"JoJo\"},{\"id\":\"12\",\"name\":\"Dio\"}]";
}
}
上面的代码的返回值全部是String类型,使用转发方式跳转
ModelAndView是SpringMVC提供的对象
作用:控制器存储数据的同时完成跳转功能
提供两种方法:
@Controller
public class ReturnValueController {
/**
* 1. 返回值为String类型
*/
@RequestMapping("/str")
public String strReturn(){
return "success";
}
/**
* 2. 返回void
*/
@RequestMapping("/void")
public void voidReturn(HttpServletResponse response){
}
/**
* 3. 返回值为ModelAndView
* 在存储数据的同时完成跳转操作
*/
@RequestMapping("/mv")
public ModelAndView returnmodelAndView(HttpServletResponse response){
//创建ModelAndView对象
ModelAndView mv = new ModelAndView();
//往request域存入数据
mv.addObject("JoJo","StarPlatinum" );
//设置跳转页面
mv.setViewName("success");
return mv;
}
}
forward:
response.getRequestDispatcher(url).forward(..)
/**
* 使用forward方式转发
*/
@RequestMapping("/forward")
public String forward(){
return "forward:/pages/success.jsp"; //指定跳转路径
}
contrller 方法提供了一个 String 类型返回值之后, 在返回值里使用redirect:
它相当于response.sendRedirect(url)
注意:重定向到jsp页面时,jsp页面不可放在WEB-INF目录下
/**
* 使用重定向转发
*/
@RequestMapping("/redirect")
public String redirect(){
return "redirect:/pages/success.jsp"; //指定跳转路径
}
multipart/form-data
,表示表单以文件上传形式提交。(一般表单提交数据不写该属性,默认值是application/x-www-form-urlencoded,表示不以文件上传形式提交)
**
<dependency>
<groupId>Commons-fileuploadgroupId>
<artifactId>Commons-fileuploadartifactId>
<version>1.3.1version>
dependency>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
upload
/**
* 使用传统方式:Apache提供的fileUpload组件实现文件上传
*/
@Controller
public class TraditionalUploadController {
@RequestMapping("/upload")
public void upload(HttpServletRequest request) throws Exception {
/*
实现文件上传思路:
1. 获取文件上传目录地址
2. 根据当前日期创建子目录(方便规整每天用户上传的图片)
3. 处理文件上传
3.1 创建文件上传核心工具类ServletFileUpload
3.2 使用核心工具类将表单数据封装到FileItem对象
3.3 遍历FileItem对象,获取每个表单元素,如果是普通元素,打印;如果是文件元素
3.3.1 获取文件名,并使用UUID规则使文件名唯一化(避免重名)
3.3.2 上传文件并删除临时文件
*/
//1. 获取文件上传目录地址
String realPath = request.getSession().getServletContext().getRealPath("/upload");
//文件上传的目标地址:E:/Java_study/JavaprojectsIV/day56project_SpringMVC_day2/target/day56project_SpringMVC_day2-1.0-SNAPSHOT/upload
System.out.println(realPath);
//2. 根据当前日期创建子目录(方便规整每天用户上传的图片)
String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
//创建目录
File file = new File(realPath,date);
if (!file.exists()) {
file.mkdirs();
}
//3. 处理文件上传
//创建FileItem工厂
FileItemFactory factory = new DiskFileItemFactory();
//3.1 创建文件上传核心工具类ServletFileUpload
ServletFileUpload upload = new ServletFileUpload(factory);
//3.2 使用核心工具类将表单数据封装到FileItem对象
List<FileItem> fileItems = upload.parseRequest(request);
//3.3 遍历FileItem对象,获取每个表单元素,如果是普通元素,打印;
for (FileItem fileItem : fileItems) {
//判断:如果是普通表单元素就获取打印
if (fileItem.isFormField()) {
String nameStr = fileItem.getString("UTF-8");
System.out.println("输入的用户名:" + nameStr);
} else {
//文件元素
//3.3.1 获取文件名,并使用UUID规则使文件名唯一化(避免重名)
String fileName = fileItem.getName();
fileName = UUID.randomUUID().toString().replaceAll("-","")+"_" +fileName;
//3.3.2 上传文件并删除临时文件
fileItem.write(new File(file,fileName));//父路径加文件名
fileItem.delete();
}
}
}
}
@Controller
public class SpringMVCUploadController {
/**
实现文件上传思路:
1. 获取文件上传目录地址
2. 根据当前日期创建子目录(方便规整每天用户上传的图片)
3. 处理文件上传
3.1 使用MultipartFile对象获取文件名,并使用UUID规则使文件名唯一化(避免重名)
3.2 直接使用MultipartFile对象的方法上传文件
*/
@RequestMapping("/upload2")
public String upload(HttpServletRequest request, MultipartFile imgFile) throws IOException {
//1. 获取文件上传目录地址
String realPath = request.getSession().getServletContext().getRealPath("/upload");
//文件上传的目标地址:E:/Java_study/JavaprojectsIV/day56project_SpringMVC_day2/target/day56project_SpringMVC_day2-1.0-SNAPSHOT/upload
System.out.println(realPath);
//2. 根据当前日期创建子目录(方便规整每天用户上传的图片)
String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
//创建目录
File file = new File(realPath,date);
if (!file.exists()) {
file.mkdirs();
}
//3. 处理文件上传
//3.1 使用MultipartFile对象获取文件名,并使用UUID规则使文件名唯一化(避免重名)
String fileName = imgFile.getOriginalFilename();
fileName = UUID.randomUUID().toString().replaceAll("-","")+"_" +fileName;
//3.2 直接使用MultipartFile对象的方法上传文件
imgFile.transferTo(new File(file,fileName));
//顺便把用户名打印一下吧
System.out.println(request.getParameter("username"));
//4. 如果使用返回void,由于没有指定返回的页面,默认返回到控制类方法的映射,即默认返回upload2,而项目没有/pages/upload2.jsp,会找不到返回页面而报错
//故指定返回的页面
return "upload";
}
}
使用文件上传解析器:CommonsMultipartResolver
注意事项:文件上传解析器的id是固定的(一定要是multipartResolver),不能起别的名称,否则无法实现请求参数的绑定
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760">property>
bean>
<dependency>
<groupId>com.sun.jerseygroupId>
<artifactId>jersey-coreartifactId>
<version>1.18.1version>
dependency>
<dependency>
<groupId>com.sun.jerseygroupId>
<artifactId>jersey-clientartifactId>
<version>1.18.1version>
dependency>
@Controller
public class SToSUploadController {
@RequestMapping("/upload3")
public String upload(HttpServletRequest request,MultipartFile imgFile) throws IOException {
//创建jersey包中提供的client对象
Client client = new Client();
//使用client和文件服务器建立联系
//6080是文件服务器的端口号
String uploadPath = "http://localhost:6080/fileSystem/upload/" + imgFile.getOriginalFilename();
WebResource webResource = client.resource(uploadPath);
//将web资源对象添加到文件服务器上
webResource.put(String.class,imgFile.getBytes());
return "success";
}
}