SpringMVC简单构造restful, 并返回json

在别人的博客上看到的文章,就摘抄下来了,最近看书的方向比较乱,nodejs准备学着看看。。转载的内容先为自己留着

 

文章要要点:

  1. 快速搭建构造restful的StringMvc

  2. GET, POST , PUT , DELETE的各种调用

  3. 同一资源 多种表述 (ContentNegotiatingViewResolver解析器),既可以返回对象给JSP, 也可以返回JSON

快速搭建构造restful的StringMvc

首现搭建一个简单的restfulMvc框架,  并上配置文件, 后期会增加带JSON返回值的配置

JAR包


 

web.xml配置

<servlet>

     <servlet-name>spring</servlet-name>
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
     <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>classpath:config/spring-servlet.xml</param-value>
     </init-param>
     <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
      <servlet-name>spring</servlet-name>
      <url-pattern>/api/*</url-pattern>
</servlet-mapping>


<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配置

 

<!-- 启动注解驱动的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

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="/list",method=RequestMethod.GET)
    public  String getProducts(HttpServletRequest request,HttpServletResponse response) throws Exception {
    
        request.setAttribute("name""helloWord");
          
        return  "products/list";
          
    }
}

地址栏输入 http://localhost:8080/RestFulMvc/api/products/list

得到结果

GET, POST , PUT , DELETE的各种调用

刚才写的是第一种GET, 第二种GET:

@RequestMapping(value="/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="/info/{pid}/{pname}",method=RequestMethod.GET)

让我们看下面这段代码

@RequestMapping(value="/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表单如下

<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代码

@RequestMapping(value="/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提交 , 只需要用对象接就可以了

 

补上 PUT DELETE 就和表单不一样了, 因为表单只支持GET和POST

这时候就需要用到ajax,  或者nodejs调用

贴上jsp代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script  type="text/javascript"  src='<%=basePath%>/public/js/jquery-2.1.0.min.js'></script>
<script  type="text/javascript">
function savepro(){
 var saveData = {"pid":"aa"}; //发送给服务器的JSON
 $.ajax({
  type : "PUT",
  url : "/RestFulMvc/api/products/info.json",
  data:JSON.stringify(saveData),
  contentType:"application/json",  //发送至服务器的类型
  dataType : "json",     //预期服务器返回类型
  success: function(data){
   alert(data);
  }
    
 })
}
</script>
</head>
<body>
<div>
 <input  type="button"  value="保存"  onclick="savepro()"/>
</div>
</body>

后台代码

1
2
3
4
5
6
7
8
9
10
11
@RequestMapping(value="/info",method=RequestMethod.PUT)
    public  ModelAndView updateProduct( @RequestBody  Product pro, HttpServletRequest request,HttpServletResponse response) throws  Exception {
    
  Map<String,Object> map1 = new  HashMap<String,Object>();
  map1.put("pid", pro.getPid());
    
  ModelAndView mav=new  ModelAndView("products/list",map1);
    
  return  mav;
  }

和以往不一样的是, 后台接收参数的对象前面 加了个@RequestBody , 这个是用于把传来的JSON 转换成接收的对象, 如果是form提交就不需要了, 但如果前台用的是application/json类型传进来,就一定要加@RequestBody

得到的结果:

同一资源 多种表述

如果写完一个方法,返回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="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={"/info/{pid}"},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"}

 

最后 如果是nodejs  ajax提交的数据,以application/json格式提交时,

接收参数可以在参数前加 @RequestBody

public ModelAndView getProductInfo(@RequestBody Product pro, HttpServletRequest request .....

它可以把json转换为对象里的属性

 

 -----------------------------------------------------------------------------------------------------------------------

PUT/DELETE方法:从语义上来讲,对资源是有破坏性的,PUT更改现有的资源,而DELETE摧毁一个资源,带有破坏性质的方法有时候会被防火墙或者IT管理人员特别关注,所以当提供PUT/DELETE接口服务时,需要确保服务器前置的防火墙没有block这些方法。当然如果走的是HTTPS协议,无需担心这一点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值