spring 处理json 参考:
Spring 3 MVC And JSON Example
注:
在方法或者返回值上面加上@ResponseBody,当spring发现下面的三个条件都满足之后,就会自动进行json数据转换(通过jackson):
1. classpath下有jackson依赖包
2. 配置文件中包含 <mvc:annotation-driven /> 配置
3. 方法或者方法返回值前有 @ResponseBody 注解
用maven下载依赖jar
maven依赖(目前最新稳定版本3.2.5)jackson用于处理json:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tch</groupId> <artifactId>springmvc</artifactId> <packaging>war</packaging> <version>1.0</version> <name>springmvc Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit-version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring-version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hiberante-version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql-version}</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>${jackson-version}</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j-version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j-version}</version> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>${javassist-version}</version> </dependency> </dependencies> <properties> <junit-version>3.8.1</junit-version> <spring-version>3.2.6.RELEASE</spring-version> <hiberante-version>3.6.10.Final</hiberante-version> <javassist-version>3.12.0.GA</javassist-version> <mysql-version>5.1.28</mysql-version> <jackson-version>1.9.10</jackson-version> <log4j-version>1.2.17</log4j-version> <slf4j-version>1.7.5</slf4j-version> </properties> <build> <finalName>springmvc</finalName> </build> </project>
和struts2一样,首先需要在web.xml中配置核心控制器(Controller),只不过struts2是一个filter,spring mvc的控制器则是一个servlet: DispatcherServlet :
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- 配置spring mvc的核心控制器DispatcherServlet --> <servlet> <servlet-name>spring_mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 默认情况下,spring mvc配置文件在/WEB-INF/下,servlet名字-servlet.xml(这里是spring_mvc-servlet.xml) --> <init-param> <!-- 指定spring mvc配置文件位置 --> <param-name>contextConfigLocation</param-name> <param-value>classpath*:dispatcher-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring_mvc</servlet-name> <url-pattern>/mvc/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
然后就是spring mvc的配置文件,就是上面的:classpath下面的 dispatcher-servlet.xml :(包含了spring mvc 拦截器,以及spring的其它配置)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <!-- 启动扫描component功能 --> <context:component-scan base-package="com.tch.springmvc" /> <!-- viewResolver --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/" /> <property name="suffix" value=".jsp" /> </bean> <mvc:annotation-driven /> <!-- 拦截器 --> <mvc:interceptors> <!-- 这里配置的拦截器相当于全局拦截器,只要有响应的后端处理器,就会经过该拦截器 --> <bean class="com.tch.springmvc.interceptor.MyInteceptor" /> <mvc:interceptor> <!-- 只拦截匹配的路径 --> <mvc:mapping path="/namespace/*"/> <bean class="com.tch.springmvc.interceptor.MyInteceptor2" /> </mvc:interceptor> </mvc:interceptors> <!-- 启动注解实物配置功能 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/test"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> <!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <!--读取数据库配置文件 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mappingLocations"> <list> <value>classpath*:com/tch/springmvc/entity/*.hbm.xml</value> </list> </property> <property name="packagesToScan"> <list> <!-- <value>com.tch.test.ssh.entity.annotation</value> --> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> </bean> </beans>
然后就是后端控制器了:
package com.tch.springmvc.web.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.tch.springmvc.bean.Shop;
@Scope("prototype") //这样可以让控制器是原型模式,而不是单例
@Controller("helloWorld") //表示这个类是后端控制器
@RequestMapping("/namespace") //在类上面加上@RequestMapping,则该类下面的方法的访问路径都需要加上该前缀,类似struts2的namespace
public class HelloWorldController {
public HelloWorldController() {
System.err.println("create");
}
/**
* Created on: 2013-12-9
* <p>Discription: 最简单的方法,访问路径:http://localhost:8080/xxx/mvc/namespace/helloWorld</p>
* @return String
*/
@RequestMapping("/helloWorld")
public String helloWorld(Model model) {
model.addAttribute("message", "Hello World!");
return "index";
//return "forward:/js/login.js"; //服务端跳转
//return "redirect:/js/login.js"; //客户端跳转
}
/**
* Created on: 2013-12-9
* <p>Discription: 返回json数据(@ResponseBody可以放在方法上面,如json方法;或者在返回值前,像json2一样)
* 访问:http://localhost:8080/xxx/mvc/namespace/json</p>
* @return Object
*/
@RequestMapping("/json")
@ResponseBody
public Object json(){
List<String> list=new ArrayList<String>();
list.add("电视");
list.add("洗衣机");
list.add("冰箱");
list.add("电脑");
list.add("汽车");
list.add("空调");
list.add("自行车");
list.add("饮水机");
list.add("热水器");
return list;
}
/**
* Created on: 2013-12-9
* <p>Discription: 返回json数据(@ResponseBody可以放在方法上面,如json方法;或者在返回值前,像json2一样),
* 访问:http://localhost:8080/xxx/mvc/namespace/json2</p>
* @return Shop
*/
@RequestMapping("/json2")
public @ResponseBody Shop json2(){
Shop shop = new Shop();
shop.setName("爽歪歪");
shop.setStaffName(new String[]{"张三", "李四", "王五"});
return shop;
}
/**
* Created on: 2013-12-9
* <p>Discription: 使用rest风格来接收参数,如http://localhost:8080/xxx/mvc/namespace/rest/dreamoftch,则参数中的username的值就是dreamoftch</p>
* @return String
*/
@RequestMapping("/rest/{username}")
public String rest(Model model,@PathVariable("username") String username) {
model.addAttribute("message", "Hello "+username+" !");
return "index";
}
/**
* Created on: 2013-12-9
* <p>Discription: 使用rest风格来接收参数<br>如http://localhost:8080/xxx/mvc/namespace/json3,则参数中的myParam的值就是json3<br>
* 这个例子也说明了路径的匹配是先精确匹配,如果是http://localhost:8080/xxx/mvc/namespace/json,或者
* http://localhost:8080/xxx/mvc/namespace/json2则会分别映射到json和json2方法,但http://localhost:8080/xxx/mvc/namespace/json3
* 则没有精确映射的方法,所以就进到这里了,myParam的值就是json3</p>
* @return String
*/
@RequestMapping("{myParam}")
public String rest2(Model model,@PathVariable("myParam") String myParam) {
model.addAttribute("message", "Hello "+myParam+" !");
return "index";
}
/**
* Created on: 2013-12-9
* <p>Discription: 使用rest风格来接收参数,如http://localhost:8080/xxx/mvc/namespace/rest/aaa/bbb,则参数中的username的值就是aaa,password是bbb</p>
* @return String
*/
@RequestMapping("rest/{username}/{password}")
public String rest3(Model model,@PathVariable("username") String username,@PathVariable("password") String password) {
System.out.println("rest3");
model.addAttribute("message", "Hello "+username+" , your password is "+password+" !");
return "index";
}
/**
* Created on: 2013-12-9
* <p>Discription: 使用rest风格来接收参数,如http://localhost:8080/xxx/mvc/namespace/aaa/bbb,则参数中的username的值就是aaa,password是bbb</p>
* @return String
*/
@RequestMapping("/{username}/{password}")
public String rest4(Model model,@PathVariable("username") String username,@PathVariable("password") String password) {
System.out.println("rest4");
model.addAttribute("message", "Hello "+username+" , your password is "+password+" !");
return "index";
}
}
拦截器:
MyInteceptor :
package com.tch.springmvc.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class MyInteceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("prehandle -------");
return super.preHandle(request, response, handler);
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion -------");
super.afterCompletion(request, response, handler, ex);
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle -------");
super.postHandle(request, response, handler, modelAndView);
}
}
MyInteceptor2 :
package com.tch.springmvc.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class MyInteceptor2 extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
System.out.println("prehandle -------MyInteceptor2");
String uri = request.getRequestURI();
if(uri.indexOf("rest") != -1){
response.getWriter().print("contains rest");
return false;
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion -------MyInteceptor2");
}
@Override
public void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle -------MyInteceptor2");
}
}
实体类:
package com.tch.springmvc.bean;
public class Shop {
String name;
String staffName[];
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getStaffName() {
return staffName;
}
public void setStaffName(String[] staffName) {
this.staffName = staffName;
}
}
最后就是页面了,由于上面dispatcher-servlet.xml 中配置了:
<!-- 添加前缀 --> <property name="prefix" value="/pages/" /> <!-- 添加后缀 --> <property name="suffix" value=".jsp" />
表示我们的相应页面的结构是这样组成: '/pages/' + action的结果字符串 + '.jsp'
对应上面的helloWorld方法的结果字符串:"helloWorld",页面就是 /pages/helloWorld.jsp 了。
所以需要在/pages/ 下面新建 helloWorld.jsp ,内容为:(页面加载完之后,会发出ajax请求获取json数据,最后控制台打印出来)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'User.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script type="text/javascript" src="<%=basePath%>/js/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
$(function(){
//ajax请求获取json数据
$.getJSON("mvc/namespace/json", function(json){
console.info(json);
});
});
</script>
</head>
<body>
${message}
</body>
</html>
好了,最简单的结构就完成了(下面的 xxx 是项目名称)
访问helloWorld : http://localhost:8080/xxx/mvc/namespace/helloWorld 就出来结果了。。。
访问json : http://localhost:8080/xxx/mvc/namespace/json
访问json2 : http://localhost:8080/xxx/mvc/namespace/json2
访问rest : http://localhost:8080/xxx/mvc/namespace/rest/dreamoftch
访问rest2 : http://localhost:8080/z/mvc/namespace/json3
访问rest3 : http://localhost:8080/xxx/mvc/namespace/rest/aaa/bbb,则参数中的username的值就是aaa,password是bbb
访问rest4 : http://localhost:8080/xxx/mvc/namespace/aaa/bbb,则参数中的username的值就是aaa,password是bbb