1.基础概念+原理
springmvc:基于MVC模式的一个WEB框架,是spring框架中的一个模块。
MVC模式:Model-模型,View-视图,Controller-控制器,是一种软件设计模式。
https://www.cnblogs.com/xiaoxi/p/6164383.html
springmvc的工作原理:
1.客户端的请求将被前端控制器(DispatcherServlet)拦截。
2.前端控制器调用映射器(HandlerMapping)去查找处理器(Controller)。
3.前端控制器调用适配器(HandlerAdapter)去执行处理器。
4.处理器执行完后向适配器返回模型视图(ModelAndView)。
5.适配器向前端控制器返回模型视图。
6.前端控制器调用视图解析器(ViewResolver)对模型视图进行解析。
7.视图解析器向前端控制器返回视图(View)。
8.前端控制器对视图进行渲染并响应给客户端。
各个组件的作用详解:
1.前端控制器(DispatcherServlet):接收请求,响应结果,类似于管家。
2.映射器(HandlerMapping):根据请求的url去查找处理器。
3.处理器(Controller):需要编写具体的处理逻辑。
4.适配器(HandlerAdapter):支持各种类型的处理器。
5.模型视图(ModelAndView):封装Model和View对象。
6.视图解析器(ViewResolver):进行视图解析。
7.视图(View):渲染具体数据的页面。
一般情况下需要关注的组件:处理器(Controller)、视图(View)。
2.开发步骤(1.2.3)
springmvc开发步骤:
1.导入所需jar包:
2.在web.xml文件中配置前端控制器(org.springframework.web.servlet.DispatcherServlet):
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 配置springmvc前端控制器(DispatcherServlet) -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet(固定)</servlet-class>
<!-- 配置springmvc文件的加载路径(contextConfigLocation) -->
<init-param>
<param-name>contextConfigLocation(固定)</param-name>
<param-value>classpath:config/springmvc.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
注:若不在web.xml文件中配置contextConfigLocation初始化参数,则springmvc配置文件必须在WEB-INF目录下,且文件名必须为的值加上”-servlet.xml”,如springmvc-servlet.xml。
/:拦截不带后缀名的请求以及带后缀名的静态资源(如.js、.css、
.png、.css、.jpg、.html等等,但不会拦截.jsp动态资源),会覆盖tomcat的默认拦截配置。/*表示拦截所有请求,一般只用在过滤器上。
3.创建springmvc配置文件,如:springmvc.xml。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/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">
<context:component-scan base-package="com.controller"/>
<!-- 开启springmvc注解功能 -->
<mvc:annotation-driven/>
</beans>
3.创建控制器(Controller)
一、 创建控制器(Controller),三种方式。
A. 定义返回类型为ModelAndView的处理方法。
B. 定义返回类型为void的处理方法。
C. 定义返回类型为String的处理方法(常用)。
注:若要在控制器中请求非页面资源且使用了视图解析器时则只能用重定向或请求转发。
视图解析器用来返回逻辑视图,需在springmvc文件中配置:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver(固定)">
<property name="prefix(固定)" value="jsp/"/>
<property name="suffix(固定)" value=".jsp"/>
</bean>
配置视图解析器后代码修改如下:
二、控制器中方法的参数由spring容器自动注入:
1. 注入自带类型,如Model、ModelMap、HttpServletRequest、HttpServletResponse、HttpSession等。
2. 注入简单类型,处理方法的参数名需与请求的参数名一致,如String、String[]、int等。
3. 注入复杂类型,处理方法中参数的属性名需与请求的参数名一致,如Shop等。
4. 注入List类型,需将绑定在对象上,而不能直接定义在处理方法的参数中,且处理方法中参数的List类型属性名需与请求的参数名一致。
5. 注入Map类型,需在处理方法的参数中添加@RequestParam注解。
4.AJAX请求及JSON交互
AJAX请求及JSON交互:
1. 若需将处理方法的返回值以JSON格式返回,或将JSON格式的请求参数映射为处理方法参数的具体类型,则需以下jar包的支持。
下载地址:
http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-core-asl
http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl
2.若提交方式为POST,处理中文时则需在web.xml文件中配置spring提供的过滤器。
<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>
3. 若需引用外部js文件,则需在springmvc配置文件中添加静态资源的访问配置。
<!--
配置静态资源的访问
location:配置静态资源所在物理路径。
mapping:配置请求静态资源的映射路径。
**:匹配当前路径及其子孙路径。
-->
<mvc:resources location="/js/" mapping="/js/**"/>
4. 请求及响应。
响应字符串:
响应实体:
响应Map:
响应List:
响应List
JSON请求参数映射为实体:
//data为字符串
type:“post”,//必须设置为post
//Content-Type,内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码
contentType:“application/json”,//必须设置该属性
JSON请求参数映射为Map:
JSON请求参数映射为List<Pojo>:
JSON请求参数映射为List<Map>:
springmvc中的常用注解:
@RequestMapping:配置请求与处理方法的映射,可用于类和方法上。
@RequestParam:配置请求参数与处理方法参数的映射,用于参数中。
@PathVariable:配置URL中的变量与处理方法参数的映射,支持restful请求风格(即不带后缀和参数的请求),用于参数中。
restful
//中文不可传
//顺序要保持一致,参数类型
@RequestMapping(“restful/{age}/{name}”)
public String restful(@PathVariable String name,@PathVariable int age){
System.out.println(name+"="+age);
return “”;
}
@RequestBody:配置json请求参数与处理方法参数的映射,用于参数中。
@ResponseBody:处理方法的返回值作为响应体。
5.JSON.stringify()
JavaScript JSON.stringify()
JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串。
语法
JSON.stringify(value[, replacer[, space]])
参数说明:
value:
必需, 要转换的 JavaScript 值(通常为对象或数组)。
replacer:
可选。用于转换结果的函数或数组。
如果 replacer 为函数,则 JSON.stringify 将调用该函数,并传入每个成员的键和值。使用返回值而不是原始值。如果此函数返回 undefined,则排除成员。根对象的键是一个空字符串:""。
如果 replacer 是一个数组,则仅转换该数组中具有键值的成员。成员的转换顺序与键在数组中的顺序一样。当 value 参数也为数组时,将忽略 replacer 数组。
space:
可选,文本添加缩进、空格和换行符,如果 space 是一个数字,则返回值文本在每个级别缩进指定数目的空格,如果 space 大于 10,则文本缩进 10 个空格。space 有可以使用非数字,如:\t。
返回值:
返回包含 JSON 文本的字符串。
6.Spring MVC @ResponseBody响应中文乱码
http://www.cnblogs.com/striver-zhu/p/7158623.html
7.拦截器
拦截器:用于对处理器进行预处理和后处理,常用于日志记录,权限检查,性能监控等。
实现步骤:
1.创建一个实现HandlerInterceptor接口,重写接口中的方法。
2. 在springmvc配置文件中添加拦截器配置。
<mvc:interceptors>
<!-- 多个拦截器则按配置的先后顺序执行 -->
<mvc:interceptor>
<!-- /**:拦截所有及子url -->
<mvc:mapping path="/delete"/>
<bean class="com.interceptor.InterceptorDemo"/>
</mvc:interceptor>
</mvc:interceptors>
3.测试的处理器和jsp页面。
8.文件上传下载
一、web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 配置springmvc前端控制器(DispatcherServlet) -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置springmvc文件的加载路径(contextConfigLocation) -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/springmvc.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 配置spring提供的字符编码过滤器(针对post提交方式) -->
<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>
</web-app>
二、index.jsp
<%@ page pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>文件上传和下载</title>
</head>
<body>
<!-- 固定写法:method="post" enctype="multipart/form-data" -->
<form action="upload" method="post" enctype="multipart/form-data">
文件1:<input type="file" name="files"/><br/>
文件2:<input type="file" name="files"/><br/>
<input type="submit" value="上传"/>
</form>
<a href="filelist">文件列表</a>
</body>
</html>
三、springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/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">
<context:component-scan base-package="com.controller"/>
<!-- 开启springmvc注解功能 -->
<mvc:annotation-driven/>
<!-- 配置文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
</beans>
四、com.controller
@Controller
public class ControllerDemo {
@RequestMapping("/upload")
public String upload(@RequestParam MultipartFile[] files, HttpServletRequest request)
throws IllegalStateException, IOException {
// 获取目录名的绝对路径
String path = request.getSession().getServletContext().getRealPath("upload");
// 创建文件夹对象
File dir = new File(path);
if(files != null) {
for(MultipartFile file : files) {
// 获取上传的文件名(文件名+后缀名)
String fileName = file.getOriginalFilename();
if(!file.isEmpty()) {
File dest = new File(dir, fileName);
// 上传文件
file.transferTo(dest);
}
}
}
return "index.jsp";
}
@RequestMapping("/filelist")
public String filelist(HttpServletRequest request) {
// 获取目录名的绝对路径
String path = request.getSession().getServletContext().getRealPath("upload");
// 创建文件夹对象
File dir = new File(path);
// 获取该路径下的所有文件和目录名
String[] fileNameArr = dir.list();
// 将所有的文件名以逗号(,)拼接
StringBuilder sb = new StringBuilder();
for(String fileName : fileNameArr) {
if(sb.length() != 0) {
sb.append(",");
}
sb.append(fileName);
}
request.setAttribute("fileNames", sb.toString());
return "show.jsp";
}
@RequestMapping("/download/{fileName}")
public ResponseEntity<byte[]> download(@PathVariable String fileName,
HttpServletRequest request) throws IOException {
// 解决文件名中文问题
fileName = new String(fileName.getBytes("iso-8859-1"), "utf-8");
// 获取目录名的绝对路径
String path = request.getSession().getServletContext().getRealPath("upload");
// 构建下载的文件对象
File file = new File(path, fileName);
// 解决下载时文件名的中文问题
String downloadFileName = new String(fileName.getBytes(), "iso-8859-1");
// 用来封装响应头信息
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentDispositionFormData("attachment", downloadFileName);
httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
byte[] b = FileUtils.readFileToByteArray(file);
ResponseEntity<byte[]> responseEntity =
new ResponseEntity<byte[]>(b, httpHeaders, HttpStatus.OK);
return responseEntity;
}
}
五、show.jsp
<%@ page pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>文件上传和下载</title>
<script type="text/javascript">
window.onload = function()
{
var html = [];
var fileNames = "${fileNames}";
var arr = fileNames.split(",");
for(var i=0; i<arr.length; i++)
{
html.push("<a href='download/" + arr[i] + "/'>" + arr[i] + "</a>");
}
var div = document.getElementById("div_list");
div.innerHTML = html.join("<br/>");
}
</script>
</head>
<body>
<div id="div_list"></div>
</body>
</html>
9.spring+springmvc+mybatis+ajax整合
1. 导入所需jar包。
2. 导入jquery的脚本。
3. web.xml文件配置。
4. 工程结构图。
spring-bean.xml文件内容:
spring-mvc.xml文件内容:
spring.xml文件内容:
注:在实际开发中一般用ContextLoaderListener监听器来加载和初始化公共的bean,如DAO和Service层的bean。而DispatcherServlet只用来加载和初始化web相关的bean,如Controller、HandlerMapping、HandlerAdapter等。
web.xml文件:
spring-bean.xml文件内容:
springmvc.xml文件内容:
10.web中静态资源和动态资源的概念及区别
https://blog.csdn.net/u012110719/article/details/44239429
1.静态资源和动态资源的概念
简单来说:
静态资源:一般客户端发送请求到web服务器,web服务器从内存在取到相应的文件,返回给客户端,客户端解析并渲染显示出来。
动态资源:一般客户端请求的动态资源,先将请求交于web容器,web容器连接数据库,数据库处理数据之后,将内容交给web服务器,web服务器返回给客户端解析渲染处理。
2.静态资源和动态资源的区别
a.静态资源一般都是设计好的html页面,而动态资源依靠设计好的程序来实现按照需求的动态响应;
b.静态资源的交互性差,动态资源可以根据需求自由实现;
c.在服务器的运行状态不同,静态资源不需要与数据库参于程序处理,动态可能需要多个数据库的参与运算。
l html:静态资源 ,浏览器可以看得懂,它可以有变量;
l JSP/Servlet:动态资源,需要先转换成html,再给浏览器看。
11.出现的问题
无效的列索引;
原因:参数可能没有传过去
12.druid(用连接池配置数据源)
数据库账号密码加密
<!-- 配置数据源DriverManagerDataSource 自带的,实际开发中不用 -->
<!--实际开发中用连接池c3p0,db3p,druid-->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.pwd}"/>
</bean>
db.properties配置,如下:
jdbc.driver=oracle.jdbc.OracleDriver
jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl
jdbc.user=movie
#加密:java -cp druid-1.1.9.jar com.alibaba.druid.filter.config.ConfigTools 123(密码)
#密码是随机的,在druid包页面命令行中,复制粘贴加密里面的内容,然后run,之后复制密码,拷贝到这边的密码中
jdbc.pwd=Vuanr8BSGqajX8dLQXF3ZkUrDH8HCR75BUqlObSa9viUBFqaMWeA357ESHjtiFi8CtyfunB9iUnOkR6qPIFgKw==
#初始连接数。
jdbc.initialSize=1
#最小连接池数量。
jdbc.minIdle=1
#最大连接池数量。
jdbc.maxActive=10
#获取连接时最大等待时间(单位毫秒),这里为1分钟。
jdbc.maxWait=60000
#一个连接在池中的最小生存时间(单位毫秒)。
jdbc.minEvictableIdleTimeMillis=300000
#1.Destroy线程会检测连接的间隔时间,即间隔多久才进行一次检测需要关闭的空闲连接(单位毫秒)。
#2.testWhileIdle的判断依据。
jdbc.timeBetweenEvictionRunsMillis=60000
#连接使用限制时间(单位秒),若有业务处理时间超过设定时间,可适当调整,这里为1分钟。
jdbc.removeAbandonedTimeout=60
#连接使用超过限制时间是否回收(不建议在生产环境中打开)。
jdbc.removeAbandoned=true
#连接回收时控制台打印信息,测试环境可为true,生产环境false,会影响性能。
jdbc.logAbandoned=false
#用来检测连接是否有效的sql,要求是一个查询语句。
#如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle均无效。
#常用数据库的validationQuery检查语句:
#oracle:select 1 from dual
#mysql、sqlserver、ingres、derby、h2:select 1
#db2:select 1 from sysibm.sysdummy1
#hsqldb:select 1 from information_schema.system_users
#postgresql:select version()
jdbc.validationQuery=select 1 from dual
#申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能(默认true)。
jdbc.testOnBorrow=false
#归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能(默认false)。
jdbc.testOnReturn=false
#建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于
#timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效(默认false)。
jdbc.testWhileIdle=true
#是否缓存preparedStatement,也就是PSCache(默认false)。
#如果用oracle则配置为true,mysql为false。分库分表较多的数据库,建议配置为false。
jdbc.poolPreparedStatements=true
#指定每个连接上PSCache的大小
jdbc.maxPoolPreparedStatementPerConnectionSize=20
#通过别名的方式配置扩展插件。
#常用的插件有:监控统计:stat、日志:log4j、防御sql注入:wall。
#启动服务后的监控访问地址:http://ip:port/projectName/druid
jdbc.filters=stat,config
#解密,步骤1:filters=config、步骤2:config.decrypt.key为publicKey。
#(公共key也是随机的,myEclipse+\,eclipse不+\)
jdbc.connectionProperties=config.decrypt=true;config.decrypt.key\=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJTdbQv0gde10olfxCjLC/a7Ba21Enf6MiS7OUIm7rfDBWih5roJXqGbf33nAFqY1yuKR3qHOwb9i+iHnqMVmqkCAwEAAQ==
13,加密+解密
//druid提供加解密
String pwd1=ConfigTools.encrypt("123");
String pwd2=ConfigTools.decrypt(pwd1);
@Test
public void xx1() throws Exception{
//druid提供加解密
String pwd1=ConfigTools.encrypt("123");
System.out.println(pwd1);
String pwd2=ConfigTools.decrypt(pwd1);
System.out.println(pwd2);
}