Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 Servlet,属于SpringFrameWork的后续产品。Spring MVC 本身就是 Spring 框架的一部分,与 Spring 框架是无缝集成的。
MVC架构
MVC模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。除此之外,此模式透过对复杂度的简化,使程序结构更加直观。软件系统透过对自身基本部分分离的同时也赋予了各个基本部分应有的功能。
模型(Model) - 程序员编写程序应有的功能(实现算法等等)、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。
视图(View) - 界面设计人员进行图形界面设计。
控制器(Controller)- 负责转发请求,对请求进行处理。
1.Model1
1.Modedl1主要分为两层,视图层和模型层。
2.JSP职责不单一,职责过重,不便于维护
2.Model2
1.用户发送请求->Servlet接受请求数据并调用对应的业务逻辑方法->业务处理完成后返回给更新后的数据给Servlet->Servlet转向到JSP,由JSP渲染页面->响应给前端更新后的页面
2.Controller
3.Model
4.View
Servlet回顾 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 <?xml version="1.0" encoding="UTF-8"?> <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.0</modelVersion > <groupId > com.ling</groupId > <artifactId > SpringMVC</artifactId > <packaging > pom</packaging > <version > 1.0-SNAPSHOT</version > <modules > <module > SpringMVC-01-Servlet</module > <module > SpringMVC-02-Hello</module > </modules > <properties > <maven.compiler.source > 8</maven.compiler.source > <maven.compiler.target > 8</maven.compiler.target > </properties > <dependencies > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.13.2</version > <scope > test</scope > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > 5.3.13</version > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > servlet-api</artifactId > <version > 2.5</version > <scope > provided</scope > </dependency > <dependency > <groupId > javax.servlet.jsp</groupId > <artifactId > jsp-api</artifactId > <version > 2.2</version > <scope > provided</scope > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > jstl</artifactId > <version > 1.2</version > </dependency > </dependencies > </project >
📣 使用Tomca9是一种明智的选择 ,Spring Framework尚未做到与Tomcat10 jakarta命名空间更改兼容,Tomcat10目前不能用于Spring框架(包括SpringBoot )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <dependencies > <dependency > <groupId > jakarta.servlet</groupId > <artifactId > jakarta.servlet-api</artifactId > <version > 5.0.0</version > <scope > provided</scope > </dependency > <dependency > <groupId > jakarta.servlet.jsp</groupId > <artifactId > jakarta.servlet.jsp-api</artifactId > <version > 3.0.0</version > <scope > provided</scope > </dependency > <dependency > <groupId > org.glassfish.web</groupId > <artifactId > jakarta.servlet.jsp.jstl</artifactId > <version > 2.0.0</version > </dependency > </dependencies >
👉 对于Spring MVC 5,Spring MVC DispatcherServlet 依赖于 javax.servlet.*
包命名空间(使用 Java EE 8 javax
包),而 Tomcat10 基于 Jakarta EE 9。(Tomcat10将所有包从javax.servlet重命名为 jakarta.servlet,目前 Spring Boot 和 Spring Framework 都不支持 Jakarta EE 9,可能在 Spring Framework 6 和 Spring Boot 3 对Tomcat10提供支持)
❓ 参考:Support for Jakarta EE 9
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class HelloServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getParameter("method" ); if (method.equals("add" )){ req.getSession().setAttribute("msg" ,"The add method was executed" ); } else if (method.equals("delete" )){ req.getSession().setAttribute("msg" ,"The delete method was executed" ); } req.getRequestDispatcher("/WEB-INF/jsp/test.jsp" ).forward(req,resp); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 <%--form.jsp--%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="/hello" method="post" > <input type="text" name="method" > <input type="submit" > </form> </body> </html>
1 2 3 4 5 6 7 8 9 10 <%-- test.jsp --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${msg} </body> </html>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns ="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version ="5.0" > <servlet > <servlet-name > Hello</servlet-name > <servlet-class > com.ling.servlet.HelloServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > Hello</servlet-name > <url-pattern > /hello</url-pattern > </servlet-mapping > </web-app >
1.MVC框架:
将url映射到java类或java类的方法
封装用户提交的数据
处理请求->调用相关的业务请求->封装响应数据
将响应的数据用jsp/html进行渲染
2.常见的服务器端MVC框架有:Struts、Spring MVC、ASP.NET MVC、Zend Framework、JSF
3.常见前端MVC框架:Angular、React、Backbone、Vue
SpringMVC Docs
SpringMVC:
轻量级,简单易学
高效,基于请求响应的MVC框架
与Spring无缝集成
约定大于配置
职责分离清晰
强大的适配能力、非侵入性和灵活性
可定制的数据绑定和验证、处理器映射和视图解析
灵活的模型传递
Spring MVC 框架是围绕 DispatcherServlet(继承 HttpServlet 基类) 来设计的,这个 Servlet 会把请求分发给各个处理器,并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染和文件上传等功能(以请求为驱动,围绕一个中心Servlet分派请求及提供其他功能)。
SpringMVC流程
1.🔧DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。
2.🔧DispatcherServlet调用HandlerMapping(处理器映射器),HandlerMapping根据请求信息(url)查找handler(根据xml配置以及注解),返回HandlerExecutionChain对象(封装一个Handler对象和多个Handlerinterceptor拦截器)。
3.🔧DispatcherServlet调用HandlerAdapter(处理器适配器)执行对应的Handler(Controller)。
4.🔧Handler(Controller)执行后将ModelAndView返回给HandlerAdapter。
5.🔧HandlerAdapter将ModelAndView传递给DispatcherServlet。
6.🔧DispatcherServlet调用ViewResolver(视图解析器)来解析ModelAndView(根据逻辑视图名modelAndView.setViewName()
或者传入Model参数之后return字符串
解析成物理视图名)。
7.🔧ViewResolver解析后返回View视图对象给DispatcherServlet。
8.🔧DispatcherServlet根据ViewResolver返回的View视图对象进行视图渲染(模型数据填充到视图中modelAndView.addObject()->${}
)。
9.🔧将视图(jsp页面)返回给客户端(响应用户)。
1.编写web.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns ="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version ="5.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:springmvc-servlet.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 > </web-app >
2.编写SpringMVC配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" > <bean class ="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" /> <bean class ="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" /> <bean class ="org.springframework.web.servlet.view.InternalResourceViewResolver" id ="internalResourceViewResolver" > <property name ="prefix" value ="/WEB-INF/jsp/" /> <property name ="suffix" value =".jsp" /> </bean > <bean id ="/hello" class ="com.ling.controller.HelloController" /> </beans >
3.编写操作业务Controller
1 2 3 4 5 6 7 8 9 10 11 12 public class HelloController implements Controller { public ModelAndView handleRequest (HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mv = new ModelAndView(); mv.addObject("msg" ,"->SpringMVC<-" ); mv.setViewName("hello" ); return mv; } }
4.注册该类到Spring容器中
1 <bean id ="/hello" class ="com.ling.controller.HelloController" />
5.编写跳转页面,显示ModelandView存放的数据
1 2 3 4 5 6 7 8 9 10 <%-- WEB/WEB-INF/jsp/hello.jsp --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${msg} </body> </html>
出现404错误,排查jar包是否存在,在IDEA的项目发布中添加lib依赖(Project Structure->Project Settings->Artifacts->对应Spring项目或模块->在WEB-INF下新建lib文件夹->选择该文件夹点击+号->Library Files->Ctrl选择所有添加->重启Tomcat)
注解开发 1.配置web.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns ="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version ="5.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:springmvc-servlet.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 > </web-app >
2.编写Spring MVC配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <?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.ling.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 > </beans >
3.创建Contrllor类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package com.ling.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;@Controller @RequestMapping("/hello") public class HelloController { @RequestMapping("/h1") public String hello (Model model) { model.addAttribute("msg" ,"->Interview h1 Page" ); return "hello" ; } @RequestMapping("/h2") public String h2Method (Model model) { model.addAttribute("msg" ,"->Interview h2 Page" ); return "hello" ; } }
4.编写前端View视图页面
1 2 3 4 5 6 7 8 9 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> msg: ${msg} </body> </html>
Controller
控制器Controller:
控制器负责提供访问应用程序的行为,通常通过接口定义和注解定义两种方法实现。
控制器负责解析用户的请求并将其转换为一个模型。
在SpringMVC中一个控制器类可以包含多个方法。
1.实现Controller接口(实现该接口的类即为一个控制器)
1 2 3 4 5 6 @FunctionalInterface public interface Controller { @Nullable ModelAndView handleRequest (HttpServletRequest request, HttpServletResponse response) throws Exception ; }
1 2 3 4 5 6 7 8 9 10 public class ControllerDemo implements Controller { @Override public ModelAndView handleRequest (HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mv = new ModelAndView(); mv.addObject("msg" ,"Controller1" ); mv.setViewName("test" ); return mv; } }
2.使用注解@Controller
1.@Controller注解用于声明Spring类的实例是一个控制器。
2.Spring使用扫描机制来找到应用程序中所有基于注解的控制器类,需要在配置文件中声明组件扫描。
1 2 3 4 5 6 7 8 @Controller public class ControllerDemo2 { @RequestMapping("/demo2") public String test (Model model) { model.addAttribute("msg" ,"Controller2" ); return "test" ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <?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" 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" > <context:component-scan base-package ="com.ling.controller" /> <bean class ="org.springframework.web.servlet.view.InternalResourceViewResolver" id ="internalResourceViewResolver" > <property name ="prefix" value ="/WEB-INF/jsp/" /> <property name ="suffix" value =".jsp" /> </bean > <bean name ="/demo" class ="com.ling.controller.ControllerDemo" /> </beans > <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns ="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" version ="5.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:springmvc-servlet.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 > </web-app >
RequestMapping
@RequestMapping注解用于映射url到Controller类或Controller类中特定方法,可用于类或方法上。用于类上可表示类中的所有响应请求的方法都是以该地址作为父地址。
1.注解在方法上
1 2 3 4 5 6 7 8 9 @Controller public class ControllerDemo2 { @RequestMapping("/d2") public String test (Model model) { model.addAttribute("msg" ,"->Demo2" ); return "test" ; } }
2.注解类和方法
1 2 3 4 5 6 7 8 9 10 @Controller @RequestMapping("/Demo") public class ControllerDemo2 { @RequestMapping("/d2") public String test (Model model) { model.addAttribute("msg" ,"Demo->Demo2" ); return "test" ; } }
RestFUL风格
1.表现层状态转换(Representational State Transfer,REST)是Roy Thomas Fielding博士于2000年在他的博士论文中提出来的一种万维网软件架构风格,目的是便于不同软件/程序在网络(例如互联网)中互相传递信息。表现层状态转换是基于超文本传输协议(HTTP)之上而确定的一组约束和属性,是一种设计提供万维网络服务的软件构建风格。符合或兼容于这种架构风格(简称为 REST 或 RESTful)的网络服务,允许客户端发出以统一资源标识符访问和操作网络资源的请求,而与预先定义好的无状态操作集一致化。因此表现层状态转换提供了在互联网络的计算系统之间,彼此资源可交互使用的协作性质(interoperability)。相对于其它种类的网络服务,例如SOAP服务,则是以本身所定义的操作集,来访问网络上的资源。
2.REST是设计风格而不是标准。REST通常基于HTTP、URI、XML以及HTML这些现有的广泛流行的协议和标准。
3.可重新表达的状态迁移的特征
Uniform Interface:统一接口。
以资源为基础
通过重表达的客户端可以管理原资源
返回信息足够描述自己
超媒体是应用状态的引擎
Stateless:无状态。
Cacheable:可缓存。
Client-Server:客户服务器分离模式,任何一个客户端与服务器都是可替换的。
Layered System:分层的系统,客户端不知道他联系的是不是最终服务器。
Code on Demand(可选):服务器可以将能力扩展到客户端,如果客户端可以执行的话。这个功能是可选择的
4.REST优点
可更高效利用缓存来提高响应速度
通讯本身的无状态性可以让不同的服务器的处理一系列请求中的不同请求,提高服务器的扩展性
浏览器即可作为客户端,简化软件需求
相对于其他叠加在HTTP协议之上的机制,REST的软件依赖性更小
不需要额外的资源发现机制
在软件技术演进中的长期的兼容性更好
5.Example
1 GET http:// www.store.com/products
1 2 GET http:// www.store.com/products/ 12345
1 2 3 4 POST http: <purchase-order> <item> ... </item> </purchase-order>
在SpringMVC中可以使用@PathVariable注解,让方法参数的值绑定到对应的URI模板变量上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 @Controller public class RestFulController { @RequestMapping("/add/{a}/{b}") public String test1 (@PathVariable int a,@PathVariable int b, Model model) { model.addAttribute("msg" ,"Result: " +(a+b)); return "test" ; } @RequestMapping(value = "/mul/{a}/{b}",method = RequestMethod.GET) public String test2 (@PathVariable int a,@PathVariable int b, Model model) { model.addAttribute("msg" ,"Get Result: " +(a*b)); return "test" ; } @GetMapping(value = "/division/{a}/{b}") public String test3 (@PathVariable int a,@PathVariable int b, Model model) { model.addAttribute("msg" ,"Get Result: " +(a/b)); return "test" ; } @PostMapping(value = "/division/{a}/{b}") public String test4 (@PathVariable int a,@PathVariable int b, Model model) { model.addAttribute("msg" ,"Post Result: " +(a/b)); return "test" ; } }
重定向和转发 1.ModelAndView:设置ModelAndView,视图解析器根据View名称返回真正的视图对象。
1 2 3 4 5 6 7 8 9 public class ControllerDemo implements Controller { @Override public ModelAndView handleRequest (HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mv = new ModelAndView(); mv.addObject("msg" ,"Controller1" ); mv.setViewName("test" ); return mv; } }
1 2 3 4 5 <bean class ="org.springframework.web.servlet.view.InternalResourceViewResolver" id ="internalResourceViewResolver" > <property name ="prefix" value ="/WEB-INF/jsp/" /> <property name ="suffix" value =".jsp" /> </bean >
2.Servlet API
通过设置ServletAPI,不需要视图解析器
通过HttpServletResponse进行输出或者重定向
通过HttpServletRequest实现转发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Controller public class ServletController { @RequestMapping("/rw") public void test1 (HttpServletRequest req, HttpServletResponse resp) throws IOException { HttpSession session = req.getSession(); resp.getWriter().print("<h1>Method test1</h1>" ); resp.getWriter().print("<p>" +session.getId()+"</p>" ); } @RequestMapping("/rr") public void test2 (HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.sendRedirect("/index.jsp" ); } @RequestMapping("/rd") public void test3 (HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { req.setAttribute("msg" ,"Method test3" ); req.getRequestDispatcher("/WEB-INF/jsp/test.jsp" ).forward(req,resp); } }
3.SpringMVC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package com.ling.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;@Controller public class NotViewReController { @RequestMapping("/rsp/m1") public String test1 () { return "/index.jsp" ; } @RequestMapping("/rsp/m2") public String test2 () { return "forward:/index.jsp" ; } @RequestMapping("/rsp/m3") public String test3 () { return "redirect:/index.jsp" ; } @RequestMapping("/rsp/m4") public String test4 (Model model) { model.addAttribute("msg" ,"-Method test4-" ); return "forward:/WEB-INF/jsp/test.jsp" ; } }
1 2 3 4 5 <bean class ="org.springframework.web.servlet.view.InternalResourceViewResolver" id ="internalResourceViewResolver" > <property name ="prefix" value ="/WEB-INF/jsp/" /> <property name ="suffix" value =".jsp" /> </bean >
1 2 3 4 5 6 7 8 9 10 11 12 13 @Controller public class ViewReController { @RequestMapping("/test") public String test1 () { return "test" ; } @RequestMapping("/test2") public String test2 () { return "redirect:/index.jsp" ; } }
数据处理
1.提交的域名称和处理方法的参数名一致
1 2 3 4 5 6 7 @RequestMapping("/hello") public String test1 (String name, Model model) { model.addAttribute("msg" ,"Hello " +name); System.out.println("Name:" +name); return "test" ; }
2.提交的域名称和处理方法的参数名不一致
1 2 3 4 5 6 7 @RequestMapping("/helloUser") public String test2 (@RequestParam("username") String name, Model model) { model.addAttribute("msg" ,"Hello " +name); System.out.println("Name:" +name); return "test" ; }
3.提交的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 public class User { private String name; private int id; private int age; public User (String name, int id, int age) { this .name = name; this .id = id; this .age = age; } @Override public String toString () { return "User{" + "name='" + name + '\'' + ", id=" + id + ", age=" + age + '}' ; } }
1 2 3 4 5 6 7 @RequestMapping("/userhello") public String test3 (User user,Model model) { model.addAttribute("msg" ,"Hello " + user); System.out.println(user.toString()); return "test" ; }
1.ModelAndView
1 2 3 4 5 6 7 8 9 public class ControllerDemo3 implements Controller { @Override public ModelAndView handleRequest (HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView mv = new ModelAndView(); mv.addObject("msg" ,"Method with ModelAndView" ); mv.setViewName("test" ); return mv; } }
2.ModelMap
1 2 3 4 5 @RequestMapping("/test") public String hello1 (String name, ModelMap modelMap) { modelMap.addAttribute("msg" ,"method with ModelMap" +" and name: " +name); return "test" ; }
3.Model
1 2 3 4 5 @RequestMapping("/test2") public String hello2 (String name, Model model) { model.addAttribute("msg" ,"method with Model" +" and name: " +name); return "test" ; }
ModelMap 继承了 LinkedMap ,除了实现了自身的方法,同样的继承 LinkedMap 的方法和特性。
ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。
中文乱码 1 2 3 4 5 6 7 8 9 @Controller public class EncodingController { @PostMapping("/e/t1") public String test1 (String name, Model model) { System.out.println(name); model.addAttribute("msg" ,name); return "test" ; } }
1 2 3 4 5 6 7 8 9 10 11 12 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="/e/t1" method="post" > <input type="text" name="name" > <input type="submit" > </form> </body> </html>
1.自定义Fileter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class EncodingFilter implements Filter { @Override public void init (FilterConfig filterConfig) throws ServletException { } @Override public void doFilter (ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException { req.setCharacterEncoding("utf-8" ); resp.setCharacterEncoding("utf-8" ); filterChain.doFilter(req,resp); } @Override public void destroy () { } }
web.xml中注册
1 2 3 4 5 6 7 8 9 10 <filter > <filter-name > encoding</filter-name > <filter-class > com.ling.filter.EncodingFilter</filter-class > </filter > <filter-mapping > <filter-name > encoding</filter-name > <url-pattern > /*</url-pattern > </filter-mapping >
2.使用Spring框架的过滤器
1 2 3 4 5 6 7 8 9 10 11 12 <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 >
乱码问题仍然无法解决
1.修改tomcat配置文件:
1 2 3 <Connector URIEncoding ="utf-8" port ="8080" protocol ="HTTP/1.1" connectionTimeout ="20000" redirectPort ="8443" />
2.自定义过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 public class GenericEncodingFilter implements Filter { @Override public void destroy () { } @Override public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse myResponse=(HttpServletResponse) response; myResponse.setContentType("text/html;charset=UTF-8" ); HttpServletRequest httpServletRequest = (HttpServletRequest) request; HttpServletRequest myrequest = new MyRequest(httpServletRequest); chain.doFilter(myrequest, response); } @Override public void init (FilterConfig filterConfig) throws ServletException { } } class MyRequest extends HttpServletRequestWrapper { private HttpServletRequest request; private boolean hasEncode; public MyRequest (HttpServletRequest request) { super (request); this .request = request; } @Override public Map getParameterMap () { String method = request.getMethod(); if (method.equalsIgnoreCase("post" )) { try { request.setCharacterEncoding("utf-8" ); return request.getParameterMap(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } else if (method.equalsIgnoreCase("get" )) { Map<String, String[]> parameterMap = request.getParameterMap(); if (!hasEncode) { for (String parameterName : parameterMap.keySet()) { String[] values = parameterMap.get(parameterName); if (values != null ) { for (int i = 0 ; i < values.length; i++) { try { values[i] = new String(values[i] .getBytes("ISO-8859-1" ), "utf-8" ); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } } hasEncode = true ; } return parameterMap; } return super .getParameterMap(); } @Override public String getParameter (String name) { Map<String, String[]> parameterMap = getParameterMap(); String[] values = parameterMap.get(name); if (values == null ) { return null ; } return values[0 ]; } @Override public String[] getParameterValues(String name) { Map<String, String[]> parameterMap = getParameterMap(); String[] values = parameterMap.get(name); return values; } }
JSON
1.JSON(JavaScript Object Notation)是由Douglas Crockford构想和设计的一种轻量级资料交换格式 。其内容由属性和值所组成,因此也有易于阅读和处理 的优势。JSON是独立于编程语言的资料(文本)格式 ,其不仅是JavaScript的子集,也采用了C语言家族的习惯用法,目前也有许多编程语言都能够将其解析和字符串化,其广泛使用的程度也使其成为通用的资料格式。JSON格式是1999年《JavaScript Programming Language, Standard ECMA-262 3rd Edition》的子集合,所以可以在JavaScript以eval()函数(javascript通过eval()调用解析器)读入。不过这并不代表JSON无法使用于其他语言,事实上几乎所有与网络开发相关的语言都有JSON函数库。
2.JSON的基本数据类型:
数值:十进制数,不能有前导0,可以为负数,可以有小数部分。还可以用e或者E表示指数部分。不能包含非数,如NaN。不区分整数与浮点数。JavaScript用双精度浮点数表示所有数值。
字符串:以双引号""
括起来的零个或多个Unicode码位。支持反斜杠开始的转义字符序列。
布尔值:表示为true
或者false
。
数组:有序的零个或者多个值。每个值可以为任意类型。序列表使用方括号[
,]
括起来。元素之间用逗号,
分割 。形如:[value, value]
对象:若干无序的"键-值对"(key-value pairs),其中键只能是字符串。建议但不强制要求对象中的键是独一无二的。对象以花括号{
开始,并以}
结束。 键-值对之间使用逗号分隔 。键与值之间用冒号:分割 。
空值:值写为null
。
3.token(6种标点符号、字符串、数值、3种字面量)之间可以存在有限的空白符并被忽略。四个特定字符被认为是空白符:空格符、水平制表符、回车符、换行符。空白符不能出现在token内部(但空格符可以出现在字符串内部)。
4.JSON标准不允许有字节序掩码,不提供注释的句法。
5.一个有效的JSON文档的根节点必须是一个对象或一个数组。
6.JSON交换时必须编码为UTF-8。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 { "firstName" : "John" , "lastName" : "Smith" , "sex" : "male" , "age" : 25 , "address" : { "streetAddress" : "21 2nd Street" , "city" : "New York" , "state" : "NY" , "postalCode" : "10021" }, "phoneNumber" : [ { "type" : "home" , "number" : "212 555-1234" }, { "type" : "fax" , "number" : "646 555-4567" } ] }
从 JSON 字符串转换为 JavaScript 对象,使用 JSON.parse() 方法:
1 var obj = JSON .parse('{"a": "Hello", "b": "World"}' );
从 JavaScript 对象转换为 JSON 字符串,使用 JSON.stringify() 方法:
1 var json = JSON .stringify({a : 'Hello' , b : 'World' });
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > <script type ="text/javascript" > var user={ name :"JavaScript" , age :3 , sex :"male" } var json = JSON .stringify(user) var obj = JSON .parse(json) console .log(json) console .log(obj) </script > </head > <body > </body > </html >
Java JSON
1.导入依赖,配置web.xml pom.xml springmvc-servlet.xml
1 2 3 4 5 6 7 <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-databind</artifactId > <version > 2.13.0</version > </dependency >
2.编写对应实体类
1 2 3 4 5 6 7 8 9 @Data @AllArgsConstructor @NoArgsConstructor public class User { private String name; private int id; private String sex; }
3.编写对应Controller类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Controller public class UserController { @RequestMapping("/j1") @ResponseBody public String jsonDemo () throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); User user = new User("伍六" ,12 ,"male" ); String str = mapper.writeValueAsString(user); return str; } }
乱码问题还可以在springmvc的配置文件中加入消息StringHttpMessageConverter转换配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <mvc:annotation-driven > <mvc:message-converters register-defaults ="true" > <bean class ="org.springframework.http.converter.StringHttpMessageConverter" > <constructor-arg value ="UTF-8" /> </bean > <bean class ="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" > <property name ="objectMapper" > <bean class ="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean" > <property name ="failOnEmptyBeans" value ="false" /> </bean > </property > </bean > </mvc:message-converters > </mvc:annotation-driven >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 @RestController public class UserController { @RequestMapping("/j2") public String jsonDemo () throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); List<User> userList = new ArrayList<User>(); User user = new User("伍六" ,12 ,"male" ); User user1 = new User("七八" ,12 ,"male" ); User user2 = new User("九十" ,12 ,"female" ); userList.add(user); userList.add(user1); userList.add(user2); String str = mapper.writeValueAsString(userList); return str; } @RequestMapping("/j3") public String jsonDemo2 () throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false ); Date date = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" ); mapper.setDateFormat(simpleDateFormat); return mapper.writeValueAsString(date); } }
4.提取出JSON工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class JsonUtils { public static String getJson (Object object) { return getJson(object,"yyyy-MM-dd HH:mm:ss" ); } public static String getJson (Object object,String dateFormat) { ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false ); SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); mapper.setDateFormat(sdf); try { return mapper.writeValueAsString(object); } catch (JsonProcessingException e) { e.printStackTrace(); } return null ; } }
1 2 3 4 5 6 @RequestMapping("/j2") public String jsonDemo () throws JsonProcessingException { Date date = new Date(); String json = JsonUtils.getJson(date); return json; }
FastJSON
1.fastjson.jar是阿里开发的一款用于Java开发的包,可以方便的实现json对象与JavaBean对象的转换,实现JavaBean对象与json字符串的转换,实现json对象与json字符串的转换。
2.fastjson三个主要类:
JSONObject:json对象
JSONObject实现了Map接口
JSONObject对应json对象,通过各种形式的get()方法可以获取json对象中的数据,也可用如size(),isEmpty()等方法获取"键:值"对的个数和判断是否为空
JSONArray:json对象数组
1 2 3 4 5 6 <dependency > <groupId > com.alibaba</groupId > <artifactId > fastjson</artifactId > <version > 1.2.78</version > </dependency >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class FastJsonDemo { public static void main (String[] args) { User user1 = new User("Model1" , 1 , "male" ); User user2 = new User("Model2" , 2 , "male" ); User user3 = new User("Model3" , 3 , "female" ); User user4 = new User("Model4" , 4 , "female" ); List<User> list = new ArrayList<User>(); list.add(user1); list.add(user2); list.add(user3); list.add(user4); String str1 = JSON.toJSONString(list); System.out.println("JSON.toJSONString(list)==>" +str1); String str2 = JSON.toJSONString(user1); System.out.println("JSON.toJSONString(user1)==>" +str2); User jp_user1=JSON.parseObject(str2,User.class); System.out.println("JSON.parseObject(str2,User.class)==>" +jp_user1); JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2); System.out.println("(JSONObject) JSON.toJSON(user2)==>" +jsonObject1.getString("name" )); User to_java_user = JSON.toJavaObject(jsonObject1, User.class); System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>" +to_java_user); } }
SSM整合 1.搭建数据库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 CREATE DATABASE ssmbuild;USE ssmbuild; CREATE TABLE `books`(`bookID` INT NOT NULL AUTO_INCREMENT COMMENT '书id' , `bookName` VARCHAR (100 ) NOT NULL COMMENT '书名' , `bookCounts` INT NOT NULL COMMENT '数量' , `detail` VARCHAR (200 ) NOT NULL COMMENT '描述' , KEY `bookID`(`bookID`) )ENGINE= INNODB DEFAULT CHARSET= utf8; INSERT INTO `books`(`bookID`,`bookName`,`bookCounts`,`detail`)VALUES (1 ,'Java' ,1 ,'Java核心技术' ), (2 ,'MySQL' ,10 ,'MySQL必知必会' ), (3 ,'Linux' ,5 ,'鸟哥的Linux私房菜' )
2.新建Maven项目,添加Web支持
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 <?xml version="1.0" encoding="UTF-8"?> <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.0</modelVersion > <groupId > org.noob</groupId > <artifactId > SSM</artifactId > <version > 1.0-SNAPSHOT</version > <properties > <maven.compiler.source > 8</maven.compiler.source > <maven.compiler.target > 8</maven.compiler.target > </properties > <dependencies > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.13.2</version > <scope > test</scope > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 8.0.27</version > </dependency > <dependency > <groupId > com.mchange</groupId > <artifactId > c3p0</artifactId > <version > 0.9.5.5</version > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > servlet-api</artifactId > <version > 2.5</version > <scope > provided</scope > </dependency > <dependency > <groupId > javax.servlet.jsp</groupId > <artifactId > jsp-api</artifactId > <version > 2.2</version > <scope > provided</scope > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > jstl</artifactId > <version > 1.2</version > </dependency > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.5.7</version > </dependency > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis-spring</artifactId > <version > 2.0.6</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > 5.3.13</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-jdbc</artifactId > <version > 5.3.13</version > </dependency > <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > <version > 1.18.20</version > <scope > provided</scope > </dependency > </dependencies > <build > <resources > <resource > <directory > src/main/java</directory > <includes > <include > **/*.properties</include > <include > **/*.xml</include > </includes > <filtering > false</filtering > </resource > <resource > <directory > src/main/resources</directory > <includes > <include > **/*.properties</include > <include > **/*.xml</include > </includes > <filtering > false</filtering > </resource > </resources > </build > </project >
3.编写数据库对应实体类
1 2 3 4 5 6 7 8 9 @Data @AllArgsConstructor @NoArgsConstructor public class Books { private int bookID; private String bookName; private int bookCounts; private String detail; }
4.配置Mybatis核心文件以及配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd" > <configuration > <typeAliases > <package name ="com.ling.pojo" /> </typeAliases > <mappers > <mapper class ="com.ling.dao.BookMapper" /> </mappers > </configuration >
1 2 3 4 5 jdbc.driver =com.mysql.cj.jdbc.Driver jdbc.url =jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai jdbc.username =root jdbc.password =0513
5.编写数据库CRUD接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package com.ling.dao;import com.ling.pojo.Books;import java.util.List;public interface BookMapper { int addBook (Books books) ; int deleteBook (int id) ; int updateBook (Books books) ; Books queryBookByID (int id) ; List<Books> queryAllBook () ; List<Books> queryBookByName (String bookName) ; }
6.编写接口对应mapper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="com.ling.dao.BookMapper" > <insert id ="addBook" parameterType ="Books" > insert into ssmbuild.books(bookName, bookCounts, detail) values (#{bookName}, #{bookCounts}, #{detail}) </insert > <delete id ="deleteBook" parameterType ="int" > delete from ssmbuild.books where bookID = #{bookID}; </delete > <update id ="updateBook" parameterType ="Books" > update ssmbuild.books set bookName=#{bookName}, bookCounts=#{bookCounts}, detail=#{detail} where bookID=#{bookID}; </update > <select id ="queryBookByID" resultType ="Books" > select * from ssmbuild.books where bookID=#{bookID} </select > <select id ="queryAllBook" resultType ="Books" > select * from ssmbuild.books </select > <select id ="queryBookByName" resultType ="Books" > select * from ssmbuild.books where bookName like concat('%',#{bookName},'%'); </select > </mapper >
提示信息:
在settings–>Languages&Frameworks–>SQL Dialects中配置数据库类型,将项目添加进去
在IDEA中连接Mysql数据库对应库的database
7.编写Service层接口
1 2 3 4 5 6 7 8 public interface BookService { int addBook (Books books) ; int deleteBook (int id) ; int updateBook (Books books) ; Books queryBookByID (int id) ; List<Books> queryAllBook () ; List<Books> queryBookByName (String bookName) ; }
8.编写Service层接口实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public class BookServiceImpl implements BookService { private BookMapper bookMapper; public void setBookMapper (BookMapper bookMapper) { this .bookMapper=bookMapper; } public int addBook (Books books) { return bookMapper.addBook(books); } @Override public int deleteBook (int id) { return bookMapper.deleteBook(id); } @Override public int updateBook (Books books) { return bookMapper.updateBook(books); } @Override public Books queryBookByID (int id) { return bookMapper.queryBookByID(id); } @Override public List<Books> queryAllBook () { return bookMapper.queryAllBook(); } @Override public List<Books> queryBookByName (String bookName) { return bookMapper.queryBookByName(bookName); } }
9.编写Spring配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <?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" 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" > <context:property-placeholder location ="classpath:database.properties" /> <bean id ="dataSource" class ="com.mchange.v2.c3p0.ComboPooledDataSource" > <property name ="driverClass" value ="${jdbc.driver}" /> <property name ="jdbcUrl" value ="${jdbc.url}" /> <property name ="user" value ="${jdbc.username}" /> <property name ="password" value ="${jdbc.password}" /> <property name ="maxPoolSize" value ="30" /> <property name ="minPoolSize" value ="10" /> <property name ="autoCommitOnClose" value ="false" /> <property name ="checkoutTimeout" value ="10000" /> <property name ="acquireRetryAttempts" value ="2" /> </bean > <bean id ="sqlSessionFactory" class ="org.mybatis.spring.SqlSessionFactoryBean" > <property name ="dataSource" ref ="dataSource" /> <property name ="configLocation" value ="classpath:mybatis-config.xml" /> </bean > <bean class ="org.mybatis.spring.mapper.MapperScannerConfigurer" > <property name ="sqlSessionFactoryBeanName" value ="sqlSessionFactory" /> <property name ="basePackage" value ="com.ling.dao" /> </bean > </beans >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?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" 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" > <context:component-scan base-package ="com.ling.service" /> <bean id ="BookServiceImpl" class ="com.ling.service.BookServiceImpl" > <property name ="bookMapper" ref ="bookMapper" /> </bean > <bean id ="transactionManager" class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property name ="dataSource" ref ="dataSource" /> </bean > </beans >
1 2 3 4 5 6 7 8 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" > <import resource ="classpath:spring-dao.xml" /> <import resource ="classpath:spring-service.xml" /> <import resource ="classpath:spring-mvc.xml" /> </beans >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?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:mvc ="http://www.springframework.org/schema/mvc" xmlns:context ="http://www.springframework.org/schema/context" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" > <mvc:annotation-driven /> <mvc:default-servlet-handler /> <context:component-scan base-package ="com.ling.controller" /> <bean class ="org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name ="prefix" value ="/WEB-INF/jsp/" /> <property name ="suffix" value =".jsp" /> </bean > <context:component-scan base-package ="com.ling.controller" /> </beans >
10.编写web.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <?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:applicationcontext.xml</param-value > </init-param > </servlet > <servlet-mapping > <servlet-name > springmvc</servlet-name > <url-pattern > /</url-pattern > </servlet-mapping > <filter > <filter-name > encodingFilter</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 > encodingFilter</filter-name > <url-pattern > /*</url-pattern > </filter-mapping > <session-config > <session-timeout > 15</session-timeout > </session-config > </web-app >
11.编写Controller类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 @Controller @RequestMapping("/book") public class BookController { @Autowired @Qualifier("BookServiceImpl") private BookService bookService; @RequestMapping("/allBook") public String list (Model model) { List<Books>list = bookService.queryAllBook(); model.addAttribute("list" ,list); return "allBook" ; } @RequestMapping("/toAddBook") public String toAddPaper () { return "addBook" ; } @RequestMapping("/addBook") public String addPaper (Books books) { System.out.println(books); bookService.addBook(books); return "redirect:/book/allBook" ; } @RequestMapping("/toUpdateBook") public String toUpdateBook (Model model, int id) { Books books = bookService.queryBookByID(id); System.out.println(books); model.addAttribute("book" ,books ); return "updateBook" ; } @RequestMapping("/updateBook") public String updateBook (Model model, Books book) { System.out.println(book); bookService.updateBook(book); return "redirect:/book/allBook" ; } @RequestMapping("/del/{bookId}") public String deleteBook (@PathVariable("bookId") int id) { bookService.deleteBook(id); return "redirect:/book/allBook" ; } @RequestMapping("/queryBook") public String queryBook (String queryBookName,Model model) { List<Books> list = bookService.queryBookByName(queryBookName); if (list.isEmpty()){ model.addAttribute("error" ,"不存在该书籍" ); } model.addAttribute("list" ,list); return "allBook" ; } }
12.编写前端JSP页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>书籍展示页面</title> <style> a{ text-decoration: none; color: black; font-size: 18px; } h3{ width:180px; height: 38px; margin: 100px auto; text-align: center; line-height: 38px; background: deepskyblue; border-radius: 5px; } </style> </head> <body> <h3> <a href="${pageContext.request.contextPath}/book/allBook" >进入书籍首页</a> </h3> </body> </html>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>新增书籍</title> <meta name="viewport" content="width=device-width, initial-scale=1.0" > <!-- 引入 Bootstrap --> <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" > </head> <body> <div class ="container" > <div class ="row clearfix" > <div class ="col-md-12 column" > <div class ="page-header" > <h1> <small>新增书籍</small> </h1> </div> </div> </div> <form action="${pageContext.request.contextPath}/book/addBook" method="post" > 书籍名称:<input type="text" name="bookName" ><br><br><br> 书籍数量:<input type="text" name="bookCounts" ><br><br><br> 书籍详情:<input type="text" name="detail" ><br><br><br> <input type="submit" value="添加" > </form> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>书籍列表</title> <meta name="viewport" content="width=device-width, initial-scale=1.0" > <!-- 引入 Bootstrap --> <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" > </head> <body> <div class ="container" > <div class ="row clearfix" > <div class ="col-md-12 column" > <div class ="page-header" > <h1> <small>书籍列表 —— 显示所有书籍</small> </h1> </div> </div> </div> <div class ="row" > <div class ="col-md-4 column" > <a class ="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook" >新增</a> </div> <div class ="form-inline" > <%-- 查询书籍--%> <form action="${pageContext.request.contextPath}/book/queryBook" method="post" style="float: right" > <span style="color: red;font-weight: bold" >${error}</span> <input type="text" name="queryBookName" class ="form-control" placeholder="输入需要查询的书籍" > <input type="submit" value="查询" class ="btn btn-primary" > </form> </div> </div> <div class ="row clearfix" > <div class ="col-md-12 column" > <table class ="table table-hover table-striped" > <thead> <tr> <th>书籍编号</th> <th>书籍名字</th> <th>书籍数量</th> <th>书籍详情</th> <th>操作</th> </tr> </thead> <tbody> <c:forEach var ="book" items="${requestScope.get('list')}" > <tr> <td>${book.getBookID()}</td> <td>${book.getBookName()}</td> <td>${book.getBookCounts()}</td> <td>${book.getDetail()}</td> <td> <!--从原有查询页面获得ID传给toUpdateBook对应方法--> <a href="${pageContext.request.contextPath}/book/toUpdateBook?id=${book.getBookID()}" >更改</a> | <a href="${pageContext.request.contextPath}/book/del/${book.getBookID()}" >删除</a> </td> </tr> </c:forEach> </tbody> </table> </div> </div> </div>
WEB-INF/jsp/updateBook.jsp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>修改信息</title> <meta name="viewport" content="width=device-width, initial-scale=1.0" > <!-- 引入 Bootstrap --> <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" > </head> <body> <div class ="container" > <div class ="row clearfix" > <div class ="col-md-12 column" > <div class ="page-header" > <h1> <small>修改信息</small> </h1> </div> </div> </div> <!--通过toUpdateBook获取原来数据,同时上传更新数据给updateBook--> <form action="${pageContext.request.contextPath}/book/updateBook" method="post" > <!--前端传递隐藏域--> <input type="hidden" name="bookID" value="${book.getBookID()}" /> 书籍名称:<input type="text" name="bookName" value="${book.getBookName()}" /> 书籍数量:<input type="text" name="bookCounts" value="${book.getBookCounts()}" /> 书籍详情:<input type="text" name="detail" value="${book.getDetail() }" /> <input type="submit" value="提交" /> </form> </div>
Ajax
1.AJAX(Asynchronous JavaScript and XML,异步的JavaScript与XML技术),指的是一套综合了多项技术的浏览器端网页开发技术。Ajax的概念由Jesse James Garrett所提出。
2.传统的Web应用允许用户端填写表单(form),当提交表单时就向网页服务器发送一个请求。服务器接收并处理传来的表单,然后送回一个新的网页,但这个做法浪费了许多带宽,因为在前后两个页面中的大部分HTML码往往是相同的。由于每次应用的沟通都需要向服务器发送请求,应用的回应时间依赖于服务器的回应时间。这导致了用户界面的回应比本机应用慢得多。
与此不同,AJAX应用可以仅向服务器发送并取回必须的数据,并在客户端采用JavaScript处理来自服务器的回应(更新部分网页)。因为在服务器和浏览器之间交换的数据大量减少,服务器回应更快了。同时,很多的处理工作可以在发出请求的客户端机器上完成,因此Web服务器的负荷也减少了(Google Suggest应用搜索单词)。
3.类似于DHTML或LAMP,AJAX不是指一种单一的技术,而是有机地利用了一系列相关的技术。虽然其名称包含XML,但实际上数据格式可以由JSON代替以进一步减少数据量。而客户端与服务器也并不需要异步。一些基于AJAX的"派生/合成"式(derivative/composite)的技术也正在出现,如AFLAX。
1.使用jQuery(JavaScript库)中提供的AJAX方法,本质就是对JS原生XMLHttpRequest(XHR)进行封装,通过这些方法能够使用 HTTP Get 和 HTTP Post 从远程服务器上请求文本、HTML、XML 或 JSON - 同时能够把这些外部数据直接载入网页的被选元素中。
jQuery库 拥有完整的 Ajax 兼容套件。其中的函数和方法允许我们在不刷新浏览器的情况下从服务器加载数据。
函数
描述
jQuery.ajax()
执行异步 HTTP (Ajax) 请求。
jQuery.ajaxSetup()
设置将来的 Ajax 请求的默认值。
jQuery.get()
使用 HTTP GET 请求从服务器加载数据。
jQuery.post()
使用 HTTP POST 请求从服务器加载数据。
jQuery.getScript()
使用 HTTP GET 请求从服务器加载 JavaScript 文件,然后执行该文件。
jQuery.param()
创建数组或对象的序列化表示,适合在 URL 查询字符串或 Ajax 请求中使用。
jQuery ajax - ajax()方法
参数
描述
settings
可选。用于配置 Ajax 请求的键值对集合。可以通过 $.ajaxSetup() 设置任何选项的默认值。
options
类型:Object可选。AJAX 请求设置。所有选项都是可选的。
async
类型:Boolean默认值: true。默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行。
beforeSend(XHR)
类型:Function 发送请求前可修改 XMLHttpRequest 对象的函数,如添加自定义 HTTP 头。
cache
类型:Boolean 默认值: true,dataType 为 script 和 jsonp 时默认为 false。设置为 false 将不缓存此页面。jQuery 1.2 新功能。
complete(XHR, TS)
类型:Function 请求完成后回调函数 (请求成功或失败之后均调用)。参数: XMLHttpRequest 对象和一个描述请求类型的字符串。这是一个 Ajax 事件。
contentType
类型:String 默认值: “application/x-www-form-urlencoded”。
context
类型:Object 这个对象用于设置 Ajax 相关回调函数的上下文。
data
类型:String 发送到服务器的数据。将自动转换为请求字符串格式。
dataFilter
类型:Function 给 Ajax 返回的原始数据的进行预处理的函数。提供 data 和 type 两个参数:data 是 Ajax 返回的原始数据,type 是调用 jQuery.ajax 时提供的 dataType 参数。函数返回的值将由 jQuery 进一步处理。
dataType
类型:String 预期服务器返回的数据类型。如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断,比如 XML MIME 类型就被识别为 XML。在 1.4 中,JSON 就会生成一个 JavaScript 对象,而 script 则会执行这个脚本。随后服务器端返回的数据会根据这个值解析后,传递给回调函数。
可用值:
“xml”: 返回 XML 文档,可用 jQuery 处理。
“html”: 返回纯文本 HTML 信息;包含的 script 标签会在插入 dom 时执行。
“script”: 返回纯文本 JavaScript 代码。
“json”: 返回 JSON 数据。
“jsonp”: JSONP 格式。
“text”: 返回纯文本字符串。
error
类型:Function 默认值: 自动判断 (xml 或 html)。
global
类型:Boolean 是否触发全局 AJAX 事件。默认值: true。设置为 false 将不会触发全局 AJAX 事件,如 ajaxStart 或 ajaxStop 可用于控制不同的 Ajax 事件。
ifModified
类型:Boolean 仅在服务器数据改变时获取新数据。默认值: false。
jsonp
类型:String 在一个 jsonp 请求中重写回调函数的名字。
jsonpCallback
类型:String 为 jsonp 请求指定一个回调函数名。
password
类型:String 用于响应 HTTP 访问认证请求的密码
processData
类型:Boolean 默认值: true。默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串),都会处理转化成一个查询字符串,以配合默认内容类型 “application/x-www-form-urlencoded”。
scriptCharset
类型:String 只有当请求时 dataType 为 “jsonp” 或 “script”,并且 type 是 “GET” 才会用于强制修改 charset。通常只在本地和远程的内容编码不同时使用。
success
类型:Function请求成功后的回调函数。参数:由服务器返回,并根据 dataType 参数进行处理后的数据;描述状态的字符串。这是一个 Ajax 事件。
traditional
类型:Boolean 如果你想要用传统的方式来序列化数据,那么就设置为 true。请参考工具分类下面的 jQuery.param 方法。
timeout
类型:Number 设置请求超时时间(毫秒)。此设置将覆盖全局设置。
type
类型:String。请求方式 (“POST” 或 “GET”), 默认为 “GET”。
url
类型:String 默认值: 当前页地址。发送请求的地址。
username
类型:String 用于响应 HTTP 访问认证请求的用户名。
xhr
类型:Function 需要返回一个 XMLHttpRequest 对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> <%-- CDN <script src="https://code.jquery.com/jquery-3.1.1.min.js" ></script> --%> <script src="${pageContext.request.contextPath}/statics/js/jquery-3.6.0.min.js" ></script> <script> function a1 () { $.post({ url:"${pageContext.request.contextPath}/a1" , data:{'name' :$("#txtName" ).val()}, success:function (data,status) { alert(data); alert(status); } }); } </script> </head> <body> <%--失去焦点触发事件 发起一个请求--%> 用户名:<input type="text" id="txtName" onblur="a1()" /> </body> </html>
1 2 3 4 5 6 7 8 9 10 11 12 @Controller public class AjaxController { @RequestMapping("/a1") public void ajax1 (String name , HttpServletResponse response) throws IOException { if ("admin" .equals(name)){ response.getWriter().print("true" ); }else { response.getWriter().print("false" ); } } }
$ is not defined:statis/js/jquery.js(与WEB-INF同级)文件未导出
1.在SpringMVC配置文件加入:
1 <mvc:default-servlet-handler />
2.删除out文件夹,在pom.xml加入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <build > <resources > <resource > <directory > src/main/java</directory > <includes > <include > **/*.properties</include > <include > **/*.xml</include > </includes > <filtering > false</filtering > </resource > <resource > <directory > src/main/resources</directory > <includes > <include > **/*.properties</include > <include > **/*.xml</include > </includes > <filtering > false</filtering > </resource > </resources > </build >
AJAX数据回显
1.编写实体类
1 2 3 4 5 6 7 8 9 @Data @AllArgsConstructor @NoArgsConstructor public class User { private String name; private int age; private String sex; }
2.编写Controller类
1 2 3 4 5 6 7 8 9 10 11 @RestController public class AjaxController { @RequestMapping("/a2") public List<User> ajax2 () { List<User> list = new ArrayList<User>(); list.add(new User("Mike" ,13 ,"male" )); list.add(new User("Joe" ,12 ,"male" )); list.add(new User("Kevin" ,23 ,"male" )); return list; } }
3.编写前端JSP页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <input type="button" id="btn" value="获取数据" /> <table width="80%" align="center" > <tr> <td>姓名</td> <td>年龄</td> <td>性别</td> </tr> <tbody id="content" > </tbody> </table> <script src="${pageContext.request.contextPath}/statics/js/jquery-3.6.0.min.js" ></script> <script> $(function () { $("#btn" ).click(function () { $.post("${pageContext.request.contextPath}/a2" ,function (data) { console.log(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> </body> </html>
AJAX密码验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @RestController public class AjaxController { @RequestMapping("/a3") public String ajax3 (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; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>ajax</title> <script src="${pageContext.request.contextPath}/statics/js/jquery-3.6.0.min.js" ></script> <script> function a1 () { $.post({ url:"${pageContext.request.contextPath}/a3" , data:{'name' :$("#name" ).val()}, success:function (data) { if (data.toString()=='OK' ){ $("#userInfo" ).css("color" ,"green" ); }else { $("#userInfo" ).css("color" ,"red" ); } $("#userInfo" ).html(data); } }); } function a2 () { $.post({ url:"${pageContext.request.contextPath}/a3" , data:{'pwd' :$("#pwd" ).val()}, success:function (data) { if (data.toString()=='OK' ){ $("#pwdInfo" ).css("color" ,"green" ); }else { $("#pwdInfo" ).css("color" ,"red" ); } $("#pwdInfo" ).html(data); } }); } </script> </head> <body> <p> 用户名:<input type="text" id="name" onblur="a1()" /> <span id="userInfo" ></span> </p> <p> 密码:<input type="text" id="pwd" onblur="a2()" /> <span id="pwdInfo" ></span> </p> </body> </html>
乱码问题参考JSON解决方案
获取Baidu接口Demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" > <title>JSONP百度搜索</title> <style> #q{ width: 500px; height: 30px; border:1px solid #ddd; line-height: 30px; display: block; margin: 0 auto; padding: 0 10px; font-size: 14px; } #ul{ width: 520px; list-style: none; margin: 0 auto; padding: 0 ; border:1px solid #ddd; margin-top: -1px; display: none; } #ul li{ line-height: 30px; padding: 0 10px; } #ul li:hover{ background-color: #f60; color: #fff; } </style> <script> <!--定义demo函数 (分析接口、数据)--> function demo (data) { var Ul = document.getElementById('ul' ); var html = '' ; <!--如果搜索数据存在添加内容--> if (data.s.length) { <!--隐藏掉的ul显示出来--> Ul.style.display = 'block' ; <!--搜索到的数据循环追加到li--> for (var i = 0 ;i<data.s.length;i++){ html += '<li>' +data.s[i]+'</li>' ; } <!--循环的li写入ul--> Ul.innerHTML = html; } } window.onload = function(){ <!--获取输入框和ul--> var Q = document.getElementById('q' ); var Ul = document.getElementById('ul' ); <!--事件鼠标抬起时候--> Q.onkeyup = function(){ <!--如果输入框不为空--> if (this .value != '' ) { <!--创建标签--> var script = document.createElement('script' ); <!--给定要跨域的地址 赋值给src--> <!--请求的跨域的地址--> script.src = 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=' +this .value+'&cb=demo' ; <!--将组合好的带src的script标签追加到body里--> document.body.appendChild(script); } } } </script> </head> <body> <input type="text" id="q" /> <ul id="ul" > </ul> </body> </html>
拦截器
SpringMVC的拦截器(AOP)类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
过滤器
servlet规范
在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截
拦截器
拦截器属于SpringMVC框架
拦截器拦截访问控制器方法,对于jsp/html/css/image/js不进行拦截
自定义拦截器
自定义拦截器必须实现HandlerInterceptor 接口
1.编写拦截器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class MyInterceptor implements HandlerInterceptor { public boolean preHandle (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { System.out.println("------------处理前------------" ); return true ; } public void postHandle (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { System.out.println("------------处理后------------" ); } public void afterCompletion (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { System.out.println("------------清理------------" ); } }
2.在SpringMVC配置文件中配置拦截器
1 2 3 4 5 6 7 8 9 10 <mvc:interceptors > <mvc:interceptor > <mvc:mapping path ="/**" /> <bean class ="com.ling.controller.MyInterceptor" /> </mvc:interceptor > </mvc:interceptors >
3.编写测试Controller类
1 2 3 4 5 6 7 8 9 10 @Controller public class InterceptorController { @RequestMapping("/interceptor") @ResponseBody public String testFunction () { System.out.println("执行控制器中的方法" ); return "hello" ; } }
4.编写前端页面
1 <a href="${pageContext.request.contextPath}/interceptor" >拦截器测试</a>
登录拦截 1.前端页面
1 2 3 4 5 6 7 8 9 10 11 12 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> <hr> <%--登录--%> <a href="${pageContext.request.contextPath}/user/gologin" >登录</a> <a href="${pageContext.request.contextPath}/user/main" >首页</a> </body> </html>
1 2 3 4 5 6 7 8 9 10 11 12 13 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>首页</h1> <span>${username}</span> <p> <a href="${pageContext.request.contextPath}/user/goOut" >注销</a> </p> </body> </html>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <h1>登录页面</h1> <hr> <!-- WEB-INF下所有的资源只能通过controller或者servlet访问--> <body> <form action="${pageContext.request.contextPath}/user/login" > 用户名:<input type="text" name="username" > <br> 密码:<input type="password" name="password" > <br> <input type="submit" value="提交" > </form> </body> </html>
2.编写Controller类以及Interceptor拦截类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @Controller @RequestMapping("/user") public class LoginController { @RequestMapping("/main") public String main () { return "main" ; } @RequestMapping("/gologin") public String login () { return "login" ; } @RequestMapping("/login") public String login (HttpSession session, String username, String password, Model model) { session.setAttribute("userLoginInfo" ,username); model.addAttribute("username" ,username); return "main" ; } @RequestMapping("/goOut") public String loginout (HttpSession session) { session.removeAttribute("userLoginInfo" ); return "redirect:/" ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(); if (request.getRequestURI().contains("login" )){ return true ; } if (session.getAttribute("userLoginInfo" )!=null ){ return true ; } request.getRequestDispatcher("/WEB-INF/jsp/login.jsp" ).forward(request,response); return false ; } }
3.在SpringMVC配置文件中注册拦截器
1 2 3 4 5 6 <mvc:interceptors > <mvc:interceptor > <mvc:mapping path ="/user/**" /> <bean class ="com.ling.config.LoginInterceptor" /> </mvc:interceptor > </mvc:interceptors >
文件上传和下载
1.为了能上传文件,需要将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器;
表单中的 enctype 属性:
application/x-www=form-urlencoded:默认方式,只处理表单域中的 value 属性值,采用这种编码方式的表单会将表单域中的值处理成 URL 编码方式。
multipart/form-data:以二进制流的方式来处理表单数据,会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。
text/plain:除了把空格转换为 "+" 号外,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件
2.一旦设置了enctype为multipart/form-data,浏览器即会采用二进制流的方式来处理表单数据,而对于文件上传的处理则涉及在服务器端解析原始的HTTP响应。在2003年,Apache Software Foundation发布了开源的Commons FileUpload组件,其很快成为Servlet/JSP程序员上传文件的最佳选择。
Servlet3.0规范已经提供方法来处理文件上传,但这种上传需要在Servlet中完成。
Spring MVC为文件上传提供了直接的支持,这种支持是用即插即用的MultipartResolver实现的。
Spring MVC使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。因此,SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件。
String getOriginalFilename():获取上传文件名
InputStream getInputStream():获取文件流
void transferTo(File dest):将上传文件保存到一个目录文件
1.添加依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 <dependency > <groupId > commons-fileupload</groupId > <artifactId > commons-fileupload</artifactId > <version > 1.4</version > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > javax.servlet-api</artifactId > <version > 4.0.1</version > <scope > provided</scope > </dependency >
2.配置multipartResolver
1 2 3 4 5 6 7 8 <bean id ="multipartResolver" class ="org.springframework.web.multipart.commons.CommonsMultipartResolver" > <property name ="defaultEncoding" value ="utf-8" /> <property name ="maxUploadSize" value ="10485760" /> <property name ="maxInMemorySize" value ="40960" /> </bean >
3.编写前端页面
1 2 3 4 <form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post" > <input type="file" name="file" /> <input type="submit" value="upload" > </form>
1 <a href="${pageContext.request.contextPath}/download" >点击下载</a>
4.编写Controller类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 @Controller public class FileController { @RequestMapping("/upload") public String fileUpload (@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException { 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" ; } @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); file.transferTo(new File(realPath +"/" + file.getOriginalFilename())); return "redirect:/index.jsp" ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @Controller public class FileController { @RequestMapping(value="/download") public String downloads (HttpServletResponse response , HttpServletRequest request) throws Exception { String path = request.getServletContext().getRealPath("/upload" ); String fileName = "1.jpg" ; response.reset(); 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); InputStream input=new FileInputStream(file); OutputStream out = response.getOutputStream(); byte [] buff =new byte [1024 ]; int index=0 ; while ((index= input.read(buff))!= -1 ){ out.write(buff, 0 , index); out.flush(); } out.close(); input.close(); return null ; } }