SpringMVC

springmvc 源码

springmvc 流程图

 

Springmvc 三大组件(组成)部分?

  1. 处理器映射器,将请求路径映射到我们的适配器
  2. 处理器映射器,适配合适的处理器,传递参数,并接收执行结果
  3. 试图解析器,根据结果响应不同的页面

springmvc 笔记

服务器三层架构:表现层,业务层,持久层

springmvc属于表现层框架

mvc:

model 模型:javaBean

view 视图:jsp

controller 控制器:servlet

处理请求,转发

springmvc与struts2的区别

Springmvc的入口是Servlet ,Struts2的入口是Filter

springmvc的JSTL执行效率高,struts2的OGNL开发效率高

Maven创建项目时过慢,不下载插件方法

在new Module 时,添加键值对

key:archetypeCatalog     value:internal

笔记1

添加maven基本依赖

 <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   <!-- <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>-->
    <spring.version>5.0.2.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</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.0</version>
      <scope>provided</scope>
    </dependency>

  </dependencies>

web.xml配置,在项目启动时加载springmvc.xml


<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>dispatcherServlet</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>
    <load-on-startup>1</load-on-startup>  <!--加载顺序-->
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>   <!-- 拦截路径 -->
  </servlet-mapping>
</web-app>

springmvc.xml   

context:注解   beans:spring基本  mvc:springmvc基本

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       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
                            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.zxit"></context:component-scan>

    <!--视图解析器对象-->
    <!--根据执行方法的返回值,来找对应的方法-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>  <!--有返回,直接来到这个目录找-->
        <property name="suffix" value=".jsp"/> <!--来到这个目录,找jsp后缀-->
    </bean>

    <!--开启SpringMVC框架注解支持-->
    <mvc:annotation-driven/>

</beans>

#sayHello.java

//控制器
@Controller
public class HelloSprintMVC {

    //请求映射
    @RequestMapping("/sayHello")
    public String sayHello(){
        System.out.println("say Hello SpringMVC zx");
        return "success";
    }
}

如果想通过 return 访问 文件夹下的 jsp  ,  可以 return “page/aa.jsp"

笔记2   :请求

注解:

@Controller  控制器注解,默认单例

@RequestMapping    请求映射   用法:@RequestMapping(path="/sayHello")   该注解可以作用在类上或者方法上,如果在类上就是多级路径。
path = value ,当RequestMapping 里只有一个参数时,可以不写value。
method 请求方式:设定方法访问方式: @RequestMapping(path="/sayHello",method={RequestMethod.POST})
params 必须传入指定名称参数:@RequestMapping(path="/sayHello",params={"name"}),表示请求必须传入一个指定的name参数,如果没有,则不执行该方法。或者params={"name=haha"} 要求必须传入一个值为haha的name属性,没有则不执行方法。

传递请求参数 :

请求地址:http://localhost:8080/项目/dis?username=xx&userpass=xx

 @RequestMapping(value = "/dis")
    public String dis(String username,String userpass){
        System.out.println("有username,userpass的方法执行了");
        return "success";
    }

请求参数封装成实体 

userdata.jsp

<head>
    <title>用户信息-请求参数封装实体</title>
</head>
<body>
    <form action="UserData/save" method="get">
        学生姓名:<input type="text" name="studentName"/><br>
        学生年龄:<input type="text" name="studentAge"/><br>
        学生所属老师:<input type="text" name="studentTeacher.teacherName"/><br>
        学生所属老师年龄:<input type="text" name="studentTeacher.teacherAge"/><br>
        <input type="submit" value="保存"/><br>
    </form>
</body>

Student.java

public class Student {
    private String studentName;
    private String studentAge;
    private Teacher studentTeacher;
    
...get,set,toString方法
}

Teacher.java

public class Teacher {

    private String teacherName;
    private String teacherAge;
...get,set,toString方法
}

控制器类

@Controller
@RequestMapping(value = "/UserData")
public class UserDataSpringMVC {

    @RequestMapping(value = "/save")
    public String save(Student stu){
        System.out.println(stu);
        return "success";
    }
}

post请求中文参数乱码:利用拦截器格式化请求参数

  <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>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

获得原生Servlet对象

@Controller
@RequestMapping(value = "/UserData")
public class UserDataSpringMVC {

    @RequestMapping(value = "/select")
    public String select(HttpServletRequest request,HttpServletResponse response){
        System.out.println(request,response);
        return "success";
    }
}

注解

@Controller  控制层注解

@RequestMapping  请求地址映射注解 

@RequestMapping(value = "/save")
public String save(Student stu){
    System.out.println(stu);
    return "success";
}

@RequestParam 请求参数映射(传入name属性,赋值到username)

@RequestMapping(value = "/RequestParam")
public String RequestParam(@RequestParam(value = "name") String username){
    System.out.println("anno testReqeust run。。"+username);
    return "success";
}
<a href="anno/RequestParam?name=testname" >RequestParamTest</a>

@RequestParam(value="pages",required=false,defaultValue="xx") Integer page

// 如果传递了pages 参数,就用pages 参数,如果没有,则使用默认值xx

required=false 允许不传递该参数

defaultValue=xx  默认值

@RequestBody 用于获得请求体内容,可获得key/value内容

get方法不适用,因为get把参数都放在了地址里面

而post方法,会将参数做成key/value形式封装到请求里面

@RequestMapping(value = "/RequestBody")
public String RequestBody(@RequestBody String body){
    System.out.println("ReqeustBody "+body);
    return "success";
}
RequestBody 获取请求体(get请求不适用)
<form action="anno/RequestBody" method="post">
    用户名:<input type="text" name="username" ><br>
    密码:<input type="text" name="userpass" ><br>
    <input type="submit" value="提交">
</form>
Console: ReqeustBody username=22&userpass=22

@ResponseBody 响应处理,用在返回类型处

将json转成User对象,最后又将User对象转成json返回出去

public @ResponseBody User testAjax(@RequestBody User user ){
    return user;
}

@PathVaribale 请求参数占位符

restful风格:请求地址都一致,根据不同的请求方式来选择方法 (例:post,get,put)

@RequestMapping(value = "/PathVaribale/{sid}")
public String PathVariable(@PathVariable(name = "sid") String id ){
    System.out.println("PathVariable  "+id );
    return "success";
}

PathVariable的name属性需要与RequestMapping的value属性{}内容一致,形参id只是用来存放sid传过来内容的,命名意义不大

<a href="anno/PathVaribale/1">PathVariable</a>

@RequestHeader 获取请求头   

@RequestMapping(value = "/RequestHeader/{sid}")
public String RequestHeader(@RequestHeader(value = "Acccpt") String head ){
    System.out.println("RequestHeader  "+hear );
    return "success";
}
<a href="anno/RequestHeader">RequestHeader</a>

@CookieValue 获取当前会话的cookie,返回当前cookie值

@RequestMapping(value="/CookieValue")
public String cookieValue( @CookieValue(value="JSESSIONID") String cookieValue){
    System.out.pringln(cookieValue);
    return "success";
}
<a href="anno/cookieValue">CookieValue</a>

@ModelAttribute  模型参数 ,在执行请求前,必须提前执行的方法

该方法可以设置成和form提交类型一样的返回类型,可提前对提交数据校验

@ModelAttribute
public void befor(){
    System.out.println("当前请求前,提前执行的方法");
}

使用Model 调用request,执行如下操作后,就可以在jsp页面通过request获取user

@RequestMapping("/selectMethod")
public String select(Model model){
    System.out.pringln("查询数据库");
    User user = new User("姓名","性别");
    model.addAttribute("user",user);
    return "success";
}

笔记3:  响应

复习servlet

执行对应的方法后,根据返回值会来到springmvc.xml中找到jsp页面路径,打开对应的jsp

例如程序返回success,那么就会去/WEB-INF/pages/success.jsp。如果返回ok,则找ok.jsp

#springmvc.xml

 <!--视图解析器对象-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>  <!--有返回,直接来到这个目录找-->
        <property name="suffix" value=".jsp"/> <!--来到这个目录,找jsp后缀-->
</bean>

class : ModelAndView  跳转和视图类 详解

指定返回值与返回页面,作用与Model类加上return “success" 是一样,其实Model类底层就是调用ModelAndView

public ModelAndView testModelAndView(){
    //创建ModelAndView对象
    ModelAndView model = new ModelAndView();
    User user = new User("测试",22);
    
    //把user对象存储到mv对象中,也间接性的存到了request对象中
    model.addObject("user",user);
    //指定返回值(跳转页面参数)
    model.setViewName("success");
    
    return model;
}

设置springmvc拦截器不拦截js,css,image等资源,因为springmvc-->DispatcherServlet拦截器会拦截所有请求,

那么也包括了资源文件的url路径,要想避开资源文件,就在springmvc.xml中配置

    <!--前端控制器-->
    <!--设置静态资源不拦截-->
    <!--此处主要写图片文件夹啊,js,css等-->
    <mvc:resources mapping="/js/**" location="/js/**"/>

json字符串和JavaBean对象互相转换所需的jar包

     <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.0</version>
    </dependency>

按钮触发ajax事件,异步请求数据,返回并显示 

@ResponseBody 是指将返回数据封装成json

    /**
     * 模拟异步请求
     * 因为导入json转bean的jar包
     * 所以会自动的将json传过来的数据封装到user中
     * @param user
     */
    @RequestMapping(value = "/testAjax")
    public @ResponseBody User testAjax(@RequestBody User user){
        System.out.println("testAjax执行。。。1");
        System.out.println(user);
        return user;
    }
    <script src="https://code.jquery.com/jquery-2.2.1.min.js"></script>
    <script>
        $(function(){
            $("#testAjax").click(function () {
                //alert("hello btn");
                $.ajax({

                    url:"user/testAjax",     //请求地址
                    contentType:"application/json;charset=UTF-8",  //传输数据类型
                    data:'{"userName":"admin","userPass":"123"}',  //要传输的数据
                    dataType:"json",   //返回值类型
                    type:"post",     //请求方式
                    success:function(data){  //data表示服务端响应的数据
                        alert("hello btn");
                        alert(data.userName);
                        alert("单价"+data.userPrice);
                    }
                });
            });
        });
    </script>

<button id="testAjax">testAjax测试</button>

文件上传

1.form表单的enctype取值必须是:multipart/form-data

2.method属性的取值必须是Post

3.提供一个文件选择域<input type="file"/>

springmvc配置文件解析器(springmvc.xml)

<!--配置文件解析器,id名不可改,必须用这个-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="10485760"></property>
    </bean>

 上传方法参数中的MultiparFile 的变量名,必须与form表单的<input type="file"/>name名一致

 @RequestMapping(value = "/fileUpload")
    public String  fileUpload(HttpServletRequest request,MultipartFile fileUpload) throws IOException {
        String path = request.getSession().getServletContext().getRealPath("/upload"); //获取当前路径
        File file = new File(path);
        if(!file.exists()){
            file.mkdirs();
        }
        System.out.println(fileUpload.getOriginalFilename());   //上传文件名
        fileUpload.transferTo(new File(path,fileUpload.getOriginalFilename())); 
        System.out.println(path);
        return "success";
    }

    <form action="user/fileUpload" method="post" enctype="multipart/form-data">
        <input type="file" name="fileUpload"> <br><%--此处的id值,需要与对应的处理 MultipartFile 实例参数名一致--%>
        <input type="submit" value="上传">
    </form>

springmvc异常处理

用户自定义异常类,需要继承Exception

public class SysException extends Exception {

    private  String message;

    public SysException(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

异常处理类   实现 HandlerExceptionResolver 接口 ,判定捕获的异常是否为自己定义的异常,并且设定消息,返回到指定视图

**
 * 异常处理器
 */
public class SysExceptionResolver implements HandlerExceptionResolver {

    /**
     * 处理异常逻辑
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        SysException sysException = null;
        if(ex instanceof  SysException){
            sysException = (SysException)ex;
        }else {
            sysException = new SysException("未知异常。。。");
        }
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("errorMsg",sysException.getMessage());
        modelAndView.setViewName("error");   //返回到指定页面,显示异常信息
        return modelAndView;
    }
}

捕获异常,并抛出 

 @RequestMapping(value = "/select")
    public String userSelect() throws SysException {
     try {
         int i = 1/0;
     }catch (Exception e){
         throw new SysException("分母为zero");
     }

        return "success";
    }

拦截器的使用

配置拦截器,如果存在多个拦截器,可配置多个 <mvc:interceptor>

   <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/user/*"/>   <!--被拦截的请求-->
           <!-- <mvc:exclude-mapping path=""/>-->  <!--不被拦截的请求-->
            <bean class="com.zxit.interceptors.UserInterceptors"/>   <!-- 拦截器处理-->
        </mvc:interceptor>
    </mvc:interceptors>
package com.zxit.interceptors;
public class UserInterceptors implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器前置");  //可以在此处request,response
        return true;  //true 为放行,fase 为不放行
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("拦截器后置");//可以在此处request,response
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值