ssm-SpringMVC的使用

SpringMVC学习

---------------------基础

SpringMVC是一种基于Java实现的MVC设计模型的请求驱动类型的轻量级WEB框架。

1.三层架构和MVC模型
1.三层架构

咱们开发服务器端程序,一般都基于两种形式,一种C/S架构程序,一种B/S架构程序

使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构

三层架构

表现层:WEB层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型

业务层:处理公司具体的业务逻辑的

持久层:用来操作数据库的

2.MVC模型

MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。

Model:数据模型,JavaBean的类,用来进行数据封装。

View:指JSP、HTML用来展示数据给用户

Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等。

2.SpringMVC的入门

1.创建WEB工程,引入开发的jar包

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
      <spring.version>5.0.2.RELEASE</spring.version>//版本锁定
  </properties>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <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>

2.配置核心的控制器(配置DispatcherServlet)

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <!-- SpringMVC的核心控制器 -->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 配置Servlet的初始化参数,读取springmvc的配置文件,创建spring容器 -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!-- 配置servlet启动时加载对象 -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <!--设置拦截消息  /:表示所有都拦截-->
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

3.编写springMVC配置文件

<!--配置spring要扫描的包-->
    <context:component-scan base-package="com.itheima"/>

    <!--配置视图解析器   解析springMapping返回的路径-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--处理器映射器,处理适配器,视图解析器称为springMVC三大组件-->
    <!-- 配置spring开启注解mvc的支持-->
    <!--配置这个就自动加载处理器映射器,处理适配器-->
    <mvc:annotation-driven></mvc:annotation-driven>
</beans>

4.编写index.jsp和HelloController控制器类

<a href="hello">入门程序</a>
@Controller
public class HelloController {
    /*入门案例*/
    @RequestMapping(path = "/hello")
    public String hello(){
        System.out.println("hello方法执行了");
        return "success";
    }

5.在WEB-INF下建pages/success.jsp的成功页面

<h3>入门成功</h3>
3.环境搭建
1.入门案例的流程
  1. 当启动Tomcat服务器的时候,因为配置了load-on-startup标签,所以会创建DispatcherServlet对象, 就会加载springmvc.xml配置文件
  2. 开启了注解扫描,那么HelloController对象就会被创建
  3. 从index.jsp发送请求,请求会先到达DispatcherServlet核心控制器,根据配置@RequestMapping注解 找到执行的具体方法
  4. 根据执行方法的返回值,再根据配置的视图解析器,去指定的目录下查找指定名称的JSP文件
  5. Tomcat服务器渲染页面,做出响应

在这里插入图片描述

详细分析
在这里插入图片描述

2.的组件分析
  1. 前端控制器(DispatcherServlet)
  2. 处理器映射器(HandlerMapping)
  3. 处理器(Handler)
  4. 处理器适配器(HandlAdapter)
  5. 视图解析器(View Resolver)
  6. 视图(View)
4. RequestMapping注解
  1. RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系

  2. RequestMapping注解可以作用在方法和类上

    作用在类上:第一级的访问目录

    作用在方法上:第二级的访问目录

    细节:路径可以不编写 / 表示应用的根目录开始

    细节:${ pageContext.request.contextPath }也可以省略不写,但是路径上不能写 /

  3. RequestMapping的属性

    path 指定请求路径的url

    value value属性和path属性是一样的

    mthod 指定该方法的请求方式

    params 指定限制请求参数的条件

    headers 发送的请求中必须包含的请求头

5. 请求参数的绑定

1.请求参数的绑定说明
1.绑定机制
表单提交的数据都是k=v格式的 username=haha&password=123
SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的
要求:提交表单的name和参数的名称是相同的
2.支持的数据类型
基本数据类型和字符串类型
实体类型(JavaBean)
集合数据类型(List、map集合等)

2.基本数据类型和字符串类型
提交表单的name和参数的名称是相同的
区分大小写

3.实体类型(JavaBean)
提交表单的name和JavaBean中的属性名称需要一致
如果一个JavaBean类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性 例
address.name
4.给集合属性数据封装
JSP页面编写方式:list[0].属性

6. 自定义类型转换器

1.表单提交的任何数据类型全部都是字符串类型,但是后台定义Integer类型,数据也可以封装上,说明 Spring框架内部会默认进行数据类型转换。

2.如果想自定义数据类型转换,可以实现Converter的接口

public class StringToDateConverter implements Converter<String,Date>{
    @Override
    public Date convert(String source) {
         if(source==null){
             throw new RuntimeException("请输入日期");
         }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            // 把字符串转换日期
            return df.parse(source);
        } catch (Exception e) {
            throw new RuntimeException("数据类型转换出现错误");
        }
    }
}

3.注册自定义类型转换器,在springmvc.xml配置文件中编写配置

<!--配置自定义类型转换器-->
    <bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.itheima.utils.StringToDateConverter"/>
            </set>
        </property>
    </bean>
    <!--处理器映射器,处理适配器,视图解析器称为springMVC三大组件-->
    <!-- 配置spring开启注解mvc的支持-->
    <!--配置这个就自动加载处理器映射器,处理适配器-->
    <mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>
7.常用的注解
RequestParam注解

作用:把请求中的指定名称的参数传递给控制器(Controller)中的形参赋值

  1. value:请求参数中的名称

  2. required:请求参数中是否必须提供此参数,默认值是true,必须提供

    @RequestMapping(path="/hello")
    public String sayHello(@RequestParam(value="username",required=false)String name) {
    System.out.println("aaaa");
    System.out.println(name);
    return "success";
    }
    
RequestBody注解
  1. 作用:用于获取请求体的内容(注意:get方法不可以)

  2. 属性 1. required:是否必须有请求体,默认值是true

    @RequestMapping(path="/hello")
    public String sayHello(@RequestBody String body) {
    System.out.println("aaaa");
    System.out.println(body);
    return "success";
    }
    
PathVariable注解
  1. 作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符

  2. 属性 value:指定url中的占位符名称

  3. Restful风格的URL

1.请求路径一样,可以根据不同的请求方式去执行后台的不同方法

2.restful风格的URL优点 

​ 结构清晰

​ 符合标准

​ 易于理解

​ 扩展方便

@RequestMapping(path="/hello/{id}")
public String sayHello(@PathVariable(value="id") String id) {
System.out.println(id);
return "success";
}
RequestHeader注解
  1. 作用:获取指定请求头的值

  2. 属性 value:请求头的名称

    @RequestMapping(path="/hello")
    public String sayHello(@RequestHeader(value="Accept") String header) {
    System.out.println(header);
    return "success";
    }
    
CookieValue注解
  1. 作用:用于获取指定cookie的名称的值

  2. 属性 value:cookie的名称

    @RequestMapping(path="/hello")
    public String sayHello(@CookieValue(value="JSESSIONID") String cookieValue) {
    System.out.println(cookieValue);
    return "success";
    }
    
ModelAttribute注解

1.作用

​ 1.出现在方法上:表示当前方法会在控制器方法执行前线执行。

​ 2.出现在参数上:获取指定的数据给参数赋值。

2.应用场景

​ 当提交表单数据不是完整的实体数据时,保证没有提交的字段使用数据库原来的数据。

3.具体的代码

 //@ModelAttribute:1.在执行操作之前执行,有返回值,且把那个user返回到当前user了
                       //2.在执行操作之前执行,无返回值,在当前方法属性配置如下也能获取
    @RequestMapping(value="/testModelAttribute")
    public String testModelAttribute(@ModelAttribute("aaa") User user){
        System.out.println("执行了...");
        System.out.println(user);
        return "success";
    }
    @ModelAttribute
    public void getUser(Map<String,User> map){
        User user = new User();
        user.setUname("haha");
        user.setAge(13);
        user.setDate(new Date());
        map.put("aaa",user);
    }
//    @ModelAttribute
//    public User getUser(){
//        User user = new User();
//        user.setUname("haha");
//        user.setAge(13);
//        user.setDate(new Date());
//        return user;
//    }
SessionAttributes注解
  1. 作用:用于多次执行控制器方法间的参数共享 (将指定属性存入session域中)

  2. 属性 value:指定存入属性的名称

@Controller
@RequestMapping("/anno")
@SessionAttributes(value={"lqd"})   // 把msg=美美存入到session域对中
//先在类上写@SessionAttributes注解并根据存入request中的内容再转存入session域中才能取
public class AnnoController {
@RequestMapping(value="/saveSessionAttributes")
    public String saveSessionAttributes(Model model){
        // 底层会存储到request域对象中
        model.addAttribute("lqd","刘乾东");
        model.addAttribute("mmd","美美的");
        return "success";
    }

    @RequestMapping(value="/getSessionAttributes")
    public String getSessionAttributes(ModelMap modelMap){
        //根据名称获取session域的对象的值
        String naem = (String)modelMap.get("lqd");
        System.out.println(naem);
        return "success";
    }

    @RequestMapping(value="/deleteSessionAttributes")
    public String deleteSessionAttributes(SessionStatus sessionStatus){
        //清除session域
        sessionStatus.setComplete();
        return "success";
    }
}

--------------------使用

1.数据响应和结果视图
1.请求转发.重定向
//无返回值请求页面
    @RequestMapping("/testVoid")
    public void testVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("执行了");
        //请求转发
//        request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
//        return ;
        //重定向
//        response.sendRedirect(request.getContextPath()+"/index.jsp");
//        return ;
        //直接在浏览器响应
        //设置解决中文乱码
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().print("你好");
        return;
    }
2.ModelAndView.跳转
@RequestMapping("/testModelAndView")
    public ModelAndView testModelAndView(){
        // 创建ModelAndView对象
        ModelAndView mv = new ModelAndView();
        System.out.println("testModelAndView方法执行了...");
        // 模拟从数据库中查询出User对象
        User user = new User();
        user.setUsername("小凤");
        user.setPassword("456");
        user.setAge(30);
        // 把user对象存储到mv对象中,底层也是user对象存入到request对象
        mv.addObject("user",user);
        // 跳转到哪个页面
        mv.setViewName("success");
        return mv;
    }
3.关键字方式转发或者重定向
@RequestMapping("/testForwardOrRedirect")
    public String testForwardOrRedirect(){
        System.out.println("testForwardOrRedirect法执行了...");
        //请求转发
        return "forward:/WEB-INF/pages/success.jsp";
        //重定向
//        return "redirect:/index.jsp";
    }
4.模拟异步请求响应

注:如果web.xml配置了请求全部拦截,需在springmvc.xml文件配置忽略静态资源拦截

jsp代码

<script src="js/jquery-1.9.1.js"></script>
    <script>
        // 页面加载,绑定单击事件
        $(function(){
            $("#btn").click(function(){
                // alert("hello btn");
                // 发送ajax请求
                $.ajax({
                    // 编写json格式,设置属性和值
                    url:"user/testAjax",
                    contentType:"application/json;charset=UTF-8",
                    data:'{"username":"hehe","password":"123","age":30}',
                    dataType:"json",
                    type:"post",
                    success:function(data){
                        // data服务器端响应的json的数据,进行解析
                        alert(data);
                        alert(data.username);
                        alert(data.password);
                        alert(data.age);
                    }});}); });
    </script>
</head>
<body>
<button id="btn">发送ajax请求</button> <br>

java代码

@RequestMapping("/testAjax")
    public @ResponseBody User testAjax(@RequestBody User user){
        System.out.println("testAjax方法执行了...");
        // 客户端发送ajax的请求,传的是json字符串,后端把json字符串封装到user对象中
        System.out.println(user);
        // 做响应,模拟查询数据库
        user.setUsername("haha");
        user.setAge(40);
        // 做响应
        return user;
    }
2.文件上传
<body>
<%--原本的方式--%>
<form action="user/upload1" method="post" enctype="multipart/form-data">
    选择文件:<input type="file" name="upload"/><br>//文件上传框
    上传文件:<input type="submit" value="点击上传"/><br>
</form><br>

<%--springMVC的方式上传文件--%>
<form action="user/upload2" method="post" enctype="multipart/form-data">
    选择文件:<input type="file" name="upload"/><br>
    上传文件:<input type="submit" value="点击上传"/><br>
</form><br>

<%--跨服务器上传文件--%>
<form action="user/upload3" method="post" enctype="multipart/form-data">
    选择文件:<input type="file" name="upload"/><br>
    上传文件:<input type="submit" value="点击上传"/><br>
</form><br>
</body>
1.原始方式
@RequestMapping("/upload1")
    public String upload1(HttpServletRequest request) throws Exception {
        System.out.println("文件上传成功了");
        String path = request.getSession().getServletContext().getRealPath("/uploads");
        File file = new File(path);
        if (!file.exists()){
            file.mkdir();
        }
        //解析request对象,获取上传文件项
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        //解析request
        List<FileItem> items = upload.parseRequest(request);
        for (FileItem item : items) {
            if (item.isFormField()){
                //判断是否为普通表单项
            }else {
                //说明上传文件项
                //获取上传文件的名称
                String filename = item.getName();
                //把文件的名称设置唯一值
                String uuid = UUID.randomUUID().toString();
                filename = uuid+"-"+filename;
                //完成文件上传
                item.write(new File(path,filename));
                //清除缓存
                item.delete();
            }
        }
        return "success";
2.springMVC方式

注:需配置springMVC的文件解析器

<!--配置文件解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--设置上传文件大小限制-->
        <property name="maxUploadSize" value="11111111"/>
    </bean>
@RequestMapping("/upload2")
    public String upload1(HttpServletRequest request, MultipartFile upload) throws Exception {
        System.out.println("文件上传成功了");
        String path = request.getSession().getServletContext().getRealPath("/uploads");
        File file = new File(path);
        if (!file.exists()){
            file.mkdir();
        }
                //说明上传文件项
                //获取上传文件的名称
                String filename = upload.getOriginalFilename();
                //把文件的名称设置唯一值
                String uuid = UUID.randomUUID().toString();
                filename = uuid+"-"+filename;
                //完成文件上传
                upload.transferTo(new File(path,filename));
        return "success";
3.跨服务器文件上传

注:跨服务器文件上传需在tomcat安装目录的web.xml文件添加如下代码(因为默认是读访问)

<servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>readonly</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
</servlet>
@RequestMapping("/upload3")
    public String upload3(MultipartFile upload) throws Exception {
        System.out.println("跨服务器文件上传...");
        // 定义上传文件服务器路径
        String path = "http://localhost:9090/uploads/";
        // 说明上传文件项
        // 获取上传文件的名称
        String filename = upload.getOriginalFilename();
        // 把文件的名称设置唯一值,uuid
        String uuid = UUID.randomUUID().toString().replace("-", "");
        filename = uuid+"_"+filename;
        // 创建客户端的对象
        Client client = Client.create();
        // 和图片服务器进行连接
        WebResource webResource = client.resource(path + filename);
        // 上传文件
        webResource.put(upload.getBytes());
        return "success";
    }
3.异常界面处理

1.编写异常处理器类 需实现HandlerExceptionResolver

public class SysExceptionResolver implements HandlerExceptionResolver{
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        // 获取到异常对象
        SysException e = null;
        if(ex instanceof SysException){
            e = (SysException)ex;
        }else{
            e = new SysException("系统正在维护....");
        }
        // 创建ModelAndView对象
        ModelAndView mv = new ModelAndView();
        mv.addObject("errorMsg",e.getMessage());
        mv.setViewName("error");
        return mv;
    }
}

2.配置文件配置异常处理器

<!--配置异常处理器--><bean id="sysExceptionResolver" class="com.itheima.exception.SysExceptionResolver"/>

3.当捕获到异常会进入异常处理器中

4.可以在异常处理类中处理异常

4.springMVC拦截器
1.概念
  1. SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。

  2. 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链中的拦截器会按着定义的顺序执行。

  3. 拦截器和过滤器的功能比较类似,有区别

​ 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。

​ 拦截器是SpringMVC框架独有的。

​ 过滤器配置了/*,可以拦截任何资源。

​ 拦截器只会对控制器中的方法进行拦截。

​ 拦截器也是AOP思想的一种实现方式

​ 想要自定义拦截器,需要实现HandlerInterceptor接口。

2.配置拦截器

1.编写拦截器类

public class MyInterceptor implements HandlerInterceptor {

    //预处理,controller方法执行前
    //return true 放行,执行下一个拦截器,如果没有,执行controller中的方法
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器先执行11111111111");
        // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
        return true;
    }

    //后处理方法,controller方法执行后,success.jsp执行之前
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor1执行了...后1111");
        // request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
    }

    //success.jsp页面执行后,该方法会执行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor1执行了...最后1111");
    }
}

2.配置

<!--配置拦截器-->
    <mvc:interceptors>
    <!--配置拦截器-->
    <mvc:interceptor>
        <!--要拦截的具体的方法-->
        <mvc:mapping path="/user/*"/>
        <!--不要拦截的方法
        <mvc:exclude-mapping path=""/>
        -->
        <!--配置拦截器对象-->
        <bean class="com.itheima.interceptor.MyInterceptor" />
    </mvc:interceptor>
    </mvc:interceptors>

tem.out.println(“MyInterceptor1执行了…后1111”);
// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
}

//success.jsp页面执行后,该方法会执行
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    System.out.println("MyInterceptor1执行了...最后1111");
}

}


2.配置

~~~xml
<!--配置拦截器-->
    <mvc:interceptors>
    <!--配置拦截器-->
    <mvc:interceptor>
        <!--要拦截的具体的方法-->
        <mvc:mapping path="/user/*"/>
        <!--不要拦截的方法
        <mvc:exclude-mapping path=""/>
        -->
        <!--配置拦截器对象-->
        <bean class="com.itheima.interceptor.MyInterceptor" />
    </mvc:interceptor>
    </mvc:interceptors>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值