首页 > 代码库 > SpringMVC简单构造restful, 并返回json
SpringMVC简单构造restful, 并返回json
文章要要点:
快速搭建构造restful的StringMvc
GET, POST , PUT , DELETE的各种调用
同一资源 多种表述 (ContentNegotiatingViewResolver解析器),既可以返回对象给JSP, 也可以返回JSON
快速搭建构造restful的StringMvc
首现搭建一个简单的restfulMvc框架, 并上配置文件, 后期会增加带JSON返回值的配置
JAR包
web.xml配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | < servlet > < servlet-name >spring</ servlet-name > < servlet-class >org.springframework.web.servlet.DispatcherServlet</ servlet-class > <!-- 可以自定义servlet.xml配置文件的位置和名称,默认为WEB-INF目录下,名称为[<servlet-name>]-servlet.xml,如spring-servlet.xml--> < init-param > < param-name >contextConfigLocation</ param-name > < param-value >classpath:config/spring-servlet.xml</ param-value > <!-- 现定义为src下config包里(个人习惯) --> </ init-param > < load-on-startup >1</ load-on-startup > </ servlet > < servlet-mapping > < servlet-name >spring</ servlet-name > < url-pattern >/api/*</ url-pattern > </ servlet-mapping > <!-- Spring配置 --> < listener > < listener-class >org.springframework.web.context.ContextLoaderListener</ listener-class > </ listener > <!-- 指定Spring Bean的配置文件所在目录。默认配置在WEB-INF目录下 --> < context-param > < param-name >contextConfigLocation</ param-name > < param-value >classpath:config/applicationContext-*.xml</ param-value > </ context-param > |
spring-servlet.xml配置
1 2 3 4 5 6 7 | <!-- 启动注解驱动的Spring MVC功能,注册请求url和注解POJO类方法的映射--> < mvc:annotation-driven /> <!-- 启动包扫描功能,以便注册带有@Controller、@Service、@repository、@Component等注解的类成为spring的bean --> < context:component-scan base-package = "com.dsp" /> <!-- 对模型视图名称的解析,在请求时模型视图名称添加前后缀 --> < bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix = "/WEB-INF/jsp/" p:suffix = ".jsp" /> |
applicationContext.xml暂时没写东西
该配置的配置完了,下面就是写第一个HelloWord
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package com.dsp.action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Scope( "prototype" ) //单列模式 @Controller @RequestMapping( "/products" ) public class TestController{ /** * 测试方法,HelloWord * @param request * @param response * @return * @throws Exception */ @RequestMapping(value=http://www.mamicode.com/ "/list" ,method=RequestMethod.GET) public String getProducts(HttpServletRequest request,HttpServletResponse response) throws Exception { request.setAttribute( "name" , "helloWord" ); return "products/list" ; } } |
@Scope("##") : spring默认的Scope是单列模式(singleton),顾名思义,肯定是线程不安全的. 而@Scope("prototype")
可以保证每个请求都会创建一个新的实例, 还有几个参数: session request
@Scope("session")的意思就是,只要用户不退出,实例就一直存在,
request : 就是作用域换成了request
@Controller : 不多做解释 , 标注它为Controller
@RequestMapping :是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是 以该地址作为父路径。 比如现在访问getProducts方法的地址就是 :
http://localhost:8080/项目名/上面web.xml配置(api)/products/list
l
暂时先介绍两个属性 value和method
具体可以参考我参考的文章 http://blog.sina.com.cn/s/blog_72827fb10101pl9i.html
value: 就是映射的实际地址,这个上面有说过, 而重要的是里面的值 , 有几个比较感兴趣的
1. 正常的 /list 访问地址类似 http://localhost:8080/项目名/api/products/list
2. 带参数的 /info/{proId} 访问地址类似 http://localhost:8080/项目名/api/products/info/0001
method: 请求的method类型 GET POST PUT DELETE等
好,做个测试 JSP代码:
1 2 3 4 5 6 7 8 9 10 11 12 | <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> < html > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" > < title > 你好</ title > </ head > < body > ${name } </ body > </ html > |
地址栏输入 http://localhost:8080/RestFulMvc/api/products/list
得到结果
GET, POST , PUT , DELETE的各种调用
刚才写的是第一种GET, 第二种GET:
1 2 3 4 5 6 7 8 | @RequestMapping (value=http://www.mamicode.com/ "/info/{proId}" ,method=RequestMethod.GET) public String getProductInfo( @PathVariable String proId, HttpServletRequest request,HttpServletResponse response) throws Exception { request.setAttribute( "name" , proId); return "products/list" ; } |
@PathVariable注解获取的就是大括号里的值
测试 : 输入地址 http://localhost:8080/RestFulMvc/api/products/info/00001
测试结果为
如果不用@PathVariable接收大括号里的值,也可以用bean来接收:
public String getProductInfo(Product pro, HttpServletRequest request,HttpServletResponse response)...
而且也可以设置多个参数
@RequestMapping(value=http://www.mamicode.com/"/info/{pid}/{pname}",method=RequestMethod.GET)
让我们看下面这段代码
1 2 3 4 5 6 7 8 | @RequestMapping (value=http://www.mamicode.com/ "/info/{pid}/{pname}" ,method=RequestMethod.GET) public String getProductInfo(Product pro, HttpServletRequest request,HttpServletResponse response) throws Exception { request.setAttribute( "name" , pro.getPid()+ "___" +pro.getPname()); return "products/list" ; } |
访问地址: http://localhost:8080/RestFulMvc/api/products/info/00001/23123
得到的结果为 :
下面介绍POST的调用
list.jsp新增form表单如下
1 2 3 4 5 6 7 8 | < body > ${name } < form action="<%=basePath%>/api/products/info" method="post"> < input type = "text" name = "pid" /> < input type = "text" name = "pname" /> < input type = "submit" /> </ form > </ body > |
JAVA代码
1 2 3 4 5 6 7 8 | @RequestMapping (value=http://www.mamicode.com/ "/info" ,method=RequestMethod.POST) public String insertProduct(Product pro, HttpServletRequest request,HttpServletResponse response) throws Exception { request.setAttribute( "name" , pro.getPid()+ "___" +pro.getPname()); return "products/list" ; } |
form提交后结果为
执行成功.
正常的FORM提交 , 只需要用对象接就可以了
同一资源 多种表述
如果写完一个方法,返回request到JSP, 可同时手机端需要调接口怎么办, 如果前台的一层皮换成了以nodejs为服务的框架调用怎么办
可以每个需求再写一个方法返回JSON, 可下面这个可以同一资源,多种返回
spring-servlet.xml加入如下配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <!-- ContentNegotiatingViewResolver视图解析器,利用他就可以配置多种返回值 --> < bean class = "org.springframework.web.servlet.view.ContentNegotiatingViewResolver" > <!-- 这里是否忽略掉accept header,默认就是false --> < property name = "ignoreAcceptHeader" value = "true" /> <!-- 如果所有的mediaType都没匹配上,就会使用defaultContentType --> < property name = "defaultContentType" value = "text/html" /> < property name = "mediaTypes" > < map > < entry key = "json" value = "application/json" /> < entry key = "xml" value = "application/xml" /> </ map > </ property > <!-- 默认使用MappingJacksonJsonView生成jsonview--> < property name = "defaultViews" > < list > < bean class = "org.springframework.web.servlet.view.json.MappingJacksonJsonView" > < property name = "extractValueFromSingleKeyModel" value = "true" /> </ bean > < bean class = "org.springframework.web.servlet.view.xml.MarshallingView" > < property name = "marshaller" > < bean class = "org.springframework.oxm.xstream.XStreamMarshaller" /> </ property > </ bean > </ list > </ property > </ bean > |
这样同一个地址,只要在后面加 .json mediaTypes就可以把http://localhost:8080/RestFulMvc/api/products/info/00001/23123.json 的 .json映射到application/json
值得注意的是, 如果不加 <property name="extractValueFromSingleKeyModel" value=http://www.mamicode.com/"true" />
得出来的Product对象的JSON为
{"product":{"pid":"00001","pname":"23123"}}
如果想要的结果为
{"pid":"00001","pname":"23123"}
则不要前面的对象名称包在外面时, 请加上它
后台代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @RequestMapping (value=http://www.mamicode.com/{ "/info/{pid}" , "/info/{pid}.json" },method=RequestMethod.GET) public ModelAndView getProductInfo( @PathVariable String pid, HttpServletRequest request,HttpServletResponse response) throws Exception { Map<String,Object> map = new HashMap<String,Object>(); Product pro = new Product(); pro.setPid(pid); map.put( "name" , pid); map.put( "pro" , pro); ModelAndView mav= new ModelAndView( "products/list" ,map); return mav; } |
测试: 输入地址 : http://localhost:8080/RestFulMvc/api/products/info/00001.json
得到的结果为
{"pro":{"pid":"00001","pname":null},"name":"00001"}
ModelAndView是springmvc自带的重定向方法
第一个参数是返回的地址,和以往一样, 第二个参数以后, 是传给前台的值 .
如果有第二个参数, 没有第三个参数 , 那第二个参数只能是map的
也可以第二个参数为建, 第三个参数为值的方式传给前台, 具体大家可以new一个ModelAndView看看它提供的构造方法
最后 如果是nodejs ajax提交的数据,以application/json格式提交时,
接收参数可以在参数前加 @@RequestBody
public ModelAndView getProductInfo(@RequestBody Product pro, HttpServletRequest request .....
它可以把json转换为对象里的属性
SpringMVC简单构造restful, 并返回json