1. Ajax
1. 概念
(1)Ajax:Asynchronous JavaScript and XML(异步的 JavaScript 和 XML),是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术
(2)Ajax不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术
2. 用途
(1)注册时,输入用户名自动检测用户是否已经存在
(2)登陆时,提示用户名与密码错误
(3)删除数据时,将行ID发送给后台,后台在数据库删除,数据库删除成功后,在页面的DOM元素也进行删除
3. 核心:Ajax的核心是XMLHttpRequest(XHR)对象,XHR为向服务器发送请求和解析服务器提供的接口。能够以异步方式从服务器获取新数据
2. 使用JQuery实现Ajax
1. 概述:JQuery提供了多个与Ajax有关的方法。通过JQuery.Ajax的方法,能够使用HTTP GET 和HTTP POST从远程服务器请求文本、HTML、XML和JSON,同时把这些外部数据直接加载进网页中
2. 使用
(1)配置web.xml和spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置过滤器-->
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
<?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 https://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.nelws.controller"/>
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
(2)编写一个Controller
@RestController
public class AjaxController {
@RequestMapping("/t1")
public String test(){
return "ok";
}
@RequestMapping("/at1")
public void ajaxTest01(String name, HttpServletResponse response) throws IOException {
if ("admin".equals(name)){
response.getWriter().print("true");
}else {
response.getWriter().print("false");
}
}
}
(3)编写index.jsp进行测试
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
<script src="js/jquery-3.3.1.js"></script>
</head>
<body>
<%--onblur:失去焦点触发该事件--%>
用户名:<input type="text" id="txtName" onblur="a1()">
</body>
</html>
<script>
function a1() {
$.post({
url:"${pageContext.request.contextPath}/at1",
data:{"name":$("#txtName").val()},
success:function (data,status) {
console.log(data);
console.log(status);
}
})
}
</script>
(4)启动tomcat测试!打开浏览器的控制台,当我们鼠标离开输入框的时候,可以看到发出了一个ajax的请求!是后台返回给我们的结果!测试成功!
3. SpringMVC实现
(1)编写User类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private int age;
private String sex;
}
(2)获取一个集合对象,展示到前端页面
@RequestMapping("/at2")
public List<User> ajaxTest02(){
List<User> list = new ArrayList<User>();
list.add(new User("小王",12,"男"));
list.add(new User("小张",13,"男"));
list.add(new User("小刘",14,"女"));
return list;
}
(3)前端页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<input type="button" id="btn" value="获取数据">
<table>
<tr>
<td>姓名</td>
<td>年龄</td>
<td>性别</td>
</tr>
<tbody id="content">
</tbody>
</table>
</body>
</html>
<script src="js/jquery-3.3.1.js"></script>
<script>
$("#btn").click(function () {
$.post("${pageContext.request.contextPath}/at2",function (data) {
var html = "";
for(var i = 0;i < data.length;i++){
html += "<tr>" +
"<td>" + data[i].name + "</td>" +
"<td>" + data[i].age + "</td>" +
"<td>" + data[i].sex + "</td>" +
"</tr>"
}
$("#content").html(html);
})
})
</script>
4. 注册验证效果
(1)编写Controller
@RequestMapping("/at3")
public String ajaxTest03(String name,String pwd){
String msg = "";
//模拟从数据库中获取的数据
if (name != null){
if ("admin".equals(name)){
msg = "OK";
}else {
msg = "用户名错误";
}
}
if (pwd != null){
if ("123456".equals(pwd)){
msg = "OK";
}else {
msg = "密码错误";
}
}
return msg;
}
(2)编写前端界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<p>
用户名:<input type="text" id="name" onblur="a1()" />
<span id="nameInfo"/>
</p>
<p>
密码:<input type="text" id="pwd" onblur="a2()" />
<span id="pwdInfo"/>
</p>
</body>
</html>
<script src="js/jquery-3.3.1.js"></script>
<script>
function a1() {
$.post({
url:"${pageContext.request.contextPath}/at3",
data:{"name":$("#name").val()},
success:function (data) {
if (data.toString() == "OK"){
$("#nameInfo").css("color","green");
} else {
$("#nameInfo").css("color","red");
}
$("#nameInfo").html(data);
}
})
}
function a2() {
$.post({
url:"${pageContext.request.contextPath}/at3",
data:{"pwd":$("#pwd").val()},
success:function (data) {
if (data.toString() == "OK"){
$("#pwdInfo").css("color","green");
} else {
$("#pwdInfo").css("color","red");
}
$("#pwdInfo").html(data);
}
})
}
</script>
2. 拦截器
1. 简介:SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能
2. 拦截器与过滤器的区别:拦截器是AOP思想的具体应用
1. 过滤器
1. servlet规范中的一部分,任何java web工程都可以使用
2. 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截
2. 过滤器
1. 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
2. 拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的
3. 自定义拦截器:实现 HandlerInterceptor 接口
(1)配置web.xml和spring-mvc.xml
(2)编写一个拦截器
public class MyInterceptor implements HandlerInterceptor {
//在请求处理的方法之前执行
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
/**
* true:代表放行,执行下一个拦截器
* false:代表不通过,不执行下一个拦截器
*/
System.out.println("=======处理前=======");
return true;
}
//在请求处理的方法之后执行
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("=======处理后=======");
}
//在dispatcherServlet处理后执行,做清理工作
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("=======清理=======");
}
}
(3)在spring-mvc.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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.nelws.controller"/>
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/js/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--拦截所有-->
<mvc:mapping path="/**"/>
<bean class="com.nelws.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
(4)编写Controller接受请求
@RestController
public class TestController {
@RequestMapping("/interceptor")
public String testInterceptor(){
System.out.println("控制器中的方法执行了");
return "OK~";
}
}
(5)前端页面index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/interceptor">拦截器测试</a>
</body>
</html>
(6)配置tomcat并测试
4. 案例:验证用户是否登录
(1)需求:拦截用户请求,判断用户是否登录。如果用户已经登陆,则放行;如果用户未登录,则跳转至登录页面
(2)实现
- 编写index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/user/goLogin">登陆</a>
<a href="${pageContext.request.contextPath}/user/goSuccess">主页</a>
</body>
</html>
- 编写一个登陆页面login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录页面</title>
</head>
<body>
<h1>登录页面</h1>
<form action="${pageContext.request.contextPath}/user/login" method="post">
用户名:<input type="text" name="username">
密码:<input type="text" name="password">
<input type="submit" value="登陆">
</form>
</body>
</html>
- 编写一个Controller处理请求
@Controller
@RequestMapping("/user")
public class UserController {
//跳转至登录页面
@RequestMapping("/goLogin")
public String goLogin(){
return "login";
}
//跳转至成功页面
@RequestMapping("/goSuccess")
public String goSuccess(){
return "success";
}
//登陆提交
@RequestMapping("/login")
public String login(HttpSession session, String username, String password, Model model){
//向Session中存用户信息
session.setAttribute("userInfo",username);
model.addAttribute("username",username);
return "success";
}
//注销
@RequestMapping("/goOut")
public String goOut(HttpSession session){
session.removeAttribute("userInfo");
return "login";
}
}
- 编写登陆成功页面success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
</head>
<body>
<h1>首页</h1>
<h3>${username}</h3>
<a href="${pageContext.request.contextPath}/user/goOut">注销</a>
</body>
</html>
- 编写拦截器
public class UserInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//如果是登录界面则放行
if (request.getRequestURI().contains("login")){
return true;
}
if (request.getRequestURI().contains("goLogin")){
return true;
}
//如果用户已经登录也放行(Session中有东西)
HttpSession session = request.getSession();
if (session.getAttribute("userInfo") != null){
return true;
}
//用户没有登陆则跳转至登录页面
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
return false;
}
}
- 在spring-mvc.xml中注册拦截器
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--拦截所有-->
<mvc:mapping path="/**"/>
<bean class="com.nelws.interceptor.MyInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/user/**"/>
<bean class="com.nelws.interceptor.UserInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
- 测试
3. 文件上传与下载
1. 文件上传
(1)如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver
(2)前端表单要求:为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器
(3)实现(普通方法)
- 导入文件上传的jar包:commons-fileupload,maven会自动导入commons-io
<dependencies>
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<!--servlet-api导入高版本的-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>
- 配置bean:multipartResolver(这个bean的id必须是multipartResolver)
<?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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.nelws.controller"/>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--文件上传的配置-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
<!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
<property name="defaultEncoding" value="utf-8"/>
<!-- 上传文件大小上限,单位为字节(10485760=10M) -->
<property name="maxUploadSize" value="10485760"/>
<property name="maxInMemorySize" value="40960"/>
</bean>
</beans>
- 前端界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/upload" enctype="multipart/form-data" method="post">
<input type="file" name="file"/>
<input type="submit" value="upload">
</form>
</body>
</html>
- 编写Controller层
@RequestMapping("/upload")
public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {
//获取文件名 : file.getOriginalFilename();
String uploadFileName = file.getOriginalFilename();
//如果文件名为空,直接回到首页!
if ("".equals(uploadFileName)){
return "redirect:/index.jsp";
}
System.out.println("上传文件名 : "+uploadFileName);
//上传路径保存设置
String path = request.getServletContext().getRealPath("/upload");
//如果路径不存在,创建一个
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
System.out.println("上传文件保存地址:"+realPath);
InputStream is = file.getInputStream(); //文件输入流
OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流
//读取写出
int len=0;
byte[] buffer = new byte[1024];
while ((len=is.read(buffer))!=-1){
os.write(buffer,0,len);
os.flush();
}
os.close();
is.close();
return "redirect:/index.jsp";
}
- 测试
(4)实现(file.Transto)
- 编写Controller
/*
* 采用file.Transto 来保存上传的文件
*/
@RequestMapping("/upload2")
public String fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
//上传路径保存设置
String path = request.getServletContext().getRealPath("/upload");
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
//上传文件地址
System.out.println("上传文件保存地址:"+realPath);
//通过CommonsMultipartFile的方法直接写文件(注意这个时候)
file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));
return "redirect:/index.jsp";
}
- 前端表单地址修改
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/upload2" enctype="multipart/form-data" method="post">
<input type="file" name="file"/>
<input type="submit" value="upload">
</form>
</body>
</html>
- 测试
2. 文件下载
(1)编写Controller
@RequestMapping("/download")
public String downloads(HttpServletResponse response, HttpServletRequest request) throws Exception {
//要下载的图片地址
String path = request.getServletContext().getRealPath("/upload"); //可以更改
String fileName = "发票抬头.jpg"; //可以更改
//1、设置response 响应头
response.reset(); //设置页面不缓存,清空buffer
response.setCharacterEncoding("UTF-8"); //字符编码
response.setContentType("multipart/form-data"); //二进制传输数据
//设置响应头
response.setHeader("Content-Disposition",
"attachment;fileName="+URLEncoder.encode(fileName, "UTF-8"));
File file = new File(path,fileName);
//2、 读取文件--输入流
InputStream input=new FileInputStream(file);
//3、 写出文件--输出流
OutputStream out = response.getOutputStream();
byte[] buff =new byte[1024];
int index=0;
//4、执行 写出操作
while((index= input.read(buff))!= -1){
out.write(buff, 0, index);
out.flush();
}
out.close();
input.close();
return null;
}
(2)测试