返回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>