(11).Spring集成SpringMVC

Spring集成SpringMVC

 

  1. 步骤一:copy jar包:org.springframework.web-3.1.0.RELEASE.jar     与    org.springframework.web.servlet-3.1.0.RELEASE.jar
  2. 步骤二:配置web.xml允许spring在web环境下使用(这个操作虽然肯能与集成无关,但必须要有)                                                                                         request   ->   Controller(IOC)   ->  业务层   ->  dao层                                                                                                                                               response   <-                                                                                                                                                                                                           表示层:jsp      控制层:Controller    业务层:Service    数据层:Mappper                                                                                                           使用什么技术可以使spring的web工厂可以随tomcat一起启动和关闭呢?jsp技术                                                                                                   SpringMVC:Jsp(V)+Servlet(C)+Service(M)                                                                                                                                                      jsp三大组件:servlet,过滤器filter,监听器Listener(1.监听ServletContext 2.监听Session 3.监听请求)                                                                监听器:实现ServletContextListener的接口,实现里面的方法,在web.xml中配置。tomcat在启动的时候会提醒MVC.                                        在SpringMVC中servlet与监听器都需要配置才可以使用                                                                                                                                          在web.xml配置文件中配置监听器:
        <!--加载Spring主配置文件-->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:main.xml</param-value>
        </context-param>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
    <!--注释:以监听器的形式加载Spring主配置文件-->

     

  3. 配置SpringMVC:                                                                                                                                                                                                             首先了解知名的mvc框架:struts/struts2.springMVC. .netMVC(webform嫡出,mvc庶出).                                                                                   前端控制器(前端拦截器):                                                                                                                                                                                   在web.xml配置servlet:
    <!--SpringMVC,WEB-INF/mvc-servlet.xml,web工厂继承主工厂-->
        <servlet>
            <servlet-name>mvc</servlet-name><!--这里的mvc会在WEB-INF创建一个为mvc-servlet.xml的配置文件-->
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>mvc</servlet-name>
            <url-pattern>/*</url-pattern>
        </servlet-mapping>

       此时web工厂与主工厂之间会有冲突?此时跟踪源码可以得出:这个web是main.xml的子工厂。这就是spring中两个工厂之间的关系。                然后在WEB-INF下创建一个mvc-servlet.xml的spring类型的xml文件。                                                                                                                mvc-servlet.xml:1.导入两个命名空间:context,mvc。

 

接下来以一个控制器为例来了解springMVC如何使用:(此时,与上次mybatis相比,只留下jsp,别的都不要了,关闭过滤器)

  1. 在web目录下创建controller.NewsController.(表示当访问localhost8888/hello时会跳转到ok.jsp)
    package com.web.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller                                //声明自己是控制器
    public class NewsController {
        @RequestMapping("/hello")            //此时表示拦截的是hello的请求或界面(www.localhost.8888/hello)
        public String hello(){
            return "ok";
        }
    
    }

    上面写了之后,需要让spring知道,需要让spring扫描一下,在mvc-servlet.xml文件中添加扫描,使spring承认控制器。

     <context:component-scan base-package="com.web.controller"/>

     此时遇见一个问题:就是在web.xml中设置mvc中,url-parten我们设置的是/*,那么代表所有都会拦截,此时我们可以仅设为/。可以试一下      到此:我们已经了解了一个小的例子,那么我们可以把servlet中的一个方法设置一个RequestMapping来解决。  

 Controller使用:

  1. 参数传递。      我们想传递两个参数:

    String nickname,String pwd                                                                                                                                                                                     在方法中设置参数:

    @Controller
    public class NewsController {
        @RequestMapping("/hello")
        public String hello(String nickname,String pwd){
            return "ok.jsp";
        }

    那么此时我们请求界面hello,可以设为http://localhost:8888/hello?nickname=admin&pwd=123                                                                               那么hello方法中会接收到这两个参数。如果参数过多,则使用对象类型参数。

  2. 对象类型参数
    @Controller
    public class NewsController {
        @RequestMapping("/hello")
        public String hello(Users user){
            return "ok.jsp";
        }

    此时我们的调试代码为:http://localhost:8888/hello?nickname=admin&pwd=123&type=2                                                                                        那么这三个值会自动传入一个user对象,里面会有这三个属性。

向页面发送数据:

  1. 我们想向页面返回值,我们可以声明一个集合。但是要求Map必须是方法的一个参数,可以是Map或Model类型
    @Controller
    public class NewsController {
        @RequestMapping("/hello")
        public String hello(Map model, Users user){
            model.put("user",user);//相当于request.setAttribute("user",user);
            return "ok.jsp";
        }

    在页面取值:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <h1>${user.nickname},${user.pwd},${user.type}</h1>
    </body>
    </html>

    此时我们的调试代码为:http://localhost:8888/hello?nickname=admin&pwd=123&type=2                                                                                        最终调试结果是ok.jsp页面显示,admin,123,2.

  2. 控制类的return可以直接返回页面会自动跳转。eg:return "ok.jsp";   重定向:eg: return "redirect:ok.jsp"     但是重定向无法访问我们要返回的Map中的参数。     关于重定向无法访问Map参数的解决办法:1.不用重定向。2.使用HttpSession session
    @Controller
    public class NewsController {
        @RequestMapping("/hello")
        public String hello(Map model, Users user , HttpSession sessin){
            //model.put("user",user);//request.setAttribute("user",user);
            sessin.setAttribute("user",user);
            return "redirect:ok.jsp";
        }

    当使用会话sessino实现的时候,就jsp页面不用改,因为${}表达式,本身就可以从session中获取。结果和Map之前是一样的。

spring输出各种数据信息:

  1. 返回字符串。 http://localhost:8888/show
    @RequestMapping("/show")
        @ResponseBody
        public String show(){
            return new Date().toLocaleString();//把时间转化为字符串
        }

    会返回当前的这个,是时间。                          2.可以返回一段html:

     @RequestMapping("/showHtml")
        @ResponseBody
        public String showHtml(){
            return "<fond style='color:red'>"+new Date().toLocaleString()+"<fond>";
        }

    此时就是把字体变为了红色

     http://localhost:8888/showHtml                                                                                                                                                                                 3.返回Json        :Json格式:var person={name:"张三",age:20}        var nums=[1,2,3,4]      

        @RequestMapping("/showJson")
        @ResponseBody
        public String showJson(){
            return "{\"time\":\""+new Date().toLocaleString()+"\"}";
        }

    此时在web界面接受为下面的方法二:其中eval();是动态执行语言。其中ajax.open中的url换成/showJson

                                                                                                                                  

  2. 使用script的ajax创建一个服务器数字时钟。创建一个timer.jsp。html代码如下:
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <title>Title</title>
    <script type="text/javascript">
        window.onload=function(){   //注册事件处理函,可以解决访问下面为执行为读到的参数,这里是time与下面span中的time
            function freshTimeFromServer(){
                var time = document.getElementById("time");
                // 通过javascript发送请求,获取服务器时间
                var ajax = new XMLHttpRequest();  // ajax对象
                ajax.open("get","/show",true);    // 设置请求的参数,(请求的方式,对应的控制器的方法的url,true代表是异步)
                ajax.onreadystatechange = function(xhr,e){ // 注册事件处理函数
                    // 服务器响应后进行处理,http响应码:2xx(200),3xx,4xx,5xx     ,表示接收到回旋镖
                    // 收到正常数据后     ajax.readyState == 4  表示收到的数据是正常的
                    if(ajax.status == 200 && ajax.readyState == 4){//ajax.status表示http的响应码,
    //方法一:下两行 var info = ajax.responseText; // 服务器返回的数据 time.innerHTML = info; // 量时间显示到span标签中 // json 方法二:下三行 是处理Json格式 /*var obj = {}; // "obj = {\"time\":\"2020-05-20\"}"; eval("obj = "+ajax.responseText);// {time:"2020-05-20"} time.innerHTML = obj.time;*/ // 1秒钟后再次执行 setTimeout(freshTimeFromServer,1000); } }; ajax.send();//表示扔出回旋镖 } freshTimeFromServer(); } </script> </head> <body> <h1>时钟:<span id="time"></span></h1> </body> </html>

    其中ajax.open("get","/show",true);里的/show是和上面是一样的,也可以换成/showHtml。适用于方法一。

 当请求出问题:有两个控制器,当两个控制器映射到同一个目录,即两个控制器中有相同的RequstMapping命名,如果有两个/show,则会报错。

解决办法:在控制器类前设置上级别,如下:

package com.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@RequestMapping("/users")
@Controller
public class UsersController {
    @ResponseBody
    @RequestMapping("/show")
    public String show(){
        return "ok";
    }
}

那么此时的访问路径则会由之前的localhost:8888/show转变为localhost:8888/users/show.

posted @ 2020-06-16 00:18  云山有相逢  阅读(230)  评论(0)    收藏  举报