您的位置:首页 > 编程语言 > Java开发

SpringMVC之json数据交互,RestFul风格与拦截器实现

2017-09-10 11:45 531 查看
1、json数据交互

@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容(json数据)转换为java对象并绑定到Controller方法的参数上。

@ResponseBody注解实现将Controller方法返回java对象转换为json响应给客户端。 如果加上@ResponseBody注解,就不会走视图解析器,不会返回页面,而是返回的json数据。如果不加,就走视图解析器,返回页面。

使用这两个注解即能完成json数据交互。

添加jackson的jar包,使用maven

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.9</version>
</dependency>


修改商品页面(itemEdit.jsp)加载完毕,发送ajax请求。

<title>修改商品信息</title>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.4.4.min.js"></script>
<script type="text/javascript">
$(function(){
//json数据
var item='{"id":"7","title":"诺基亚N79","sellPoint":"卖的是情怀","price":999}';
//发送ajax请求,使用类似$.post()这种方式是不能发送json数据的
$.ajax({
url:"${pageContext.request.contextPath }/test/save.action",
data:item,
type:"post",
contentType:"application/json;charset=UTF-8",//发送的数据格式为json格式,
dataType:"json",//回调json
success:function(data){
alert(data.title+","+data.sellPoint);
},
error:function(){
alert("系统异常!");
}
});
});
</script>
</head>
<body>
<form id="userForm" enctype="multipart/form-data" action="${pageContext.request.contextPath }/updateItem.action" method="post">
<input type="hidden" name="id" value="${item.id }" /> 修改商品信息:
<table width="100%" border=1>
<tr>
<td>标题</td>
<td><input type="text" name="title" value="${item.title }"/></td>
</tr>
<tr>
<td>卖点</td>
<td><textarea rows="3" cols="30" name="sellPoint">${item.sellPoint }</textarea></td>
</tr>
<tr>
<td>价格</td>
<td><input type="text" name="price" value="${item.price }" /></td>
</tr>
<tr>
<td>图片</td>
<td>
<c:if test="${item.image!=null }">
<img src="/picture/${item.image }" width="100px" height="100px">
</c:if>
<input type="file" name="imageFile" src="/picture/${item.image }"/>
</td>
</tr>
<tr>
<td>销售截止日期</td>
<td><input type="text" name="sellDeadline"
value='<fmt:formatDate value="${item.sellDeadline }" pattern="yyyy-MM-dd HH:mm:ss"/>' /></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="提交" />
</td>
</tr>
</table>

</form>
</body>


服务端:

@RequestMapping("/test/save")
@ResponseBody
public TbItem save(@RequestBody TbItem item){
System.out.println(item);
return item;
}


测试:

控制台输出

TbItem [id=7, title=诺基亚N79, sellPoint=卖的是情怀, price=999, sellDeadline=null, image=null]


页面展示



当然也可以使用postman等工具进行测试更加方便。

注:如果测试出现:No converter found for return value of type: class com.scu.mvc.entity.实体类,这种异常,很有可能导入的jackson包不对。

2、RestFul风格

Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

资源:互联网所有的事物都可以被抽象为资源

资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。

分别对应 添加、 删除、修改、查询。

传统方式操作资源

http://127.0.0.1/item/queryItem.action?id=1 查询,GET

http://127.0.0.1/item/saveItem.action 新增,POST

http://127.0.0.1/item/updateItem.action 更新,POST

http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST

使用RESTful操作资源

http://127.0.0.1/item/1 查询,GET

http://127.0.0.1/item 新增,POST

http://127.0.0.1/item 更新,PUT

http://127.0.0.1/item/1 删除,DELETE

比如在京东搜索月饼,然后点击了某个月饼查看详情,请求地址就能看到

https://item.jd.com/13822345844.html,而发现13822345844就是商品编号



比如这里根据id查询商品信息,返回json数据,我们可以使用localhost:8080/SpringMVC/item/1.action去替代传统的方式http://localhost:8080/SpringMVC/toEdit.action?id=1

服务端处理

@RequestMapping("/item/{id}.action")
@ResponseBody
public TbItem findItem(HttpServletRequest request,@PathVariable int id){
TbItem tbItem = itemService.findById(id);
return tbItem;
}


注:{xxx}叫做占位符,请求地址可以是/item/1.action,也就是查询id=1的商品信息,而使用(@PathVariable intid)获取url上的数据,当{xx}跟形参名称不一致时需要指定,比如url:/item/{no}.action,形参为int id

那么需要指定no对应id,@PathVariable(“no”) int id

测试:

浏览器访问:



3、拦截器

不管过滤器还是拦截器都是用到了aop思想,可以理解为纵向代码横向抽取,把每个模块共有的功能都给提取出来,比如日志,安全校验等。用的比较多的就是用户登录校验了,当用户访问用户中心时都需要校验该用户是否登录,登录了才允许访问,否则跳转到登录页面。

Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。

我们只需要实现HandlerInterceptor接口,在重写的方法里面实现自己的处理逻辑。然后再在容器中注册,指定拦截器,拦截哪些方法,哪些方法不拦截。

现在添加登录页面

<body>
<form action="${pageContext.request.contextPath }/login.action" method="post">
<p>
用户名:<input type="text" name="username" value="${item.username }"/>
</p>
<p>
密码:<input type="text" name="password" value="${item.password }"/>
</p>
<input type="submit" value="登录"/>
</form>
</body>


服务端添加LoginController

@Controller
public class LoginController {

@RequestMapping("/toLogin")
public String toLogin(){
return "login";
}
@RequestMapping("/login")
public String login(HttpServletRequest request,User user){
//模拟登录成功,用户信息写入session
HttpSession session = request.getSession();
session.setAttribute("user", user);
return "redirect:/show.action";
}
}


(1)、自定义登录拦截器实现

public class LoginInterceptor implements HandlerInterceptor{
// Controller执行前调用此方法
// 返回true表示继续执行,返回false中止执行
// 这里可以加入登录校验、权限拦截等
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj)
throws Exception {
HttpSession session = request.getSession();
User user = (User)session.getAttribute("user");
if(user!=null){
//用户已经登录,放行
return true;
}
//重定向到登录页,不放行
String path = request.getContextPath();
path = path +"/toLogin.action";
response.sendRedirect(path);
return false;
}
// controller执行后但未返回视图前调用此方法
// 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
// controller执行后且视图返回后调用此方法
// 这里可得到执行controller时的异常信息
// 这里可记录操作日志
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}


2、注册拦截器

<!-- 拦截器配置 -->
<mvc:interceptors>
<mvc:interceptor>
<!--拦截所有请求,如果使用/*则只能拦截一层-->
<mvc:mapping path="/**"/>
<!--去登录和登录的请求不拦截-->
<mvc:exclude-mapping path="/login.action"/>
<mvc:exclude-mapping path="/toLogin.action"/>
<!--指定拦截器-->
<bean class="com.scu.mvc.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>


现在只要访问商品首页或者修改商品信息等地址的时候,只要用户没登录就应该跳转到登录页面,登录后即可继续访问。

测试:

访问商品信息列表http://localhost:8080/SpringMVC/show.action跳转到了登录页面



随便填写个用户名和密码,点击登录,跳转到了商品列表页面

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: