论坛首页 Java企业应用论坛

SpringMVC3 rest服务 相关知识点记录

浏览 6372 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-01-29   最后修改:2013-01-29
最近重新回头做j2ee开发,之前一直是struts。既然重新开始做j2ee,怎么也要有点新花样。

于是就研究springmvc的rest来做web service。


其他没什么,主要是记录一下以下的几个关键知识点。

由于是web服务,出现异常必然不可能返回页面给调用者,于是捕捉封装异常成了必然。

于是几个学习点:全局异常捕捉,json方式输出,404的处理。

1.全局异常捕捉:

自己实现一个HandlerExceptionResolver,然后写到配置文件中
比如:
public class RestServiceExceptionHandler extends
		DefaultHandlerExceptionResolver{}


同时controller内部也有注解的异常处理。这边有一个异常优先级关系。可以把注解配置的噶一些,这个看个人项目。


2. 404的处理

配置完以后发现有一些默认的404错误还是不会被捕捉到,直接就被spring的dispatchServlet给处理掉了。比如很简单的如下定义的controller的方法:

因为@RequestParam 需要两个参数

如果不小心漏了一个参数,比如:输入了 这样的/xxxxx/movie/add?a=1 路径,那肯定是希望返回json提示,但是结果是直接给我一个404的jsp页面。。。

@ResponseBody
	@RequestMapping("/movie/add")
	public Object addMovie(
			@RequestParam(value="a") String movieName,
			@RequestParam(value="b") String movieDirector,
			){
		
		this.LOGGER.info("> add date success! <");
		Map<String,Object> dataMap = new HashMap<String, Object>();
		return dataMap;
	}



处理方法:写一个默认的controller来捕捉所有的路径:

@Controller
public class DefaultNoMappingController {
	 @RequestMapping("/**")
	    public void unmappedRequest(HttpServletRequest request) {
	        String uri = request.getRequestURI();
	        throw new RestServiceException("资源不存在 " + uri,RestErrorCode.uri_not_found.getValue());
	    }

}



3.json方式输出

直接在doResolveException方法里输出了,网上貌似例子很多。。我随便找了个就用了。不知道算不算正统。。

errorConverter 为异常的转化对象,就是接收异常转化成系统自定义的错误类。

protected ModelAndView doResolveException(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex) {
		
			RestError error = errorResolver.resolveError(request, handler, ex);
			response.setCharacterEncoding("UTF-8");
			response.setContentType("application/json");
			ObjectMapper mapper = new ObjectMapper();

			try {
				JsonGenerator jsonGenerator = mapper.getJsonFactory()
						.createJsonGenerator(response.getOutputStream(),
								JsonEncoding.UTF8);
				mapper.writeValue(jsonGenerator, errorConverter.convert(error));
			} catch (JsonGenerationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (JsonMappingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			return new ModelAndView();
	}




基本上写下来发现最搞不清楚的还是404那块,当时一直不知道怎么处理,甚至于我都想到要复写dispatchServlet了,后来找到老外的一个rest的异常框架,终于了解了。。

老外的那个东东:

介绍:
http://www.stormpath.com/blog/spring-mvc-rest-exception-handling-best-practices-part-1

代码下载:
https://github.com/stormpath/spring-mvc-rest-exhandler

另外最后有一个问题没想通,请看到这个文章并且了解的人解惑:

就是像我那样直接用 response.write来输出json字串和 老外那样用ContentNegotiatingViewResolver配置来输出json 有什么本质区别??

感觉是直接写response.write来输出方便啊,谢谢。



   发表时间:2013-01-29  
ContentNegotiatingViewResolver是一个内容协商的视图解析器,本身不作为,只是更具Content-Type选择不同的视图解析器进行处理:目的是支持多视图:
如请求的Accept=application/json 表示需要json数据
如请求的Accept=application/xml 表示需要xml数据
说白了可以根据客户端的Accept等来协商返回的结果
0 请登录后投票
   发表时间:2013-01-29  
jinnianshilongnian 写道
ContentNegotiatingViewResolver是一个内容协商的视图解析器,本身不作为,只是更具Content-Type选择不同的视图解析器进行处理:目的是支持多视图:
如请求的Accept=application/json 表示需要json数据
如请求的Accept=application/xml 表示需要xml数据
说白了可以根据客户端的Accept等来协商返回的结果



呃,那我了解了,那还是一样,本质还是response.write。只是留个配置项,以后输出xml也可以。。
0 请登录后投票
   发表时间:2013-01-29  
leobluewing 写道
jinnianshilongnian 写道
ContentNegotiatingViewResolver是一个内容协商的视图解析器,本身不作为,只是更具Content-Type选择不同的视图解析器进行处理:目的是支持多视图:
如请求的Accept=application/json 表示需要json数据
如请求的Accept=application/xml 表示需要xml数据
说白了可以根据客户端的Accept等来协商返回的结果



呃,那我了解了,那还是一样,本质还是response.write。只是留个配置项,以后输出xml也可以。。

嗯,一种策略实现
0 请登录后投票
   发表时间:2013-01-29  
MappingJacksonHttpMessageConverter 现在已经支持通过
@RequestMapping( produces="application/xml",headers="Accept=application/xml")

这样的方式输出xml或者json.
0 请登录后投票
   发表时间:2013-01-29  
char1st 写道
MappingJacksonHttpMessageConverter 现在已经支持通过
@RequestMapping( produces="application/xml",headers="Accept=application/xml")

这样的方式输出xml或者json.

嗯,生产者/消费者模式
http://jinnianshilongnian.iteye.com/blog/1695047
0 请登录后投票
   发表时间:2013-02-03  
@RequestMapping("/**") 

用这个捕捉所有的路径404的处理,错误处理页面的静态资源 如图片 访问不到
已配置:
<!-- 对静态资源文件的访问支持 -->
<mvc:default-servlet-handler />

去掉这个全局处理错误页面的静态资源又可以访问了,求解
0 请登录后投票
   发表时间:2013-02-03  
ContentNegotiatingViewResolver 在 spring3.2中已经不再使用。
建议使用 setContentNegotiationManager
0 请登录后投票
   发表时间:2013-02-06  
icemoff 写道
@RequestMapping("/**") 

用这个捕捉所有的路径404的处理,错误处理页面的静态资源 如图片 访问不到
已配置:
<!-- 对静态资源文件的访问支持 -->
<mvc:default-servlet-handler />

去掉这个全局处理错误页面的静态资源又可以访问了,求解


典型的springmvc的rest风格静态资源访问问题,网上一搜一大堆。


我比较习惯于把静态资源显式的配出来,比如这样

<mvc:resources mapping="/upload/**" location="/upload/" />
	<mvc:resources mapping="/images/**" location="/WEB-INF/images/" />
	<mvc:resources mapping="/css/**" location="/WEB-INF/css/" />
	<mvc:resources mapping="/js/**" location="/WEB-INF/js/" />
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics