1.jar
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<!--web模块-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
2.配置web.xml
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
<!--
/和/*都是拦截所有请求,不会拦截jsp请求
/*的范围更大:还会拦截到*.jsp的请求
-->
</servlet-mapping>
3.配置sping.xml
1.开启注解
<context:component-scan base-package="controller"></context:component-scan>
2.配置视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
4.springMVC细节
细节一:不指定配置文件
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<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>-->
</servlet>
启动报错:/WEB-INF/下找不到xxx-servlet.xml
解决方法:在/WEB-INF/新建一个xxx-servlet.xml,即可不在web.xml中指定配置文件
细节二:/和/*的区别
/和/*都是拦截所有请求,不会拦截jsp请求
/*的范围更大:还会拦截到*.jsp的请求
5.@Pathvariable
6.requestMapping属性
requestMapping属性
* method:限定请求方式
* params:限定请求参数
* headers:限定请求头
* consumes:限定浏览器
* produce:限定浏览器内容返回值类型
7.REST
1.配置HiddenHttpMethodFilter
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.表单提交时
<form action="user" method="post">
//转换提交
<input name="_method" value="put">
<input type="submit" value="_put">
</form>
<form action="user" method="post">
<input name="_method" value="delete">
<input type="submit" value="_delete">
</form>
8.请求参数处理
* 三个注解
* @RequestParam:获取请求参数
* value:请求参数的key
* required:true/false
* defaultValue:设置默认值
* @RequestHeader
* value:请求参数的key
* required:true/false
* defaultValue:设置默认值
* @CookieValue:
* value:请求参数的key
* required:true/false
* defaultValue:设置默认值
@RequestMapping(value = "/user",method = RequestMethod.GET)
public String select(@RequestParam(value = "",required = true,defaultValue = "ddd") String id,
@RequestHeader(value = "",required = true,defaultValue = "")String header,
@CookieValue(value = "",required = true,defaultValue = "")String cookie){
System.out.println("select......."+id);
return "success";
}
9.请求参数
1.支持pojo自动封装
<form action="/user" method="post">
<input type="text" value="name">
<input type="text" value="sex">
<input type="text" value="age">
</form>
@RequestMapping("/user")
public String test02(User user){
System.out.println(user);
return "success";
}
2.支持级联
<form action="/user" method="post">
<input type="text" value="name">
<input type="text" value="sex">
<input type="text" value="age">
//级联属性
<input type="text" value="address.addr"
</form>
@RequestMapping("/user")
public String test02(User user){
System.out.println(user);
return "success";
}
3.支持原生API
HttpServletRequest
HttpServletResponse
HttpSession
@RequestMapping("/user")
public String test02(HttpServletRequest request,
HttpServletResponse response,
HttpSession session){
return "success";
}
10.请求编码(必须写在最前面)
<!--字符编码-->
<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>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
11.Mdole,Map,ModleMap
12.返回值为ModelAndView
//返回值为ModelAndView可以携带数据并且跳转
@RequestMapping("/user")
public ModelAndView test02(Model model){
ModelAndView mv = new ModelAndView("success");
return mv;
}
13.SessionAttribute
14.redirect和forward
返回值的多种用法:
1.相对路径
@RequestMapping("/tosuccess")
public String test(){
return "../success";
}
2.forward
2.1跳转到另一个方法
@RequestMapping("/tosuccess")
public String test(){
return "forward:/success";
}
2.2跳转到另一个页面
@RequestMapping("/tosuccess")
public String test(){
return "forward:/success.jsp";
}
3.redirect
3.1跳转到另一个方法
@RequestMapping("/tosuccess")
public String test(){
return "redirect:/success";
}
3.2跳转到另一个页面
@RequestMapping("/tosuccess")
public String test(){
return "redirect:/success.jsp";
}
15.view-controller
16.自定义视图解析器
1.自定义MyViewResolver,实现ViewResolver和order
并且将MyViewResolver加入容器
//实现Order为了自定义视图解析器的执行顺序
public class MyViewResolver implements ViewResolver, Ordered {
private Integer order;
public void setOrder(Integer order) {
this.order = order;
}
@Override
public int getOrder() {
return order;
}
@Override
public View resolveViewName(String s, Locale locale) throws Exception {
if(s.startsWith("mv:")){
return new MyViews();
}else {
return null;
}
}
}
//加入容器并且指定执行顺序
<bean class="view.MyViewResolver" id="myViewResolver">
<property name="order" value="1"></property>
</bean>
2.自定义views,实现View
public class MyViews implements View {
@Override
public String getContentType() {
return "text/html";
}
@Override
public void render(Map<String, ?> map, HttpServletRequest request, HttpServletResponse response) throws Exception {
httpServletResponse.setContentType("text/html");
httpServletResponse.getWriter().println("ssssssss。。。。。");
}
}
17.自定义类型转换器
1.编写一个实现Converter接口的converter
//泛型代表将string转换为user类型
public class Myconvter implements Converter<String,User> {
@Override
public User convert(String s) {
User user=new User();
if(s!=null&&s!=""){
//编写逻辑代码
}
return user;
}
}
2.配置conversionservice
<bean class="org.springframework.context.support.ConversionServiceFactoryBean" id="ConversionService">
<property name="converters">
//将自己的converter加入到conversionservice
<set>
<bean class="component.Myconvter"></bean>
</set>
</property>
</bean>
注意点:ConversionServiceFactoryBean这个是不带有格式化器的
推荐使用:org.springframework.format.support.FormattingConversionServiceFactoryBean
<bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean" id="ConversionService">
<property name="converters">
//将自己的converter加入到conversionservice
<set>
<bean class="component.Myconvter"></bean>
</set>
</property>
</bean>
3.更改默认的conversionservice
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
18.两个必备配置
<!--tomcat处理静态资源-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!--注解驱动模式,动态和静态资源都能访问-->
<mvc:annotation-driven></mvc:annotation-driven>
19.格式化器(自定义类型转换器存在时,看17注意点)
1.日期格式化
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birth;
2.数字格式化
@NumberFormat(pattern = "#,###.##")
private Integer salary;
20.数据校验
1.jar
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>7.0.0.Alpha3</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>7.0.0.Alpha3</version>
</dependency>
<dependency>
<groupId>com.fasterxml</groupId>
<artifactId>classmate</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.4.1.Final</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
2.为属性添加注解
@Length(min=3,max = 10)
private Integer id;
@Email
private Email email;
3.在封装对象时添加@valid注解,并且紧跟BindingResult封装校验结果
@RequestMapping("/jsr")
public String test02(@Valid User user, BindingResult result) {
boolean hasErrors = result.hasErrors();
if(hasErrors){
//校验有错误
return "success";
}else {
//校验没有错误
return "error";
}
}
4.表单回显错误,在每个属性后面跟<form:errors path="属性名"></form:errors>
<form action="/jsr" method="post">
<input type="text" name="id"><form:errors path="id"></form:errors>
<input type="text" name="salary"><form:errors path="salary"></form:errors>
<input type="text" name="email"><form:errors path="email"></form:errors>
<input type="text" name="birth"><form:errors path="birth"></form:errors>
<input type="submit" value="提交">
</form>
20.1JSR303注解一览
21.国际化和定制国际化错误消息
1.编写资源文件
资源文件中的key值
errors_en_US.properties:
Email=Email is not correct!
Birth=Birth is not correct
errors_zh_CN.properties:
Eamil=邮箱不对
Birth=生日不对
2.交给spring管理
<!--管理国际化文件-->
<bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource">
<property name="basename" value="errors"></property>
</bean>
3.细节
22.没有国际化需求可以直接指定message指定错误消息
@Length(min=3,max = 10,message = "长度必须在3-10之间")
private Integer id;
@Email(message = "邮箱格式不正确")
private Email email;
23.ajax与springMVC
1.@ResponseBody与@RequestBody
@ResponseBody:将返回的数据转化为json格式
@RequestBody:将json数据绑定到一个对象(字符串)上
@RequestMapping("/test")
public void test(@requestBody User user,@requestBody String pwd){
System.out.println(userName+" :"+pwd);
}
2.@httpEntity:获取所有的请求体
@requestHeader:获取某个请求头
@RequestMapping("/test")
public void test(@HttpEntity<String> str){
System.out.println(str);
}
3.responseEntity:发送请求体(内容+定制请求头)
@RequestMapping("/test")
public ResponseEntity<String> test(){
String body="success";
MultiValueMap<String,String> headers=new HttpHeaders();
headers.add("Set-cookie","hhhhhhh");
return new ResponseEntity<String>(body,headers, HttpStatus.OK);
}
24.单文件上传
1.jar
<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.4</version>
</dependency>
2.配置文件上传解析器
<!--配置文件上传解析器-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<property name="maxUploadSize" value="#{1024*1024*20}"></property>
<property name="resolveLazily" value="true"></property>
</bean>
3.编写controller和前端请求
@RequestMapping("/upload")
//通过MultipartFile获取file文件参数
public String test(@RequestParam("wenjian") MultipartFile file, Model model) throws IOException {
model.addAttribute("msg","文件上传成功");
//transferTo该方法表示需要保存的位置
file.transferTo(Paths.get("H:\\haha.docx"));
return "forward:/index.jsp";
}
//文件上传请求重要的是enctype="multipart/form-data"这个属性和值
<form action="upload" method="post" enctype="multipart/form-data">
文件:<input type="file" name="wenjian">
<input type="submit" value="文件上传">
</form>
25.多文件上传
3.编写controller和前端请求
@RequestMapping("/upload")
//将MultipartFile改为MultipartFile[]数组类型
public String test(@RequestParam("wenjian") MultipartFile[] files, Model model) throws IOException {
model.addAttribute("msg","文件上传成功");
//判断文件是否为空
for (MultipartFile file:files) {
if(!file.isEmpty()){
file.transferTo(Paths.get(new File("H://") + file.getOriginalFilename()));
}
}
return "forward:/index.jsp";
}
//多文件的name最好同名
<form action="upload" method="post" enctype="multipart/form-data">
文件1:<input type="file" name="wenjian">
文件2:<input type="file" name="wenjian">
文件3:<input type="file" name="wenjian">
文件4:<input type="file" name="wenjian">
<input type="submit" value="文件上传">
</form>
26.拦截器
1.实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
2.spring.xml配置
<!--配置拦截器-->
<mvc:interceptors>
<!--简单配置拦截器,默认拦截所有-->
<bean class="component.MyInterceptor" id="myInterceptor"></bean>
<!--详细配置拦截器-->
<mvc:interceptor>
<!--配置拦截路径-->
<mvc:mapping path="/test01"/>
<!--使用哪个拦截器-->
<bean class="component.MyInterceptor" id="myInterceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
3.多拦截器执行顺序
1.preHandle顺序执行
2.postHandle,afterCompletion逆序执行
3.只要preHandle的返回值为true,那么该拦截器的afterCompletion也必定执行
27.@ExceptionHandler异常处理
1.在类中单独处理
@ExceptionHandler(value = {Exception.class/*ArithmeticException.class,NullPointerException.class,*/})
public ModelAndView ex(Exception e){
ModelAndView mv = new ModelAndView();
mv.setViewName("myerror");
mv.addObject("e",e);
return mv;
}
2.编写异常处理类
@ControllerAdvice
public class MyAllExceptionHandler {
@ExceptionHandler(value = {Exception.class/*ArithmeticException.class,NullPointerException.class,*/})
public ModelAndView ex(Exception e){
ModelAndView mv = new ModelAndView();
mv.setViewName("myerror");
mv.addObject("e",e);
return mv;
}
}
匹配优先级:
本类优先,精确优先
28.@ResponseStatus异常处理(用于自定义异常)
1.有自定义异常类,自定义异常UserNotFunException
@ResponseStatus(reason = "用户被拒绝",value = HttpStatus.NOT_ACCEPTABLE)
public class UserNotFunException extends RuntimeException{
}
2.在方法中抛出自定义异常
@RequestMapping("/test02")
public void sss(){
throw new UserNotFunException();
}
@DefaultHandlerExceptionResolver用于springMVC自己的异常,如果没有
别的异常处理进行处理,就会自己进行处理。
29.springMVC运行流程