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