qq3国就是不想死进不去 而且投诉来个404 nofound

博客分类:
基于SpringMVC做Websocket开发过程遇到一系列问题:
问题1:统计了一下大家遇到第一个问题就是连接websocket时候报404错误
先检查连接websocket的url格式:ws://localhost:8080/test/webSocketServer.do,这个.do后缀要匹配SpringMVC拦截后缀
其次检查下Spring配置文件是否有加这个tag:&mvc:annotation-driven/&(加这个会出现中文乱码,下面会讲到),使用Spring websocket需要这个tag支持
当Spring配置文件有使用&context:component-scan/&扫描包,这个tag&context:annotation-config/&可以不去掉。
问题2:连接websocket时候报200,说明已经进入拦截器握手成功,但是没连接上websocket
首先,这个主要原因是在自己的代码上,如果websocket有配置自己定义的拦截器,先检查下拦截器beforeHandshake这个方法,这个方法有个参数Map&String, Object& attributes,不能给这个map的value设成null,否则进不到自己Handler下的这个方法afterConnectionEstablished,就会报200其次,在自定义websocket的Handler和拦截器,加上@Component注解(这个是可选部分,根据自己环境来做选择,基本上可以拔除这个原因,仅做参考)
问题3:连接websocket时候,如果缺少配置会报415 Unsupported Media Type请求的格式不受请求页面的支持错误
当用户发送请求后,@Requestbody 注解会读取请求body中的数据,默认的请求转换器HttpMessageConverter通过获取请求头Header中的Content-Type来 确认请求头的数据格式,从而来为请求数据适配合适的转换器。例如contentType:applicatin/json,那么转换器会适配 MappingJacksonHttpMessageConverter。响应时候的时候同理,@Responsebody注解会启用 HttpMessageConverter,通过检测Header中Accept属性来适配的响应的转换器。
当在使用SpringMVC做服务器数据接收时,尤其是在做Ajax请求的时候,尤其要注意contentType属性,和accepte 属性的设置,在springmvc-config.xml中配置好相应的转换器。
添加相应转换器:
&bean id="stringHttpMessageConverter"
class="org.springframework.http.converter.StringHttpMessageConverter"&
&property name="supportedMediaTypes"&
&value&text/charset=UTF-8&/value&
&/property&&/bean&
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"&
&property name="messageConverters"&
&ref bean="stringHttpMessageConverter" /&新增的
&ref bean="byteArrayHttpMessageConverter" /&
&ref bean="jsonHttpMessageConverter" /&
&ref bean="jsonHttpMessageConverter4JS" /&
&/property&
可以参考这个文章:http://www.2cto.com/kf/557.html
问题4:网上例子都有说要在web.xml下的servlet和filter里面加上&async-supported&true&/async-supported&我试下没有影响websocket是可以连接成功的,可以不用加,这个是用来支持异步的servlet3.x,建议不用加,除非有用到这个特性
问题5:添加&mvc:annotation-driven/&这个出现中文乱码
刚开始时候,所有浏览器都出现中文乱码,后来解决在Chrome浏览不会出现中文乱码,但是在FF下会出现。原因有三个:
第一,MessageConverter转换器没配置相应的&property name="supportedMediaTypes"&属性,
第二,bean和tag的先后顺序不对,
第三,当使用&mvc:annotation-driven/&这个tag时候,请求处理器就会变成RequestMappingHandlerAdapter,跟进代码就会发现不是采用AnnotationMethodHandlerAdapter,所以配置时候要改成:org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
统一解决办法是:要注意bean和tag的先后顺序
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"&//这是根本原因
&property name="messageConverters"&
&ref bean="stringHttpMessageConverter" /&
&ref bean="byteArrayHttpMessageConverter" /&
&ref bean="jsonHttpMessageConverter" /&
&ref bean="jsonHttpMessageConverter4JS" /&
&/property&
&context:component-scan base-package="扫描Spring controller包路径" /&
&context:component-scan base-package="扫描websocket包路径"/&
&context:annotation-config /&
//这个标注可以不加
&mvc:annotation-driven/&//这个tag一定要放在上面代码最后,这是也是乱码根源之一
这块具体的配置可以参考我上一篇文章第4点:http://strongant.iteye.com/admin/blogs/2153820
问题6:websocket相关js代码放在html上可以连接到websocket后端,放在jsp上就连接不成功
如果项目有配置yuicompressor-2.4.7.jar,就要注意了这个问题跟项目环境有关,主要是检查项目web.xml配置,项目里面web.xml配置对jsp,css,do做了自动优化(使用yuicompressor-2.4.7.jar),自动优化会把jsp输出优化成无格式,主要用于传输速度变快,但是变成无格式后websocket相关脚本就出现运行不了,最后把这块jsp自动优化去掉
问题7:js上onopen和onmessage会同时触发
当第一次连接到websocket后台,会触发Handler下的afterConnectionEstablished这个方法发送消息,如果在这个方法有发送消息给自己,在UI上会同时触发onopen和onmessage方法,这个不知道为什么会触发onmessage方法,从websocket上协议讲,只会触发onopen方法!!!
问题8:返回jsp时候,路径出现重复名字导致找不到jsp页面(这个大家估计不会遇到,跟项目配置有关)
比如:正常要返回路径localhost:8080/test/template/js/list.jsp
变成错误路径:localhost:8080/test/template/template/js/list.jsp(多了一个template),后来发现是我的视图解释图配置有点问题
&bean id="viewResolvers"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"&
&property name="cache" value="true" /&
&property name="prefix" value="" /&
&property name="suffix" value=".jsp" /&
&property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" /&
&property name="contentType"&
&value&text/ charset=UTF-8&/value&
&/property&&/bean&
改成下面这个配置解决这个问题
&bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver"&
&property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" /&
&property name="prefix" value="/" /&
&property name="suffix" value=".jsp" /&&/bean&
问题9:启动时候出现这个Factory method 'webSocketHandlerMapping' nested exception is java.lang.IllegalStateException: No suitable default RequestUpgradeStrategy found
说明你的容器不支持websocket协议Tomcat7,0.26之后才支持websocket
Jboss as 7不支持websocket,需要要安装插件,可以直接升级到wildfly8支持websocket
浏览: 26776 次
使用sockjs,不进入握手拦截器什么原因
使用了sockJs,后台不进入握手拦截器怎么回事呢
怎么代码下载啊?
你们使用的EJB框架,用来做什么的,怎么看楼主的项目都有EJB ...
weir2009 写道Constants.WEBSOCKET_ ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'  近年来为了引导消费者购买小排量汽车,国家出台了购置税优惠和征收燃油税等相关政策,同时近日相关部门又在讨论降低小排量车的车船使用税。这些政策能够大幅度降低小排量车的使用成本,而微型车凭借油耗低和排放小等特点一直以来都是&小排量&汽车的代名词。今天,我们挑选六款四万元左右的微型车,我们一起看看这些车型各自的特点,看哪款车更适合你。
  与发动机相匹配,QQ3匹配5速手动和5速AMT自动变速箱,其中5速AMT变速箱的基础仍是传统手动变速箱,其工作原理其实很简单,车辆在起步和换挡时,离合器由液压泵控制分离和接合,挡位转换也由液压结构操作。手动模式下驾驶者只需要推拉排挡杆即可完成升、降挡,自动模式下变速箱控制电脑会根据车速、发动机负荷等数据自行切换挡位。
  QQ3的内饰是大众化的设计,以方便实用为主,只有仪表盘的显示略有特色,其他如中控面板和内饰颜色都属于比较平庸型,但耐用耐脏好收拾成为它的优点。
  相关新闻:在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
标签:至少1个,最多5个
@ControllerAdvice 和 @ExceptionHandler 的区别
ExceptionHandler, 方法注解, 作用于 Controller 级别. ExceptionHandler 注解为一个 Controler 定义一个异常处理器.
ControllerAdvice, 类注解, 作用于 整个 Spring 工程. ControllerAdvice 注解定义了一个全局的异常处理器.
需要注意的是, ExceptionHandler 的优先级比 ControllerAdvice 高, 即 Controller 抛出的异常如果既可以让 ExceptionHandler 标注的方法处理, 又可以让 ControllerAdvice 标注的类中的方法处理, 则优先让 ExceptionHandler 标注的方法处理.
处理 Controller 中的异常
为了方便地展示 Controller 异常处理的方式, 我创建了一个工程 SpringBootRESTfulErrorHandler, 其源码可以到我的
中找到.SpringBootRESTfulErrorHandler 工程的目录结构如下:
首先我们定义了三个自定义的异常:BaseException:
public class BaseException extends Exception {
public BaseException(String message) {
super(message);
MyException1:
public class MyException1 extends BaseException {
public MyException1(String message) {
super(message);
MyException2:
public class MyException2 extends BaseException {
public MyException2(String message) {
super(message);
接着我们在 DemoController 中分别抛出这些异常:
@RestController
public class DemoController {
private Logger logger = LoggerFactory.getLogger("GlobalExceptionHandler");
@RequestMapping("/ex1")
public Object throwBaseException() throws Exception {
throw new BaseException("This is BaseException.");
@RequestMapping("/ex2")
public Object throwMyException1() throws Exception {
throw new MyException1("This is MyException1.");
@RequestMapping("/ex3")
public Object throwMyException2() throws Exception {
throw new MyException2("This is MyException1.");
@RequestMapping("/ex4")
public Object throwIOException() throws Exception {
throw new IOException("This is IOException.");
@RequestMapping("/ex5")
public Object throwNullPointerException() throws Exception {
throw new NullPointerException("This is NullPointerException.");
@ExceptionHandler(NullPointerException.class)
public String controllerExceptionHandler(HttpServletRequest req, Exception e) {
logger.error("---ControllerException Handler---Host {} invokes url {} ERROR: {}", req.getRemoteHost(), req.getRequestURL(), e.getMessage());
return e.getMessage();
/ex1: 抛出 BaseException
/ex2: 抛出 MyException1
/ex3: 抛出 MyException2
/ex4: 抛出 IOException
/ex5: 抛出 NullPointerException
当 DemoController 抛出未捕获的异常时, 我们在 GlobalExceptionHandler 中进行捕获并处理:GlobalExceptionHandler:
@RestController
@ControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger("GlobalExceptionHandler");
@ExceptionHandler(value = BaseException.class)
@ResponseBody
public Object baseErrorHandler(HttpServletRequest req, Exception e) throws Exception {
logger.error("---BaseException Handler---Host {} invokes url {} ERROR: {}", req.getRemoteHost(), req.getRequestURL(), e.getMessage());
return e.getMessage();
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Object defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
logger.error("---DefaultException Handler---Host {} invokes url {} ERROR: {}", req.getRemoteHost(), req.getRequestURL(), e.getMessage());
return e.getMessage();
我们看到, GlobalExceptionHandler 类有两个注解:
RestController, 表明 GlobalExceptionHandler 是一个 RESTful Controller, 即它会以 RESTful 的形式返回回复.
ControllerAdvice, 表示 GlobalExceptionHandler 是一个全局的异常处理器.
在 GlobalExceptionHandler 中, 我们使用了 ExceptionHandler 注解标注了两个方法:
ExceptionHandler(value = BaseException.class): 表示 baseErrorHandler 处理 BaseException 异常和其子异常.
ExceptionHandler(value = Exception.class): 表示 defaultErrorHandler 会处理 Exception 异常和其所用子异常.
要注意的是, 和 try...catch 语句块, 异常处理的顺序也是从具体到一般, 即如果 baseErrorHandler 可以处理此异常, 则调用此方法来处理异常, 反之使用 defaultErrorHandler 来处理异常.
既然我们已经实现了 Controller 的异常处理, 那么接下来我们就来测试一下吧.在浏览器中分别访问这些链接, 结果如下:/ex1:
可以看到, /ex1, /ex2, /ex3 抛出的异常都由 GlobalExceptionHandler.baseErrorHandler 处理; /ex4 抛出的 IOException 异常由 GlobalExceptionHandler.defaultErrorHandler 处理. 但是 /ex5 抛出的 NullPointerException 异常为什么不是 defaultErrorHandler 处理, 而是由 controllerExceptionHandler 来处理呢? 回想到 @ControllerAdvice 和 @ExceptionHandler 的区别 这以小节中的内容时, 我们就知道原因了: 因为我们在 DemoController 中使用 ExceptionHandler 注解定义了一个 Controller 级的异常处理器, 这个级别的异常处理器的优先级比全局的异常处理器优先级高, 因此 Spring 发现 controllerExceptionHandler 可以处理 NullPointerException 异常时, 就调用这个方法, 而不会调用全局的 defaultErrorHandler 方法了.
处理 404 错误
Spring MVC
SpringBoot 默认提供了一个全局的 handler 来处理所有的 HTTP 错误, 并把它映射为 /error. 当发生一个 HTTP 错误, 例如 404 错误时, SpringBoot 内部的机制会将页面重定向到 /error 中.例如下图中是一个默认的 SpringBoot 404 异常页面.
这个页面实在是太丑了, 我们能不能自定义一个异常页面呢? 当然可以了, 并且 SpringBoot 也给我们提示了: This application has no explicit mapping for /error, so you are seeing this as a fallback.因此我们实现一个 /error 映射的 Controller 即可.
public class HttpErrorHandler implements ErrorController {
private final static String ERROR_PATH = "/error";
* Supports the HTML Error View
* @param request
@RequestMapping(value = ERROR_PATH, produces = "text/html")
public String errorHtml(HttpServletRequest request) {
return "404";
* Supports other formats like JSON, XML
* @param request
@RequestMapping(value = ERROR_PATH)
@ResponseBody
public Object error(HttpServletRequest request) {
return "404";
* Returns the path of the error page.
* @return the error path
public String getErrorPath() {
return ERROR_PATH;
根据上面代码我们看到, 为了实现自定义的 404 页面, 我们实现了 ErrorController 接口:
public interface ErrorController {
String getErrorPath();
这个接口只有一个方法, 当出现 HTTP 错误时, SpringBoot 会将页面重定向到 getErrorPath 方法返回的页面中. 这样我们就可以实现自定义的错误页面了.
RESTful API
提供一个自定义的 "/error" 页面对 Spring MVC 的服务来说自然是没问题的, 但是如果我们的服务是一个 RESTful 服务的话, 这样做就不行了.当用户调用了一个不存在的 RESTful API 时, 我们想记录下这个异常访问, 并返回一个代表错误的 JSON 给客户端, 这该怎么实现呢?我们很自然地想到, 我们可以使用处理异常的那一套来处理 404 错误码.那么我们来试一下这个想法是否可行吧.
奇怪的是, 当我们在浏览器中随意输入一个路径时, 代码并没有执行到异常处理逻辑中, 而是返回了一个 HTML 页面给我们, 这又是怎么回事呢?原来 Spring Boot 中, 当用户访问了一个不存在的链接时, Spring 默认会将页面重定向到 **/error** 上, 而不会抛出异常.既然如此, 那我们就告诉 Spring Boot, 当出现 404 错误时, 抛出一个异常即可. 在 application.properties 中添加两个配置:
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
上面的配置中, 第一个 spring.mvc.throw-exception-if-no-handler-found 告诉 SpringBoot 当出现 404 错误时, 直接抛出异常. 第二个 spring.resources.add-mappings 告诉 SpringBoot 不要为我们工程中的资源文件建立映射. 这两个配置正是 RESTful 服务所需要的.当加上这两个配置后, 我们再来试一下:
可以看到, 现在确实是在 defaultErrorHandler 中处理了.
本文由 yongshun 发表于个人博客, 采用署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议.非商业转载请注明作者及出处. 商业转载请联系作者本人Email: 本文标题为: SpringBoot RESTful 应用中的异常处理小结本文链接为:
8 收藏&&|&&25
你可能感兴趣的文章
4 收藏,410
11 收藏,16.7k
4 收藏,2.5k
本作品采用 署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可
分享到微博?
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。后台登陆的时候,明明看见后台文件存在,但是浏览器确提示404nofound 不过换个域名又可以正常访问。但是用之前的域名就是nofound,太奇怪了
[问题点数:60分]
后台登陆的时候,明明看见后台文件存在,但是浏览器确提示404nofound 不过换个域名又可以正常访问。但是用之前的域名就是nofound,太奇怪了
[问题点数:60分]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2017年7月 PHP大版内专家分月排行榜第三2017年6月 PHP大版内专家分月排行榜第三2017年5月 PHP大版内专家分月排行榜第三2016年10月 PHP大版内专家分月排行榜第三2016年9月 PHP大版内专家分月排行榜第三2015年10月 PHP大版内专家分月排行榜第三2014年12月 PHP大版内专家分月排行榜第三2014年9月 PHP大版内专家分月排行榜第三
2017年3月 PHP大版内专家分月排行榜第三2016年12月 PHP大版内专家分月排行榜第三2016年11月 PHP大版内专家分月排行榜第三2014年10月 PHP大版内专家分月排行榜第三2014年8月 PHP大版内专家分月排行榜第三2014年3月 PHP大版内专家分月排行榜第三2014年1月 PHP大版内专家分月排行榜第三2012年8月 PHP大版内专家分月排行榜第三2012年2月 PHP大版内专家分月排行榜第三2012年1月 PHP大版内专家分月排行榜第三2011年12月 PHP大版内专家分月排行榜第三2011年11月 PHP大版内专家分月排行榜第三2011年6月 PHP大版内专家分月排行榜第三
匿名用户不能发表回复!|

我要回帖

更多关于 就是不想死 的文章

 

随机推荐