Spring MVC Controller 的同一个 URL 请求,根据逻辑判断返回 JSON 或者 HTML 视图
为什么80%的码农都做不了架构师?>>>
需求 有这样一个需求,用户注册时,对于浏览器终端和非浏览器终端发起的 HTTP 请求,都走同一个 URL:/user/register。如果是基于浏览器的终端,返回一个 HTML 视图;如果请求来自于非浏览器终端,返回一个 JSON 串。 分析 Spring MVC 返回 HTML 视图,Controller 一般需要返回一个 String 对象,形如以下代码:
//发送密码重置邮件user/sendPasswordEmail
@RequestMapping("/user/sendPasswordEmail")
public String sendPasswordEmail(HttpServletRequest request,@RequestParam("email") String email) throws Exception { userService.forgetPassword(email, request); return "user/passwordSent";
}
Spring MVC 会根据 "user/passwordSent" 找到应该返回的 jsp 页面。 或者一个 ModelAndView 对象:
//转发至resetPassword.jsp(后一个控制器可共享前一个控制器的参数与属性)
@RequestMapping("/user/resetPasswordInput")
public ModelAndView resetPasswordInput() {
return new ModelAndView("forward:/WEB-INF/jsp/user/resetPassword.jsp");
}
Spring MVC 同样会根据 "forward:/WEB-INF/jsp/user/resetPassword.jsp" 找到应该返回的 jsp 页面。 Spring MVC 返回 JSON,Controller 一般需要返回一个 Object 对象,或者 JSONObject,并非 ModelAndView 对象。形如以下代码:
/**
* 测试返回JSON数据
* @param session
* @return
*/
@RequestMapping(value="/test")
@ResponseBody
public Object test(HttpSession session){System.out.println("test....................");
return session.getAttribute("permit");
}
返回值类型不一样。就算业务逻辑可以判断出请求来自浏览器终端或者其他非浏览器终端,又如何返回不同类型的对象呢? 解决方案 对于非浏览器终端,使用 MappingJacksonHttpMessageConverter 将 Model 转为 JSON,然后写入 HttpServletResponse 后返回。参考:http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/http/converter/AbstractHttpMessageConverter.html#write(T, org.springframework.http.MediaType, org.springframework.http.HttpOutputMessage)。这样子,对于非浏览器终端的 HTTP 请求,也可以接受一个 ModelAndView 对象的返回值了。浏览器终端和非浏览器终端共用一个 URL 请求。 源码示例 自定义 JsonView 类源码:
package com.defonds.oauth.common.util;import java.io.IOException;import javax.servlet.http.HttpServletResponse;import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.servlet.ModelAndView;public class JsonView {
public static ModelAndView Render(Object model, HttpServletResponse response)
{
MappingJacksonHttpMessageConverter jsonConverter = new MappingJacksonHttpMessageConverter();MediaType jsonMimeType = MediaType.APPLICATION_JSON;try {
jsonConverter.write(model, jsonMimeType, new ServletServerHttpResponse(response));
} catch (HttpMessageNotWritableException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}return null;
}
}
浏览器终端和非浏览器终端注册共用一个 URL 的 Controller 源码: [java] view plaincopyprint?
package com.defonds.oauth.user.mvc;import javax.servlet.http.HttpServletResponse;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;import com.defonds.oauth.GlobalConstant;
import com.defonds.oauth.common.exception.UserOAuthException;
import com.defonds.oauth.common.util.JsonView;
import com.defonds.oauth.user.response.UserResponse;
import com.defonds.oauth.user.service.UserService;@Controller
public class UserController {
private static final Log log = LogFactory.getLog(UserController.class);
private UserService userService;/**
* 用户注册接口(浏览器终端、手机终端共同走此接口)
* 判断依据:浏览器接口传递过来一 hidden 变量 browser,其值为 true;否则判定为其他终端
* @param username 用户名【必须】
* @param password 密码 【必须】
* @param email 邮箱地址【必须】
* @param browser 浏览器【可选】,值为 true 者为浏览器
* @return ModelAndView:浏览器终端返回 jsp 页面;其他终端返回 JSON 串
* 备注:Spring 注解绑定时 @RequestParam("email") String email,@RequestParam 的 required 参数默认为 true
* 如果手机终端用户 HTTP 请求没有 email 参数,将产生异常
* 所以将 email 等传入参数是否包含的验证交由服务器处理,为空返回相应异常的 JSON 串
*/
@RequestMapping("/user/register")
public ModelAndView doRegister(HttpServletResponse response,
@RequestParam(value = "username", required = false) String username,
@RequestParam(value = "password", required = false) String password,
@RequestParam(value = "email", required = false) String email,
@RequestParam(value = "browser", required = false) String browser) {
if (browser != null && browser.equals("true")) {//有值且为 true,是浏览器终端发起的请求
try {
userService.addOauthUser(username, password, email);//处理注册相关业务逻辑
return new ModelAndView("user/registerSuccess");//返回到注册成功页面
} catch (UserOAuthException uoae) {//自定义业务逻辑异常
log.debug(uoae.getMessage());
ModelAndView mav = new ModelAndView("user/registerFailed");
mav.addObject("userOAuthException", uoae);
return mav;//返回注册失败页面
} catch (Exception e) {//系统异常
log.error(e.getMessage(), e);
UserOAuthException userOAuthException = new UserOAuthException(
UserOAuthException.ERROR_11001,
UserOAuthException.ERROR_CODE_11001,
UserOAuthException.ERROR_DESC_11001,
e.getMessage());
ModelAndView mav = new ModelAndView("user/registerFailed");
mav.addObject("userOAuthException", userOAuthException);
return mav;//返回注册失败页面
}
} else {//无值或不为 true,是浏览器之外的终端发起的请求
try {
userService.addOauthUser(username, password, email);//处理注册相关业务逻辑
return JsonView.Render(new UserResponse(
GlobalConstant.SUCCESS_CODE_11000,
username,
email), response);//其他终端,返回注册成功的 JSON 串
} catch (UserOAuthException uoae) {//自定义业务逻辑异常
log.debug(uoae.getMessage());
return JsonView.Render(uoae, response);//其他终端,返回注册失败的 JSON 串
} catch (Exception e) {//系统异常
log.error(e.getMessage(), e);
return JsonView.Render(new UserOAuthException(
UserOAuthException.ERROR_11001,
UserOAuthException.ERROR_CODE_11001,
UserOAuthException.ERROR_DESC_11001,
e.getMessage()), response);
}
}
}public UserService getUserService() {
return userService;
}public void setUserService(UserService userService) {
this.userService = userService;
}
}
转载于:https://my.oschina.net/wzlee/blog/262205
Spring MVC Controller 的同一个 URL 请求,根据逻辑判断返回 JSON 或者 HTML 视图相关推荐
- Spring MVC Controller 要点
2019独角兽企业重金招聘Python工程师标准>>> 今天看到一篇讲解 Spring MVC Controller 的文章,比较详细,顺道翻译下. 在 Spring MVC 中,我 ...
- Spring MVC Controller与jquery ajax请求处理json
在用 spring mvc 写应用的时候发现jquery传递的[json数组对象]参数后台接收不到,多订单的处理,ajax请求: var cmd = {orders:[{"storeId&q ...
- spring mvc controller间跳转 重定向 传参
spring mvc controller间跳转 重定向 传参 1. 需求背景 需求:spring MVC框架controller间跳转,需重定向.有几种情况:不带参数跳转,带参数拼接url形 ...
- Spring MVC Controller中返回json数据中文乱码处理
问题 在使用spring MVC Controller的过程中,发现返回到客户端的的中文出现乱码.后台Java代码: @RequestMapping(value = "/upload&quo ...
- Spring mvc Controller间跳转/重定向/传参
Spring mvc Controller常用写法 1.ModelAndView @RequestMapping(value = "/getxxxList.html") publi ...
- java注解返回不同消息,Spring MVC Controller中的一个读入和返回都是JSON的方法如何获取javax.validation注解的异常信息...
Spring MVC Controller中的一个读入和返回都是JSON的方法怎么获取javax.validation注解的错误信息? 本帖最后由 LonelyCoder2012 于 2014-03- ...
- Spring MVC 接收POST表单请求,获取参数总结
2019独角兽企业重金招聘Python工程师标准>>> 前段时间遇到一个问题,在spring mvc 服务端接收post请求时,通过html 表单提交的时候,服务端能够接收到参数的值 ...
- java调用远程 接口_java通过url调用远程接口返回json数据
java通过url调用远程接口返回json数据,有用户名和密码验证, 转自 https://blog.csdn.net/wanglong1990421/article/details/78815856 ...
- Spring MVC的GET与POST请求url-pattern坑
一.坑现象复现 1.web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns ...
最新文章
- 微软免费AI作文打分软件升级:雅思考研四六级都能用,还能查单词给替换
- 基于WebForm的Front Controller模式框架
- for in 和 for of 的区别
- 高并发服务端分布式系统设计概要(上)
- 宽带651以及光猫红色灯闪烁-故障维修
- 一个简单的javascript节流器实现
- SQLAlchemy 多态进阶(__mapper_args__ )、多对多标签
- 百度阿里网易大疆等大小厂前端校招面筋 | 掘金技术征文
- [转载] python内置函数 compile()
- 【翻译】3D Bounding Box Estimation Using Deep Learning and Geometry
- 自制VBS自动刷屏器,再也不怕刷屏刷不过别人了
- SQL面试经典题(含答案)
- 如何请求您的Apple ID帐户数据的副本
- 使用mask雕刻镂空背景
- JavaEE中的依赖性——依赖查找
- css-background-image 背景图片太大或太小
- win无法启动资源修复服务器,Win10修复:Windows Defender无法启动两步解决
- 一篇文章带你弄懂乐观锁与悲观锁,CAS原子性,synchronized底层原理
- 拼多多砍价显示服务器吃撑了,拼多多砍价网页打不开是为什么
- 微软计划在未来几周内使用更快版本的 ChatGPT 更新 Bing