笔者自学的框架,知识点来自网上学习教程,方便实惠,推荐,特此声明。
一.springmvc
- pom.xml
1,1导入springmvc+spring依赖(junit、springmvc、servlet)
1.2 设置maven参数<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.0.4.RELEASE</version> </dependency>
1.3 .额外依赖<build> <finalName>springmybatis</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <!-- jdk的版本号 --> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </pluginManagement> </build>
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-parameter-names</artifactId> <version>2.9.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jdk8</artifactId> <version>2.9.4</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.9.4</version> </dependency>
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.46</version> </dependency>
<dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.9.9</version> </dependency>
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.9.Final</version> </dependency>
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency>
- web.xml(4.0版本的web.xml)
2.1设置spring MVC的DispatcherServlet中央控制器,init-param属性的value的springmvc.xml文件可按自己需求命名,只需与resources目录下的springmvc.xml文件命名相同即可<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 注册spring MVC中央控制器 --> <servlet> <servlet-name>springMVC</servlet-name> <!-- spring MVC中的核心控制器 --> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.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> <!-- 静态资源解释器 方式1 --> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.jpg</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping> </web-app>
- springmvc.xml(名称可修改)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 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 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> <!-- 静态资源解释器 方式2 --> <mvc:default-servlet-handler/> <!-- 静态资源解释器 方式3 --> <mvc:resources mapping="/images/**" location="/images/" /> <!-- 注册组件扫描器 --> <context:component-scan base-package="com.java.*"/> <!-- 视图解释类 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <!--解决返回json数据乱码问题--> <bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/plain;charset=UTF-8</value> <value>application/json;charset=UTF-8</value> </list> </property> </bean> <!-- 通过xml注册Controller --> <bean id="/hello.do" class="com.java.Controller.HelloSpringMVC"/> </beans>
二.组件解释
- web.xml
1.1 为了配合restful风格的url,将url-pattern设置为/模式,同时添加静态资源解释器
1.2 注册spring MVC核心控制器DispatcherServlet,扫描springmvc.xml<!-- 静态资源解释器 方式1 --> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.jpg</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping>
1.3 设置utf-8,解决数据乱码<!-- 注册spring MVC中央控制器 --> <servlet> <servlet-name>springMVC</servlet-name> <!-- spring MVC中的核心控制器 --> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.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>
</servlet-mapping> <!--字符编码过滤器--> <filter> <filter-name>characterEncodingFilter</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> <!--强制指定字符编码,即如果在request中指定了字符编码,那么也会为其强制指定当前设置的字符编码--> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
- springmvc.xml
2.1为了配合restful风格的url,将url-pattern设置为/模式,同时添加静态资源解释器
2.2 注册controller<!-- 静态资源解释器 方式2 --> <mvc:default-servlet-handler/> <!-- 静态资源解释器 方式3 --> <mvc:resources mapping="/images/**" location="/images/" />
2.2.1 xml方式在springmvc.xml配置文件中注册bean,同时controller需要实现Controller接口
2.2.2 注解方式(注解需要添加注解驱动,用来注册controller的驱动,用来注册AnnotationDrivenBeanDefinitionParser 对象,并且AnnotationDrivenBeanDefinitionParser 中注册 RequestMappingHandlerMapping & RequestMappingHandlerAdapter 这两个 Bean,如果不添加会导致无法创建controller,报出404错误。注解分析详解)之后在类上添加@Controller()<bean id="/hello.do" class="com.java.Controller.HelloSpringMVC" />
<!-- 注册组件(注解)扫描器 --> <context:component-scan base-package="com.java.*"/> <!-- 注册注解驱动--> <mvc:annotation-driven/>
- 类(Controller,service等的书写)
3.1 Controller
注解记录:
a:@Controller() 用来标注Controller类
b:@RequestMapping(value="/test",method = RequestMethod.POST,params={string , int},produces = “text/html;charset=utf-8”) 用来标注类和方法,可以通过参数value方法
value可使用通配符例如:”/test“、”/test“、”/java//test“,一个为一层,两个*为多层匹配
method设置访问的方法
params可设置必须携带的参数或者必须不得携带的参数,或者参数必须为某个值
produces = “text/html;charset=utf-8"设置字符编码
c:@RequestParam(name=“age”,defaultValue = “18” required = false) 用于标记单参数的命名,当表单参数和函数参数不同时使用,该注解在参数前使用
name:表单参数的name
defaultValue:表单无参数时默认value
required : 默认为true,当设置为true时,请求必须携带参数
d:@PathVariable(“value”) :用于读取请求路径上的参数
例如:@RequestMapping(”/{username}/regist.do")
则可以通过@PathVariable(“username”)设置在name参数前,将值赋值给name
三.知识点
- 知识点1: Controller参数,以下几个参数会自动赋值,
HttpServletRequest
HttpServletResponse
HttpSession
请求携带的参数
用于承载数据的Model - 知识点2: ModelAndView
表单提交,会把表单的参数当作函数的参数传入函数,而要将表单的参数传入新的view,则需要ModelAndView的对象中addObject(“id”, id);以id举例,之后设置新的页面setViewName(“test1”); - 知识点3: Controller的不同返回类型
a:返回类型为ModelAndView:可执行参数传递以及跳转页面
b:返回String类型:返回String则是跳转页面,如果添加Model对象(Controller自动创建Model只需在函数参数中引入Model model),则与ModelAndView返回类型类似。
当addAttribute只有value没有name时,会自动匹配name例如传入com.monkey1024.Product类型,会将其命名为"product" com.monkey1024.MyProduct 命名为 "myProduct" com.monkey1024.UKProduct 命名为 "UKProduct"
model可添加Collection参数,例如list以value为name和value、map以key为name,value为valuemodel.addAttribute(name); model.addAttribute("username", name);
如果要跳转到其他网页的页面例如:www.baidu.com则需要在springmvc中配置,配置后可通过String返回类型返回return baidu;来实现对百度的跳转,但与视图解释器相冲突,视图解释器优先匹配
c:void 有两种用法,靠servlet自带的跳转<!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/> <!--定义外部资源view对象--> <bean id="baidu" class="org.springframework.web.servlet.view.RedirectView"> <property name="url" value="http://www.baidu.com/"/> </bean>
方式1:当不需要springmvc帮忙跳转,而要自己通过sevlet方式跳转时
方式2:通过response.getWriter()返回ajax数据时,不需要返回页面,所以返回类型为viodrequest.setAttribute("student", student); //因为使用servlet中的api,所以视图解析就不能使用了,转发 request.getRequestDispatcher("/jsp/welcome.jsp").forward(request,response); //重定向 response.sendRedirect("/other-app/Other");
$(function () { $("#ajaxRequest").click(function () { $.ajax({ method:"post", url:"/ajaxRequest.do", data:{name:"java",age:18}, dataType:"json", success:function (result) { alert(result.name + "," + result.age); } }); }); });
d:返回类型为object,使用了jackjson来数据类型转换PrintWriter out = response.getWriter(); String jsonString = JSON.toJSONString(student); out.write(jsonString);
- 知识点4: 转发重定向
//返回类型为ModelAndView //手动显式指定使用转发,此时springmvc.xml配置文件中的视图解析器将会失效 mv.setViewName("forward:/jsp/result.jsp"); //手动重定向 mv.setViewName("redirect:/jsp/result.jsp"); //返回类型为/String //转发 return "forward:/jsp/result.jsp"; //重定向 return "redirect:/jsp/result.jsp"; //返回类型为void //转发 request.getRequestDispatcher("/jsp/result.jsp").forward(request, response); //重定向 response.sendRedirect(request.getContextPath()+"/jsp/result.jsp");
- 知识点5: 异常处理三种方式
a: 在Controller里抛出异常,在springmvc.xml里设置异常处理器
可自定义异常处理类,并且绑定自定义异常页面,也有默认异常处理,需要指定页面。ex为异常信息。<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="com.java.Tool.MyException">error/MyError</prop> </props> </property> <property name="defaultErrorView" value="error/error"/> <property name="exceptionAttribute" value="ex"/> </bean>
b: 注解异常处理方式@ExceptionHandler(MyException.class),只解决自己Controller的异常信息,value值为异常类型,例中异常处理为MyException.class,为自定义异常
c: 可写一个异常父类,子类全部继承即可无需重写,缺点是无法继承其他类,同时可书写一个默认异常处理方法。@ExceptionHandler(MyException.class) public ModelAndView handleMyException(Exception ex) { ModelAndView mv = new ModelAndView(); mv.addObject("ex", ex); mv.setViewName("/error/MyError"); return mv; }
/** * 处理MyException异常的方法 * @param ex * @return */ @ExceptionHandler(MyException.class) public ModelAndView handleMyException(Exception ex) { ModelAndView mv = new ModelAndView(); mv.addObject("ex", ex); mv.setViewName("/error/MyError"); return mv; } /** * 其他异常处理,注解中不用写value属性 * @param ex * @return */ @ExceptionHandler public ModelAndView handleException(Exception ex) { ModelAndView mv = new ModelAndView(); mv.addObject("ex", ex); mv.setViewName("/error/error"); return mv; }
- 知识点6: 数据类型转换(日期类型转换)
a:注册类型转换器
更改springmvc.xml(注册新的转换器)
方法代码<!--注册注解驱动--> <mvc:annotation-driven conversion-service="conversionService"/> <!--注册类型转换器--> <bean id="dateConverter" class="com.java.Tool.DateConverter"/> <!--注册类型转换服务bean--> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters" ref="dateConverter"/> </bean>
之后转换器会自动把String转换为Date类型public class DateConverter implements Converter<String, Date> { @Override public Date convert(String s) { if (s != null && !"".equals(s)) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { return sdf.parse(s); } catch (ParseException e) { e.printStackTrace(); } } return null; } }
当然也可以把int转为String,把秒数转为Date等,自编代码
b:@DateTimeFormat注解
jdk7之前需要导入joda-time依赖,即localDate api
在Controller的Date前添加@DateTimeFormat(即可)
同时,在要存储的javabean中,也需要在Date属性上添加注解(这个笔者没试过,或者说没试出来,将来必须来试试) - 知识点7: 数据校验
a: 添加hibernate-validator的依赖
b: 在springmvc.xml中添加数据检验器
c: 常用注解<!--验证器--> <bean id="monkey1024Validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/> </bean> <!--注册注解驱动--> <mvc:annotation-driven validator="monkey1024Validator"/>
@AssertFalse 验证注解的元素值是 false
@AssertTrue 验证注解的元素值是 true
@DecimalMax(value=x) 验证注解的元素值小于等于指定的十进制value 值
@DecimalMin(value=x) 验证注解的元素值大于等于指定的十进制value 值
@Digits(integer=整数位数, fraction=小数位数)验证注解的元素值的整数位数和小数位数上限
@Future 验证注解的元素值(日期类型)比当前时间晚
@Max(value=x) 验证注解的元素值小于等于指定的 value值
@Min(value=x) 验证注解的元素值大于等于指定的 value值
@NotNull 验证注解的元素值不是 null
@Null 验证注解的元素值是 null
@Past 验证注解的元素值(日期类型)比当前时间早
@Pattern(regex=正则表达式) 验证注解的元素值不指定的正则表达式匹配
@Size(min=最小值, max=最大值) 验证注解的元素值的在 min 和 max (包含)指定区间之内,如字符长度、集合大小
@Valid 该注解主要用于字段为一个包含其他对象的集合或map或数组的字段,或该字段直接为一个其他对象的引用,这样在检查当前对象的同时也会检查该字段所引用的对象。
@NotEmpty 验证注解的元素值不为 null 且不为空(字符串长度不为 0、集合大小不为 0)
@Range(min=最小值, max=最大值)验证注解的元素值在最小值和最大值之间
@NotBlank 验证注解的元素值不为空(不为 null、去
除首位空格后长度为 0),不同于@NotEmpty, @NotBlank 只应用于字符串且在比较时会去除字符串的空格
@Length(min=下限, max=上限) 验证注解的元素值长度在 min 和 max 区间内
@Email 验证注解的元素值是 Email,也可以通过正则表达式和 flag 指定自定义的 email 格式
d: 使用
将javabean的每个属性注解上相应的注解,设定属性的限制,在Controller接受的参数中用@Validated标注参数,并且在参数中接受BindingResult br的结果信息。
从br中获取错误信息,如果输入错误则返回页面并显示错误信息,如果没有错误信息则显示操作成功@RequestMapping("/register.do") //不能将@Validated 注解在String类型和基本类型的形参前。 //BindingResult参数可以获取到所有验证异常的信息 public ModelAndView register(@Validated User user, BindingResult br) { ModelAndView mv = new ModelAndView(); List<ObjectError> allErrors = br.getAllErrors(); System.out.println(allErrors.size()); if (allErrors != null && allErrors.size() > 0) { FieldError nameError = br.getFieldError("name"); FieldError ageError = br.getFieldError("age"); FieldError phoneError = br.getFieldError("phone"); if (nameError != null) { mv.addObject("nameError", nameError.getDefaultMessage()); } if (ageError != null) { mv.addObject("ageError", ageError.getDefaultMessage()); } if (phoneError != null) { mv.addObject("phoneError", phoneError.getDefaultMessage()); } mv.setViewName("/register"); return mv; } mv.addObject("name", user.getName()); mv.setViewName("/user"); return mv; }
- 知识点8: 文件上传
- 编写处理文件上传的controller,在处理文件上传的方法中需要添加MultipartFile类型的参数,MultipartFile本身是一个接口,里面提供了一些文件上传的操作的方法:
getOriginalFilename()
获得文件名
isEmpty()
判断是否上传了文件,如果没有选择文件上传的话,此时结果为true
getContentType()
获得上传文件的文件类型
transferTo(File file)
将文件上传至指定目录中
getName()
获取表单中input的name值
getBytes()
获取上传文件的byte数组
getInputStream()
获取上传文件的InputStream对象 - 使用commons组件实现文件上传(导入jar包),文件自动上传
在springmvc.xml里设置好参数,添加以下<!--注册multipartResolver,由DispatcherServlet来负责调用--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--设置字符编码防止文件名乱码--> <property name="defaultEncoding" value="utf-8"/> <!--设置上传文件的总大小,单位是字节b--> <property name="maxUploadSize" value="1048576"/> <!--设置单个上传文件的大小,单位是字节b--> <property name="maxUploadSizePerFile" value="1048576"/> <!--设置内存缓冲区的大小,当超过该值的时候会写入到临时目录--> <property name="maxInMemorySize" value="1048576"/> <!--设置临时目录--> <property name="uploadTempDir" value="tempupload"/> <!--默认是false,如果设置为true的话,不会将文件路径去除,在IE浏览器下上传时会将路径名也作为文件名上传:D:\image\monkey.png--> <property name="preserveFilename" value="false"/> <!--是否使用懒加载,默认是false--> <property name="resolveLazily" value="true"/> </bean>
- 使用servlet3.0实现文件上传
xml添加以下内容
在springmvc.xml添加以下内容<!--使用servlet3.0实现文件上传--> <multipart-config> <!--临时文件路径--> <location>/temp</location> <!--单个上传文件的最大值,单位是byte--> <max-file-size>100</max-file-size> <!--总上传文件的最大值--> <max-request-size>52428800</max-request-size> <!--内存缓冲区的大小,当超过该值时,会写入到临时文件中,单位是byte--> <file-size-threshold>1024</file-size-threshold> </multipart-config>
ps:文件上传名称相同时,需要将MultipartFile参数变为MultipartFile数组参数,并在之前添加@RequestParam注解<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"/>
- 知识点9: 拦截器
springmvc.xml文件中注册拦截器,/** 表示对所有controller拦截,可定义多个拦截器package com.monkey1024.interceptor; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("拦截器中的preHandle方法"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("拦截器中的postHandle方法"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("拦截器中的afterCompletion方法"); } }
<!--注册拦截器--> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.monkey1024.interceptor.MyInterceptor"/> </mvc:interceptor> </mvc:interceptors>