返回ModelAndView
- 以forword转发的方式,有数据和视图
 
返回String
- 处理器方法返回字符串可以指定逻辑视图,通过视图解析器解析可以将其转换成物理视图地址
 - 必须要视图解析器在springmvc.xml下配置
 - 以forword的转发方式
 
  @RequestMapping("string.do")
    public String stringTest(HttpServletRequest request){
        request.setAttribute("msg", "haha");
        request.setAttribute("fun", "haha");
        return "show";
    }
- 如果使用完整路径,就不能使用视图解析器了
 
 @RequestMapping("string.do")
    public String stringTest(HttpServletRequest request){
        request.setAttribute("msg", "haha");
        request.setAttribute("fun", "haha");
        return "/WEB-INF/view/show.jsp";
    }
void:不能显示数据,也不能表示视图
- 在处理ajax的时候,可以使用void返回值。通过HttpServletResponse输出数据。响应ajax请求。
 - ajax请求服务器返回的就是数据,和视图无关。
 - jackson 依赖
 
 <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-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
- jquery请求ajax并传入数据
 
     $(function () {
            $("#btn").click(function () {
                    $.ajax({
                        url: "void.do",
                        data: {
                            name : "zhangsan",
                            age : 20
                        },
                        type: "post",
                        dataType: "json",
                        success : function (res) {
                            alert("name:" + res.name + "\n"+ "age:" + res.age);
                        }
                    })
                }
            )
        })
- java响应ajax返回json数据
 
通过手工实现转json有很多重复,所以json可以交给框架做
  @RequestMapping("void.do")
    public void voidTest(HttpServletResponse resp, String name, Integer age) {
        Student student = new Student();
        student.setAge(age);
        student.setName(name);
        String json = "";
        // 把结果转换为json格式数据
        if(student != null){
            ObjectMapper mapper = new ObjectMapper();
            try{
                json =  mapper.writeValueAsString(student);
                // 响应ajax请求, 返回json数据
                resp.setContentType("application/json;charset=utf-8");
                PrintWriter writer = resp.getWriter();
                writer.println(json);
                writer.flush();
                writer.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
返回值Object (返回值是一个对象)
- 对象有属性,所以Object只返回数据,和视图无关。
 - 现在做ajax,主要使用json的数据格式。实现步骤:
 
- 加入json库的依赖, springmvc默认使用的jackson
 - 在springmvc配置文件中加入<mvc:annotation-driven>注解驱动
 - 在方法上面加ResponseBody():其实是将java对象转为json格式的数据。
 
mvc:annotation-driven的作用
Spring 3.0.x中使用了mvc:annotation-driven后,默认会帮我们注册默认处理请求,参数和返回值的类,其中最主要的两个类:DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter ,分别为HandlerMapping的实现类和HandlerAdapter的实现类,从3.1.x版本开始对应实现类改为了RequestMappingHandlerMapping和RequestMappingHandlerAdapter。HandlerMapping的实现类的作用
实现类RequestMappingHandlerMapping,它会处理@RequestMapping 注解,并将其注册到请求映射表中。HandlerAdapter的实现类的作用
实现类RequestMappingHandlerAdapter,则是处理请求的适配器,确定调用哪个类的哪个方法,并且构造方法参数,返回值。
当配置了mvc:annotation-driven/后,Spring就知道了我们启用注解驱动。然后Spring通过context:component-scan/标签的配置,会自动为我们将扫描到的@Component,@Controller,@Service,@Repository等注解标记的组件注册到工厂中,来处理我们的请求。
springmvc处理器方法返回Object,可以转为json输出浏览器,响应ajax的内部原理
<mvc:annotation-driven> 注解驱动实现的功能是 完成java对象到json,xml,text,二进制等数据格式的转换。
HttpMessageConveter接口:消息转换器。
功能:定义了java转为json.xml等数据格式的方法。这个接口有很多的实现类。
这些类完成了java对象到json,xml,二进制的转换。会创建7个类,其中包括:MappingJackson2HttpMessageConverter(使用jackson工具库中的ObjectMapper转为json字符串)
下面两个方法是控制器类把结果输出给浏览器使用的。
boolean canRead(Class<?> var1, @Nullable MediaType var2); boolean canWrite(Class<?> var1, @Nullable MediaType var2);
1.canWrite:作用检查处理器方法的返回值,能不能转为var2表示的数据格式。如果能转为json就返回true。
2.write:把处理器方法的返回值对象调用jackson中的ObjectMapper转为json字符串。
- @ResponseBody注解
放在处理器方法上面,通过HttpServletResponse输出数据,响应ajax请求的。 - java实现
 
返回对象Student类型,
1.调用框架中的ArrayList<HttpMessageConverter>中每个类的canWrite()方法,检查那个HttpMessageConverter接口实现类型处理Student类型的数据---- MappingJackson2HttpMessage
2.框架会调用实现类的MappingJackson2HttpMessageConverter的write方法
把李四同学的student对象转为json,调用Jackson的OjectMapper实现转为json。
3.框架会调@ResponseBody把2的结果数据输出到浏览器,ajax请求处理完成。
    @RequestMapping(value = "/void.do")
    @ResponseBody
    public Object voidTest(String name, int age){
//        调用service,获取请求结果,Student为结果对象
        Student student = new Student();
        student.setName(name);
        student.setAge(age);
// 返回json对象
        return student;
    }
返回JsonList
很多情况我们返回是很多个对象,所以我们要返回个
- 也可以返回Map<key, value>对象
 
    @RequestMapping("/void.do")
    @ResponseBody
    public Object objectTest(String name, int age){
        Student student = new Student();
        student.setName(name);
        student.setAge(age);
        List<Object> list = new ArrayList<>();
        list.add(student);
        return list;
    }
  
- js
 
    @RequestMapping("/void.do")
    @ResponseBody
    public List<Object> objectTest(String name, int age){
        Student student = new Student();
        student.setName(name);
        student.setAge(age);
        List<Object> list = new ArrayList<>();
        list.add(student);
        return list;
    }
 
- 返回字符串
 
加上@ResponseBody时 返回字符串。
    @RequestMapping(value = "/void.do",produces = "text/plain;charset=utf-8")
    @ResponseBody
    public String stringTest2(String name, int age){
        return "haha 1231";
    }
静态资源相关
- url-pattern
 
用/的弊端
<url-pattern>/</url-pattern>不能访问静态资源。
*.do可以访问静态资源
tomcat本身可以处理静态资源,因为tomcat的web.xml文件中有一个servlet名称是default, 在服务器启动时创建的。而使用/会替代defaultServlet,导致所有资源都给了DispatcherServlet处理,默认情况下DispatcherServlet没有处理静态资源的能力。
1.处理静态资源
2.处理未映射到其他servlet的请求
- 解决使用/ 无法处理静态资源问题
 
在springmvc中加入
<mvc:default-servlet-handler/>
框架会创建控制器对象 defaultServletHandler,最后交给tomcat处理
它和 @RequestMapping有冲突 ,需要加入<mvc:annotation-driven/>解决问题
- 第二种访问静态资源处理方式
 
加入<mvc:resources> 框架创建ResourceHttpRequestHandler,框架自己处理不交给tomcat。
mapping属性:访问静态资源的uri地址,可以使用通配符/*
例如:<mvc:resources mapping="images/" location="/images/"/> image/ 可以标识多级目录或单级
可以写多个
- 解决和RequestMapping还是有冲突 加注解驱动解决
 
    <mvc:resources mapping="/images/**" location="/images/"/>
    <mvc:resources mapping="/js/**" location="/js/"/>
    <mvc:resources mapping="/html/**" location="/html/"/>
- 一条配置处理所有资源
 
把所有静态资源都放到static目录下
  <mvc:resources mapping="/static/**" location="/static/"/>
路径
在jsp,html中使用的地址,都是在前端页面中的地址,都是相对地址
地址分类:
- 绝对地址, 带有协议名称的是绝对地址, http://www.baidu.com , ftp://202.122.23.1
 - 相对地址, 没有协议开头的,例如 user/some.do , /user/some.do
参考地址+ 相对地址才能指定资源。 - 参考地址,在页面中访问地址不加"/"访问的是http://localhost:8080/ch06-path(项目地址) , 加/访问的参考地址是http://localhost:8080
 
- 解决方案 在jsp中加入${pageContext.request.contextPath}url 就可以解决。
 
没/都是使用base中的地址
<head>
<base href="http://www.w3school.com.cn/i/" />
<base target="_blank" />
</head>
<body>
<img src="eg_smile.gif" />
<a href="http://www.w3school.com.cn">W3School</a>
</body>


