网站建设的流程分析,wordpress怎么把设置菜单去除,怎么制作一个平台,网站后台素材文章目录 项目源码地址回顾-MVC什么是MVC#xff1f;MVC各部分组成 回顾-ServletMaven创建Web项目1、创建Maven父工程pom#xff0c;并导入依赖2、用Maven新建一个Web Module3、代码#xff1a;HelloServlet.java3、代码-hello.jsp3、代码-web.xml4、配置Tomcat5、浏览器测试… 文章目录 项目源码地址回顾-MVC什么是MVCMVC各部分组成 回顾-ServletMaven创建Web项目1、创建Maven父工程pom并导入依赖2、用Maven新建一个Web Module3、代码HelloServlet.java3、代码-hello.jsp3、代码-web.xml4、配置Tomcat5、浏览器测试 Maven创建jar项目并手动添加web依赖 初识SpringMVCSpringMVC的基础知识DispatcherServlet中心控制器SpringMVC执行原理 第一个SpringMVC程序xml配置实现1、在上述父工程下创建一个Web Module2、配置web.xml注册DispatchServlet3、编写Spring MVC的配置文件【不同】4、编写操作业务Controller【不同】5、编写要跳转的jsp页面6、启动测试 annotation注解实现1、在上述父工程下创建一个Web Module2、配置web.xml注册DispatchServlet3、编写Spring MVC的配置文件【不同】4、编写操作业务Controller【不同】5、编写要跳转的jsp页面6、启动测试 控制器Controller控制器的作用控制器实现项目Module名称实现--接口定义实现--注解实现总结 注解RequestMapping作用示例 RestFul风格什么是RestFulRestFul资源和资源操作资源操作方法对比 示例代码应用PathVariable应用method属性应用GetMapping、...... 数据处理及跳转项目Module名称结果跳转ModelAndViewServletAPISpringMVC-无需视图解析器SpringMVC-有视图解析器 数据处理-提交到后端的数据数据处理-数据显示到前端乱码处理方法1-springMVC-过滤器方法2-Tomcat修改配置文件方法3-自定义过滤器总结 Json项目Module名称什么是Json概念语法格式Json和JavaScript的区别Json和JavaScript的相互转换 Controller返回Json数据jacksonModule准备Controller核心代码统一处理乱码问题 Controller返回Json数据fastjsonModule准备fastjson三大核心类数据类型相互转换 Ajax拦截器Interceptor什么是拦截器概念过滤器和拦截器的区别 拦截器使用 文件上传和下载Module准备核心代码展示前端页面Controller 项目源码地址
GitHubhttps://github.com/Web-Learn-GSF/Java_Learn_Examples父工程Java_Framework_SpringMVC
回顾-MVC
什么是MVC
MVC是Model、View、Controller的缩写一种软件设计规范将业务逻辑、数据、显示三者分离开来组织代码
MVC主要作用是降低了视图与业务逻辑间的双向耦合
MVC各部分组成
模块组成Model模型提供要展示的数据可以认为是领域模型或JavaBean组件包含数据和行为View视图负责进行模型的展示一般就是我们见到的用户界面客户想看到的东西Controller控制器接收用户请求委托给模型进行处理状态改变处理完毕后把返回的模型数据返回给视图由视图负责展示。也就是说控制器做了个调度员的工作
回顾-Servlet
这一章将讲述两种创建Web项目的方法来回顾servlet Maven创建web项目运行servlet Maven创建jar项目手动添加框架依赖运行servlet**还没调试通顺后续有空继续整**
同时也将讲述Tomcat9和Tomcat10在servlet包依赖上的不同
Maven创建Web项目
1、创建Maven父工程pom并导入依赖
若Tomcat版本为10依赖导入
dependencies!-- 没有争议的依赖 --dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.13.1/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion6.0.9/version/dependency!-- 有版本争议的依赖servlet、jsp--!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-servlet-api --dependencygroupIdorg.apache.tomcat/groupIdartifactIdtomcat-servlet-api/artifactIdversion10.0.4/version/dependency!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-jsp-api --dependencygroupIdorg.apache.tomcat/groupIdartifactIdtomcat-jsp-api/artifactIdversion10.0.4/version/dependency/dependencies若Tomcat版本为9依赖导入
dependencies!-- 没有争议的依赖 --dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.13.1/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion6.0.9/version/dependency!-- 有版本争议的依赖servlet、jsp--dependencygroupIdjavax.servlet/groupIdartifactIdservlet-api/artifactIdversion2.5/version/dependencydependencygroupIdjavax.servlet.jsp/groupIdartifactIdjsp-api/artifactIdversion2.2/version/dependencydependencygroupIdjavax.servlet/groupIdartifactIdjstl/artifactIdversion1.2/version/dependency
/dependenciesTomcat9及以前servlet依赖包名是 javax.servletTomcat10之后servlet依赖包名是 jakarta.servlet
如若不注意版本匹配启动Tomcat会爆出404问题
2、用Maven新建一个Web Module
Module名字Demo-01-ServletReview-MavenWebCreate
Module内容解释
pom文件里面的packaging标签是war
整体结构及后续代码
Maven创建的web项目webapp在main目录下跟手动添加web依赖所在的目录不一样 3、代码HelloServlet.java
Tomcat版本为10的代码
package GSF.Example.Servlet;import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;public class HelloServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//取得参数String method req.getParameter(method);if (add.equals(method)){req.getSession().setAttribute(msg,执行了add方法);}if (delete.equals(method)){req.getSession().setAttribute(msg,执行了delete方法);}//业务逻辑暂无//视图跳转req.getRequestDispatcher(/WEB-INF/jsp/hello.jsp).forward(req,resp);}Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}Tomcat版本为9的代码
package GSF.Example.Servlet;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class HelloServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//取得参数String method req.getParameter(method);if (add.equals(method)){req.getSession().setAttribute(msg,执行了add方法);}if (delete.equals(method)){req.getSession().setAttribute(msg,执行了delete方法);}//业务逻辑暂无//视图跳转req.getRequestDispatcher(/WEB-INF/jsp/hello.jsp).forward(req,resp);}Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}区别包的名字
Tomcat10jakarta.servletTomcat9javax.servlet
3、代码-hello.jsp
% page contentTypetext/html;charsetUTF-8 languagejava %
% page isELIgnoredfalse %
html
headtitleKuangshen/title
/head
body
${msg}
/body
/htmlweb2.4之后默认禁止el表达式即${}不会从session域中获取数据通过添加上边的第二行代码% page isELIgnoredfalse %可以关闭对el表达式的禁止实现从session域中获取数据
3、代码-web.xml
Maven创建web项目默认的web.xml文件内容
头文件不太对劲但是能用有空再探讨具体有啥区别
!DOCTYPE web-app PUBLIC-//Sun Microsystems, Inc.//DTD Web Application 2.3//ENhttp://java.sun.com/dtd/web-app_2_3.dtd web-appdisplay-nameArchetype Created Web Application/display-nameservletservlet-nameHelloServlet/servlet-nameservlet-classGSF.Example.Servlet.HelloServlet/servlet-class/servletservlet-mappingservlet-nameHelloServlet/servlet-nameurl-pattern/user/url-pattern/servlet-mapping/web-app若是手动添加框架依赖创建的web.xml
?xml version1.0 encodingUTF-8?
web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaeexmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsdversion4.0servletservlet-nameHelloServlet/servlet-nameservlet-classGSF.Example.Servlet.HelloServlet/servlet-class/servletservlet-mappingservlet-nameHelloServlet/servlet-nameurl-pattern/user/url-pattern/servlet-mapping/web-app4、配置Tomcat 暂不清楚为啥要选这个也不知道选不带有war exploded的会有啥问题 5、浏览器测试
localhost:8080/user?methodaddlocalhost:8080/user?methoddelete
Maven创建jar项目并手动添加web依赖
暂时没调试通顺
初识SpringMVC
SpringMVC的基础知识
Spring MVC是Spring Framework的一部分是基于Java实现MVC的轻量级Web框架
官方文档https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/web.html#spring-web
Spring MVC特点
轻量级简单易学高效 , 基于请求响应的MVC框架与Spring兼容性好无缝结合约定优于配置功能强大RESTful、数据验证、格式化、本地化、主题等简洁灵活
Spring的web框架围绕DispatcherServlet [ 调度Servlet ] 设计。
DispatcherServlet的作用是将请求分发到不同的处理器。从Spring 2.5开始使用Java 5或者以上版本的用户可以采用基于注解形式进行开发十分简洁。
DispatcherServlet中心控制器
Spring的web框架围绕DispatcherServlet设计
DispatcherServlet的作用是将请求分发到不同的处理器从Spring 2.5开始使用Java 5或者以上版本的用户可以采用基于注解的controller声明方式
Spring MVC框架像许多其他MVC框架一样, 以请求为驱动 , 围绕一个中心Servlet分派请求及提供其他功能DispatcherServlet是一个实际的Servlet (它继承自HttpServlet 基类)
SpringMVC执行原理 实现部分表示框架已经帮忙完成虚线部分表示需要我们手动编写的地方
步骤1
DispatcherServlet表示前置控制器是整个SpringMVC的控制中心。用户发出请求DispatcherServlet接收请求并拦截请求假设请求的url为 : localhost:8080/SpringMVC/helloweb.xml中定义拦截所有请求 servletservlet-namespringmvc/servlet-nameservlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-class!--关联一个springmvc的配置文件:【servlet-name】-servlet.xml--init-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:springmvc-servlet.xml/param-value/init-param!--启动级别-1--load-on-startup1/load-on-startup/servlet!--/ 匹配所有的请求不包括.jsp--!--/* 匹配所有的请求包括.jsp--servlet-mappingservlet-namespringmvc/servlet-nameurl-pattern//url-pattern/servlet-mapping步骤2
HandlerMapping为处理器映射被DispatcherServlet调用HandlerMapping根据请求url查找Handlerspringmvc-servlet.xml中注册HandlerMapping的bean
bean classorg.springframework.web.servlet.handler.BeanNameUrlHandlerMapping/步骤3
HandlerExecution表示具体的Handler其主要作用是根据url查找控制器如上url被查找控制器为hello
步骤4
HandlerExecution将解析后的信息传递给DispatcherServlet解析后的信息处理器对象及处理器拦截器
步骤5
HandlerAdapter表示处理器适配器其按照特定的规则去执行Handlerspringmvc-servlet.xml中注册HandlerAdapter的bean
bean classorg.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter/步骤6
Handler让具体的Controller执行springmvc-servlet.xml中注册Handler的bean
bean id/hello classGSF.Example.Controller.HelloController/步骤7
Controller将具体的执行信息返回给HandlerAdapter返回的信息如ModelAndView
步骤8
HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet
步骤9
DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名springmvc-servlet.xml中注册bean并完成相关配置
bean classorg.springframework.web.servlet.view.InternalResourceViewResolver idInternalResourceViewResolver!--前缀--property nameprefix value/WEB-INF/jsp//!--后缀--property namesuffix value.jsp/
/bean步骤10
视图解析器将解析的逻辑视图名传给DispatcherServlet
步骤11
DispatcherServlet根据视图解析器解析的视图结果调用具体的视图
步骤12
最终视图呈现给用户
第一个SpringMVC程序
xml配置实现
1、在上述父工程下创建一个Web Module
Module名字Demo-02-SpringMVC-xml
整体结构图及后续写入代码 2、配置web.xml注册DispatchServlet
web.xml
!DOCTYPE web-app PUBLIC-//Sun Microsystems, Inc.//DTD Web Application 2.3//ENhttp://java.sun.com/dtd/web-app_2_3.dtd web-appdisplay-nameArchetype Created Web Application/display-name!--1.注册DispatcherServlet--servletservlet-namespringmvc/servlet-nameservlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-class!--关联一个springmvc的配置文件:【servlet-name】-servlet.xml--init-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:springmvc-servlet.xml/param-value/init-param!--启动级别-1--load-on-startup1/load-on-startup/servlet!--/ 匹配所有的请求不包括.jsp--!--/* 匹配所有的请求包括.jsp--servlet-mappingservlet-namespringmvc/servlet-nameurl-pattern//url-pattern/servlet-mapping
/web-app3、编写Spring MVC的配置文件【不同】
springmvc-servlet.xml
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdbean classorg.springframework.web.servlet.handler.BeanNameUrlHandlerMapping/bean classorg.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter/!--视图解析器:DispatcherServlet给他的ModelAndView--bean classorg.springframework.web.servlet.view.InternalResourceViewResolver idInternalResourceViewResolver!--前缀--property nameprefix value/WEB-INF/jsp//!--后缀--property namesuffix value.jsp//bean!--Handler--bean id/hello classGSF.Example.Controller.HelloController//beans4、编写操作业务Controller【不同】
HelloController.java
package GSF.Example.Controller;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;//注意这里我们先导入Controller接口
public class HelloController implements Controller {public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {//ModelAndView 模型和视图ModelAndView mv new ModelAndView();//封装对象放在ModelAndView中。Modelmv.addObject(msg,HelloSpringMVC!);//封装要跳转的视图放在ModelAndView中mv.setViewName(hello); //: /WEB-INF/jsp/hello.jspreturn mv;}
}在springmvc-servlet.xml中注册该实现类的bean
5、编写要跳转的jsp页面
hello.jsp
% page contentTypetext/html;charsetUTF-8 languagejava %
% page isELIgnoredfalse %
html
headtitleKuangshen/title
/head
body
${msg}
/body
/html6、启动测试
localhost:8080/hello
annotation注解实现
1、在上述父工程下创建一个Web Module
Module名称Demo-02-SpringMVC-annotation
整体结构图及后续写入代码 2、配置web.xml注册DispatchServlet
web.xml
?xml version1.0 encodingUTF-8?
web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaeexmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsdversion4.0!--1.注册servlet--servletservlet-nameSpringMVC/servlet-nameservlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-class!--通过初始化参数指定SpringMVC配置文件的位置进行关联--init-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:springmvc-servlet.xml/param-value/init-param!-- 启动顺序数字越小启动越早 --load-on-startup1/load-on-startup/servlet!--所有请求都会被springmvc拦截 --servlet-mappingservlet-nameSpringMVC/servlet-nameurl-pattern//url-pattern/servlet-mapping/web-app3、编写Spring MVC的配置文件【不同】
springmvc-servlet.xml
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxmlns:mvchttp://www.springframework.org/schema/mvcxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttps://www.springframework.org/schema/mvc/spring-mvc.xsd!-- 自动扫描包让指定包下的注解生效,由IOC容器统一管理 --context:component-scan base-packageGSF.Example.Controller/!-- 让Spring MVC不处理静态资源 --mvc:default-servlet-handler /!--支持mvc注解驱动在spring中一般采用RequestMapping注解来完成映射关系要想使RequestMapping注解生效必须向上下文中注册DefaultAnnotationHandlerMapping和一个AnnotationMethodHandlerAdapter实例这两个实例分别在类级别和方法级别处理。而annotation-driven配置帮助我们自动完成上述两个实例的注入。--mvc:annotation-driven /!-- 视图解析器 --bean classorg.springframework.web.servlet.view.InternalResourceViewResolveridinternalResourceViewResolver!-- 前缀 --property nameprefix value/WEB-INF/jsp/ /!-- 后缀 --property namesuffix value.jsp //bean/beans4、编写操作业务Controller【不同】
package GSF.Example.Controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;Controller
RequestMapping(/HelloController)
public class HelloController {//真实访问地址 : 项目名/HelloController/helloRequestMapping(/hello)public String sayHello(Model model){//向模型中添加属性msg与值可以在JSP页面中取出并渲染model.addAttribute(msg,hello, SpringMVC);//web-inf/jsp/hello.jspreturn hello;}
}通过注解扫描实现自动注入bean
5、编写要跳转的jsp页面
% page contentTypetext/html;charsetUTF-8 languagejava %
% page isELIgnoredfalse %
html
headtitle你好/title
/head
body
${msg}
/body
/html6、启动测试
localhost:8080/HelloController/hello
控制器Controller
控制器的作用
控制器复杂提供访问应用程序的行为通常通过接口定义或注解定义两种方法实现。
控制器负责解析用户的请求并将其转换为一个模型。
在Spring MVC中一个控制器类可以包含多个方法
在Spring MVC中对于Controller的配置方式有很多种
控制器实现
项目Module名称
Demo-03-SpringMVC-Controller_Restful
实现–接口定义
package GSF.Example.Controller;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.ui.Model;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;public class HelloController_Interface implements Controller {Overridepublic ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {ModelAndView mv new ModelAndView();mv.addObject(msg, hello, SpringMVC, Controller_Interface);mv.setViewName(hello);return mv;}
}实现–注解实现
package GSF.Example.Controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;Controller
RequestMapping(/controller)
public class HelloController_Annotation {//真实访问地址 : 项目名/controller/helloRequestMapping(/annotation)public String sayHello(Model model){//向模型中添加属性msg与值可以在JSP页面中取出并渲染model.addAttribute(msg,hello,SpringMVC, Controller_Annotation);//web-inf/jsp/hello.jspreturn hello;}
}总结
注解开发会更频繁且高效
两个方法的跳转指向同一个jsp页面视图复用可以看出控制器和视图之间是弱耦合关系
注解RequestMapping
作用
用于映射url到控制器类或一个特定的处理程序方法
可用于类或方法上
用于类上表示类中的所有响应请求的方法都是以该地址作为父路径用于方法上表示可以通过该路径访问到该方法
示例
// 仅注解在方法上localhost:8080 / 项目名 / h1Controller
public class TestController {RequestMapping(/h1)public String test(){return test;}
}// 既注解在类上也注解在方法上localhost:8080 /项目名/ admin / h1Controller
RequestMapping(/admin)
public class TestController {RequestMapping(/h1)public String test(){return test;}
}RestFul风格
什么是RestFul
RestFul
Restful就是一个资源定位及资源操作的风格不是标准也不是协议只是一种风格
基于这个风格设计的软件可以更简洁更有层次更易于实现缓存等机制
资源和资源操作
资源互联网所有的事物都可以被抽象为资源资源操作 使用POST、DELETE、PUT、GET对资源进行操作分别对应对资源的增、删、改、查查单一、查全部操作
资源操作方法对比
操作Restful传统增http://127.0.0.1/itemPOST方法http://127.0.0.1/item/saveItem.actionPOST方法删http://127.0.0.1/item/1DELETE方法http://127.0.0.1/item/deleteItem.action?id1GET方法或POST方法改http://127.0.0.1/itemPUT方法http://127.0.0.1/item/updateItem.actionPOST方法查单一http://127.0.0.1/item/GET方法不带参数http://127.0.0.1/item/queryItem.action?id1GET方法查全部http://127.0.0.1/item/1/GET方法带参数http://127.0.0.1/item/queryItem.action/allGET方法
示例
代码
test1
package GSF.Example.Restful;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;Controller
public class Restful {RequestMapping(/restful/{var1}/{var2})public String calculate(PathVariable int var1, PathVariable int var2, Model model){int result var1 var2;model.addAttribute(msg, 求和结果 result);return hello;}
}test2
package GSF.Example.Restful;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;Controller
public class Restful_method {//RequestMapping(value /restful_method/{var1}/{var2}, method {RequestMethod.POST})RequestMapping(value /restful_method/{var1}/{var2})GetMappingpublic String calculate(PathVariable int var1, PathVariable int var2, Model model){int result var1 var2;model.addAttribute(msg, 求和结果 result);return hello;}
}应用PathVariable 将url变量绑定到方法参数上 若url变量传入的类型和方法参数的类型不对应会出现404无法访问而不是在程序中出现类型不匹配异常
应用method属性
指定该url的请求方法
应用GetMapping、… 通过注解的形式指定url的请求方法类型 GetMapping、PostMapping、PutMapping、DeleteMapping、PatchMapping
数据处理及跳转
项目Module名称
Demo-04-SpringMVC-DataProcess_Redirection
代码参考上述连接该部分文章中不贴入完整代码
结果跳转
ModelAndView
package GSF.Example.ResultRedirection;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.mvc.Controller;public class ModelAndView implements Controller {Overridepublic org.springframework.web.servlet.ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {org.springframework.web.servlet.ModelAndView mv new org.springframework.web.servlet.ModelAndView();mv.addObject(msg, hello, Result Redirection, ModelAndView);mv.setViewName(hello);return mv;}
}springmvc-servlet中注册bean addObject写入数据 setViewName设置要跳转的视图资源 配合视图解析器
ServletAPI
package GSF.Example.ResultRedirection;import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import java.io.IOException;Controller
public class ServletAPI {RequestMapping(servlet_redirection/test1)public void test1(HttpServletRequest req, HttpServletResponse rsp) throws IOException {// 输出rsp.getWriter().println(hello, Result Redirection, ServletAPI: rsp.getWriter().println);}RequestMapping(servlet_redirection/test2)// 重定向禁止指向受保护的视图资源public void test2(HttpServletRequest req, HttpServletResponse rsp) throws IOException {rsp.sendRedirect(/Result_Redirection/test2.jsp);}RequestMapping(servlet_redirection/test3)public void test3(HttpServletRequest req, HttpServletResponse rsp) throws IOException, ServletException {// 请求转发可以指向受保护的视图资源req.setAttribute(msg, hello, Result Redirection, ServletAPI: req.setAttribute, req.getRequestDispatcher);req.getRequestDispatcher(/WEB-INF/jsp/hello.jsp).forward(req, rsp);}
}注意该代码针对Tomcat10servlet包名前缀是“jakarta” test1直接在响应结果中写入数据支持html标签 test2响应重定向重新请求资源禁止请求受保护资源 test3请求转发请求和响应信息可以继续传递可以请求受保护资源
SpringMVC-无需视图解析器
需要写全路径
package GSF.Example.ResultRedirection;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;// 请求前需要先注释掉springmvc-servlet.xml的视图解析器Controller
public class SpringMVC_NoViewParser {RequestMapping(/springMvc_redirection/test1)public String test1() {// 转发return /index_1.jsp;}RequestMapping(/springMvc_redirection/test2)public String test2() {// 转发//return forward:/index.jsp;//return forward:/index_1.jsp;return forward:/WEB-INF/jsp/hello.jsp;}RequestMapping(/springMvc_redirection/test3)public String test3() {// 重定向不让定向到受保护的视图资源内//return redirect:/index.jsp;return redirect:/WEB-INF/jsp/hello.jsp;}
}SpringMVC-有视图解析器
根据视图解析器的前缀和后缀补全剩余路径即可针对响应重定向不受视图解析器的影响写入全路径即可
package GSF.Example.ResultRedirection;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;import java.io.IOException;Controller
public class SpringMVC_ViewParser {RequestMapping(/springMvc_redirection_VP/test1)public String test1() throws IOException {// 转发自动借助视图解析器补充前缀和后缀// return index_1; // 不行// return /index_2; // 行return /jsp/hello; // 行}RequestMapping(/springMvc_redirection_VP/test2)public String test2() throws IOException {// 重定向不需要视图解析器写全路径return redirect:/Result_Redirection/test2.jsp;}
}数据处理-提交到后端的数据
package GSF.Example.DataProcess;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;Controller
RequestMapping(/data_process)
public class ProcessSubmitData {RequestMapping(/same_name)public String test1(String name){System.out.println(name);return /jsp/hello;}RequestMapping(/different_name)public String test2(RequestParam(username) String name){System.out.println(name);return /jsp/hello;}RequestMapping(/object)public String test3(User user){System.out.println(user);return /jsp/hello;}
}test1localhost:8080/data_process/same_name?name123456test2localhost:8080/data_process/different_name?username123456test3localhost:8080/data_process/object?namegsfid1age15
数据处理-数据显示到前端
package GSF.Example.DataShow;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;Controller
public class ShowDataToView {// 第一种ModelAndView参考ResultRedirection/ModelAndView// ModelMapRequestMapping(/show_data)public String test1(RequestParam(username) String name, ModelMap model){//封装要显示到视图中的数据//相当于req.setAttribute(name,name);model.addAttribute(msg,name);System.out.println(name);return /jsp/hello;}// ModelRequestMapping(/show_data_2)public String test2(RequestParam(username) String name, Model model){//封装要显示到视图中的数据//相当于req.setAttribute(name,name);model.addAttribute(msg,name);System.out.println(name);return /jsp/hello;}
}test1ModelMaptest2Model
乱码处理
方法1-springMVC-过滤器
使用springMVC提供的过滤器在web.xml中配置
filterfilter-nameencoding/filter-namefilter-classorg.springframework.web.filter.CharacterEncodingFilter/filter-classinit-paramparam-nameencoding/param-nameparam-valueutf-8/param-value/init-param
/filter
filter-mappingfilter-nameencoding/filter-nameurl-pattern/*/url-pattern
/filter-mapping极端情况下对get支持不好
方法2-Tomcat修改配置文件
Connector URIEncodingutf-8 port8080 protocolHTTP/1.1connectionTimeout20000redirectPort8443 /方法3-自定义过滤器
过滤器
package com.kuang.filter;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;/**
* 解决get和post请求 全部乱码的过滤器
*/
public class GenericEncodingFilter implements Filter {Overridepublic void destroy() {}Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {//处理response的字符编码HttpServletResponse myResponse(HttpServletResponse) response;myResponse.setContentType(text/html;charsetUTF-8);// 转型为与协议相关对象HttpServletRequest httpServletRequest (HttpServletRequest) request;// 对request包装增强HttpServletRequest myrequest new MyRequest(httpServletRequest);chain.doFilter(myrequest, response);}Overridepublic void init(FilterConfig filterConfig) throws ServletException {}}过滤器中调用的方法
//自定义request对象HttpServletRequest的包装类
class MyRequest extends HttpServletRequestWrapper {private HttpServletRequest request;//是否编码的标记private boolean hasEncode;//定义一个可以传入HttpServletRequest对象的构造函数以便对其进行装饰public MyRequest(HttpServletRequest request) {super(request);// super必须写this.request request;}// 对需要增强方法 进行覆盖Overridepublic Map getParameterMap() {// 先获得请求方式String method request.getMethod();if (method.equalsIgnoreCase(post)) {// post请求try {// 处理post乱码request.setCharacterEncoding(utf-8);return request.getParameterMap();} catch (UnsupportedEncodingException e) {e.printStackTrace();}} else if (method.equalsIgnoreCase(get)) {// get请求MapString, String[] parameterMap request.getParameterMap();if (!hasEncode) { // 确保get手动编码逻辑只运行一次for (String parameterName : parameterMap.keySet()) {String[] values parameterMap.get(parameterName);if (values ! null) {for (int i 0; i values.length; i) {try {// 处理get乱码values[i] new String(values[i].getBytes(ISO-8859-1), utf-8);} catch (UnsupportedEncodingException e) {e.printStackTrace();}}}}hasEncode true;}return parameterMap;}return super.getParameterMap();}//取一个值Overridepublic String getParameter(String name) {MapString, String[] parameterMap getParameterMap();String[] values parameterMap.get(name);if (values null) {return null;}return values[0]; // 取回参数的第一个值}//取所有值Overridepublic String[] getParameterValues(String name) {MapString, String[] parameterMap getParameterMap();String[] values parameterMap.get(name);return values;}
}总结
为了避免乱码问题在可能设置编码的地方都设置为UTF-8springMVC提供的过滤器基本就够用了
Json
项目Module名称
Demo-05-SpringMVC-Json
代码参考上述连接该部分文章中不贴入完整代码
什么是Json
概念
JSONJavaScript Object Notation, JS 对象标记是一种轻量级的数据交换格式目前使用特别广泛。采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和编写同时也易于机器解析和生成并有效地提升网络传输效率。
语法格式
对象表示为键值对数据由逗号分隔花括号保存对象方括号保存数组
Json和JavaScript的区别
JSON 是 JavaScript 对象的字符串表示法它使用文本表示一个 JS 对象的信息本质是一个字符串
var obj {a: Hello, b: World}; //这是一个对象注意键名也是可以使用引号包裹的
var json {a: Hello, b: World}; //这是一个 JSON 字符串本质是一个字符串Json和JavaScript的相互转换
var obj JSON.parse({a: Hello, b: World});
//结果是 {a: Hello, b: World}var json JSON.stringify({a: Hello, b: World});
//结果是 {a: Hello, b: World}Controller返回Json数据jackson
Module准备
1、导包
!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --
dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion2.9.8/version
/dependency2、建立Module完成springmvc-servlet.xml、web.xml配置大差不差不再详细贴出代码
Controller核心代码
package GSF.Example.Controller;import GSF.Example.Pojo.User;
import GSF.Example.Utils.JsonUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;//Controller // 使用Controller需要在方法上添加ResponseBody注解保证返回json形式数据
RestController // 使用RestController保证返回的都是json形式数据
public class UserController {RequestMapping(/json1)//RequestMapping(value /json1,produces application/json;charsetutf-8) // 设置返回数据字符集避免乱码//ResponseBodypublic String json1() throws JsonProcessingException {//创建一个jackson的对象映射器用来解析数据ObjectMapper mapper new ObjectMapper();//创建一个对象User user new User(秦疆1号, 3, 男);//将我们的对象解析成为json格式String str mapper.writeValueAsString(user);System.out.println(str);//由于ResponseBody注解这里会将str转成json格式返回十分方便return str;}RequestMapping(/json2)public String json2() throws JsonProcessingException {//创建一个jackson的对象映射器用来解析数据ObjectMapper mapper new ObjectMapper();//创建一个对象User user1 new User(秦疆1号, 3, 男);User user2 new User(秦疆2号, 3, 男);User user3 new User(秦疆3号, 3, 男);User user4 new User(秦疆4号, 3, 男);ListUser list new ArrayListUser();list.add(user1);list.add(user2);list.add(user3);list.add(user4);//将我们的对象解析成为json格式String str mapper.writeValueAsString(list);return str;}// 默认返回一个时间戳是一个lang整数值RequestMapping(/json3)public String json3() throws JsonProcessingException {ObjectMapper mapper new ObjectMapper();//创建时间一个对象java.util.DateDate date new Date();//将我们的对象解析成为json格式String str mapper.writeValueAsString(date);return str;}// 通过定义返回时间的格式返回数据RequestMapping(/json4)public String json4() throws JsonProcessingException {ObjectMapper mapper new ObjectMapper();//不使用时间戳的方式mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);//自定义日期格式对象SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);//指定日期格式mapper.setDateFormat(sdf);Date date new Date();String str mapper.writeValueAsString(date);return str;}RequestMapping(/json5)public String json5() throws JsonProcessingException {Date date new Date();String json JsonUtils.getJson(date); // 将代码抽出来自定义一个工具类return json;}
}统一处理乱码问题
springmvc-servlet.xml配置
!--Jackson统一解决乱码问题--
mvc:annotation-drivenmvc:message-converters register-defaultstruebean classorg.springframework.http.converter.StringHttpMessageConverterconstructor-arg valueUTF-8//beanbean classorg.springframework.http.converter.json.MappingJackson2HttpMessageConverterproperty nameobjectMapperbean classorg.springframework.http.converter.json.Jackson2ObjectMapperFactoryBeanproperty namefailOnEmptyBeans valuefalse//bean/property/bean/mvc:message-converters
/mvc:annotation-drivenController返回Json数据fastjson
Module准备
1、导包
dependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion1.2.60/version
/dependency2、建立Module完成springmvc-servlet.xml、web.xml配置大差不差不再详细贴出代码
fastjson三大核心类
核心类代表解释JSONObject代表 json 对象JSONObject实现了Map接口猜想 JSONObject底层操作是由Map实现的JSONObject对应json对象通过各种形式的get()方法可以获取json对象中的数据也可利用诸如size()isEmpty()等方法获取键值对的个数和判断是否为空其本质是通过实现Map接口并调用接口中的方法完成的JSONArray代表 json 对象数组内部是有List接口中的方法来完成操作的JSON代表 JSONObject和JSONArray的转化JSON类源码分析与使用主要是实现json对象json对象数组javabean对象json字符串之间的相互转化
数据类型相互转换
json对象json对象数组javabean对象json字符串之间的相互转化
package GSF.Example.Controller;import GSF.Example.Pojo.User;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;import java.util.ArrayList;
import java.util.List;public class FastJsonDemo {public static void main(String[] args) {//创建一个对象User user1 new User(秦疆1号, 3, 男);User user2 new User(秦疆2号, 3, 男);User user3 new User(秦疆3号, 3, 男);User user4 new User(秦疆4号, 3, 男);ListUser list new ArrayListUser();list.add(user1);list.add(user2);list.add(user3);list.add(user4);System.out.println(*******Java对象 转 JSON字符串*******);String str1 JSON.toJSONString(list);System.out.println(JSON.toJSONString(list)str1);String str2 JSON.toJSONString(user1);System.out.println(JSON.toJSONString(user1)str2);System.out.println(\n****** JSON字符串 转 Java对象*******);User jp_user1JSON.parseObject(str2,User.class);System.out.println(JSON.parseObject(str2,User.class)jp_user1);System.out.println(\n****** Java对象 转 JSON对象 ******);JSONObject jsonObject1 (JSONObject) JSON.toJSON(user2);System.out.println((JSONObject) JSON.toJSON(user2)jsonObject1.getString(name));System.out.println(\n****** JSON对象 转 Java对象 ******);User to_java_user JSON.toJavaObject(jsonObject1, User.class);System.out.println(JSON.toJavaObject(jsonObject1, User.class)to_java_user);}
}Ajax
学一半后边再说吧有点学不明白
拦截器Interceptor
什么是拦截器
概念
SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能
过滤器和拦截器的区别
过滤器拦截器servlet规范中的一部分任何java web工程都可以使用拦截器是SpringMVC框架自己的只有使用了SpringMVC框架的工程才能使用通过配置可以对所有要访问的资源进行拦截是AOP思想的具体应用只会拦截访问的控制器方法如果访问的是jsp/html/css/image/js是不会进行拦截的
拦截器使用
java代码
package GSF.Example.Interceptor;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;public class MyInterceptor implements HandlerInterceptor {//在请求处理的方法之前执行//如果返回true执行下一个拦截器//如果返回false就不执行下一个拦截器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(------------处理后------------);}//在dispatcherServlet处理后执行,做清理工作.public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {System.out.println(------------清理------------);}
}springmvc-servlet.xml配置
!--关于拦截器的配置--
mvc:interceptorsmvc:interceptor!--/** 包括路径及其子路径--!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截--!--/admin/** 拦截的是/admin/下的所有--mvc:mapping path/**/!--bean配置的就是拦截器--bean classGSF.Example.Interceptor.MyInterceptor//mvc:interceptor
/mvc:interceptors文件上传和下载
Module准备
1、建立相关Module
2、导包
!--文件上传有关的第三方库--
dependencygroupIdcommons-fileupload/groupIdartifactIdcommons-fileupload/artifactIdversion1.3.3/version
/dependency3、springmvc-servlet.xml配置bean
!--文件上传配置--
bean idmultipartResolver classorg.springframework.web.multipart.support.StandardServletMultipartResolver/这个bean的名字必须叫这个不能为其他的
核心代码展示
前端页面
% page contentTypetext/html;charsetUTF-8 languagejava %
html
body
h2Hello World!/h2h1上传文件/h1
h2上传单个文件java原生代码实现/h2
form action/upload enctypemultipart/form-data methodpostinput typefile namefile/input typesubmit valueupload
/formh2上传单个文件调file.TransferTo保存文件代码/h2
form action/upload2 enctypemultipart/form-data methodpostinput typefile namefile/input typesubmit valueupload
/formh2上传多个文件多个文件选择框实现调file.TransferTo保存文件代码/h2
form action/upload3 enctypemultipart/form-data methodpostinput typefile namefile/input typefile namefile/input typesubmit valueupload
/formh2上传多个文件单个文件选择框实现调file.TransferTo保存文件代码/h2
form action/upload3 enctypemultipart/form-data methodpostinput typefile namefile multiple/input typesubmit valueupload
/form
/bodyh1下载文件/h1
h2java原生代码实现/h2
a href/download点击下载/a
/htmlController
package GSF.Example.Controller;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;Controller
public class FileController {RequestMapping(/upload)public String fileUpload_onefile_manualsave(RequestParam(file) MultipartFile 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);System.out.println(path);//如果路径不存在创建一个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 len0;byte[] buffer new byte[1024];while ((lenis.read(buffer))!-1){os.write(buffer,0,len);os.flush();}os.close();is.close();return redirect:/index.jsp;}/** 采用file.Transto 来保存上传的文件*/RequestMapping(/upload2)public String fileUpload2(RequestParam(file) MultipartFile 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;}RequestMapping(/upload3) // 等价于 RequestMapping(value /upload, method RequestMethod.POST)public String fileUpload(HttpServletRequest req, RequestParam(file) MultipartFile[] files) throws IOException {ListString pathStrs new ArrayListString();if(files.length 0){//循环多次上传多个文件for (MultipartFile file : files) {if(!file.isEmpty()){//上传路径保存设置String path req.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;}// 下载文件的步骤// 1、设置response响应头// 2、读取文件InputStream// 3、写出文件OutputStream// 4、执行操作// 5、关闭流先开的流后关RequestMapping(value/download)public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{//要下载的图片地址String path request.getServletContext().getRealPath(/upload);String fileName 基础语法.jpg;//1、设置response 响应头response.reset(); //设置页面不缓存,清空bufferresponse.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 inputnew FileInputStream(file);//3、 写出文件--输出流OutputStream out response.getOutputStream();byte[] buff new byte[1024];int index0;//4、执行 写出操作while((index input.read(buff))! -1){out.write(buff, 0, index);out.flush();}out.close();input.close();return null;}
}