将HttpServletRequest获取到Spring ResponseEntityExceptionHandler中(Get HttpServletRequest into Spring ResponseEntityExceptionHandler)
我有一个使用Spring Boot 2.0.1制作的REST服务器。
我正在自定义扩展ResponseEntityExceptionHandler的异常处理。
这是我的班级
@RestControllerAdvice public class ApplicationExceptionHandler extends ResponseEntityExceptionHandler { private Logger log = LogManager.getLogger(); @Autowired private MessageSource messageSource; private MessageSourceAccessor messageSourceAccessor = null; @PostConstruct public void postConstruct() { Assert.notNull(messageSource, "MessageSource must not be null!"); this.messageSourceAccessor = new MessageSourceAccessor(messageSource); } /** * Mapping each constraint name with the corrispondent exception code -> message */ private static Map<String, ExceptionCode> constraintCodeMap = new HashMap<String, ExceptionCode>() { private static final long serialVersionUID = -628747907324708275L; { put("account_username", ExceptionCode.ACCOUNT_DUPLICATE_USERNAME); put("paymenttype_code", ExceptionCode.PAYMENTTYPE_DUPLICATE_CODE); put("ticketblock_number_type", ExceptionCode.TICKETBLOCK_DUPLICATE_CODE); put("ticket_number", ExceptionCode.TICKET_DUPLICATED_CODE); put("licenseplate_plate", ExceptionCode.LICENSEPLATE_DUPLICATED); } }; @Override protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { return response(HttpStatus.BAD_REQUEST, new HttpHeaders(), buildGenericError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale())); } @Override protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { return response(HttpStatus.BAD_REQUEST, new HttpHeaders(), buildGenericError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale())); } @Override protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { if (ExceptionUtils.getRootCauseMessage(ex).contains("Duplicate entry")) { /** * Custom errors and messages for DataIntegrityViolationException checked against the list of indexes names */ return response(HttpStatus.CONFLICT, new HttpHeaders(), buildIntegrityError(ex, request, HttpStatus.CONFLICT, LocaleContextHolder.getLocale())); } else { return response(HttpStatus.BAD_REQUEST, new HttpHeaders(), buildGenericError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale())); } } /** * @see {@link RepositoryRestExceptionHandler} * * @param ex * @param request * @param locale * @return * @throws Exception */ @ExceptionHandler(DataIntegrityViolationException.class) public ResponseEntity<?> handleConflictException(DataIntegrityViolationException ex, HttpServletRequest request, Locale locale) throws Exception { /** * Keep the default Exception format for Violation exception @see {@link RepositoryRestExceptionHandler} */ if (ex instanceof RepositoryConstraintViolationException) { return response(HttpStatus.BAD_REQUEST, new HttpHeaders(), new RepositoryConstraintViolationExceptionMessage((RepositoryConstraintViolationException) ex, messageSourceAccessor)); } /** * Custom errors and messages for DataIntegrityViolationException checked against the list of indexes names */ return response(HttpStatus.CONFLICT, new HttpHeaders(), buildIntegrityError(ex, request, HttpStatus.CONFLICT, locale)); } /** * Handle the exception when the file size is bigger than the maximum set in the configuration * * @param ex * @param request * @param locale * @return * @throws Exception */ @ExceptionHandler(MaxUploadSizeExceededException.class) public ResponseEntity<?> handleFileUpload(MaxUploadSizeExceededException ex, HttpServletRequest request, Locale locale) throws Exception { log.error(String.format("Received a file too big from %s. Error: %s", AppUtils.getRemoteIp(request), ExceptionUtils.getRootCauseMessage(ex))); return response(HttpStatus.BAD_REQUEST, new HttpHeaders(), buildIntegrityError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale())); } /** * Build a JSON integrity error compliant to the standard exception * * @param exception * @param request * @param httpStatus * @param message * @return */ private JsonException buildIntegrityError(final Throwable exception, final HttpServletRequest request, final HttpStatus httpStatus, Locale locale) { return buildIntegrityError(exception, request.getRequestURI(), httpStatus, locale); } private JsonException buildIntegrityError(final Throwable exception, final WebRequest request, final HttpStatus httpStatus, Locale locale) { return buildIntegrityError(exception, "", httpStatus, locale); } /** * Build a JSON integrity error compliant to the standard exception * */ private JsonException buildIntegrityError(final Throwable exception, String requestUri, final HttpStatus httpStatus, Locale locale) { String finalMessage = ""; String rootMsg = ExceptionUtils.getRootCauseMessage(exception); Optional<Map.Entry<String, ExceptionCode>> entry = constraintCodeMap.entrySet().stream() .filter((it) -> rootMsg.contains(it.getKey())).findAny(); if (entry.isPresent()) { finalMessage = messageSource.getMessage(entry.get().getValue().getCode(), new Object[] {}, locale); } else { finalMessage = messageSource.getMessage(ExceptionCode.INTEGRITY_VIOLATION.getCode(), new Object[] { rootMsg }, locale); } JsonException jsonException = new JsonException(); jsonException.setError(httpStatus.getReasonPhrase()); jsonException.setStatus(httpStatus.value()); jsonException.setException(exception.getClass().getName()); jsonException.setMessage(finalMessage); jsonException.setPath(requestUri); return jsonException; } /** * Build a JSON integrity error compliant to the standard exception * * @param exception * @param request * @param httpStatus * @param message * @return */ private JsonException buildGenericError(final Throwable exception, final HttpServletRequest request, final HttpStatus httpStatus, Locale locale) { String rootMsg = ExceptionUtils.getRootCauseMessage(exception); String finalMessage = messageSource.getMessage(ExceptionCode.INTERNAL_ERROR.getCode(), new Object[] { rootMsg }, locale); JsonException jsonException = new JsonException(); jsonException.setError(httpStatus.getReasonPhrase()); jsonException.setStatus(httpStatus.value()); jsonException.setException(exception.getClass().getName()); jsonException.setMessage(finalMessage); jsonException.setPath(request.getRequestURI()); return jsonException; } private JsonException buildGenericError(final Throwable exception, final WebRequest request, final HttpStatus httpStatus, Locale locale) { String rootMsg = ExceptionUtils.getRootCauseMessage(exception); String finalMessage = messageSource.getMessage(ExceptionCode.INTERNAL_ERROR.getCode(), new Object[] { rootMsg }, locale); JsonException jsonException = new JsonException(); jsonException.setError(httpStatus.getReasonPhrase()); jsonException.setStatus(httpStatus.value()); jsonException.setException(exception.getClass().getName()); jsonException.setMessage(finalMessage); jsonException.setPath(""); return jsonException; } private static <T> ResponseEntity<T> response(HttpStatus status, HttpHeaders headers, T body) { Assert.notNull(headers, "Headers must not be null!"); Assert.notNull(status, "HttpStatus must not be null!"); return new ResponseEntity<T>(body, headers, status); } }
我想重写
HttpMessageNotReadableException
的行为,但我必须重写方法handleHttpMessageNotReadable
因为它是由超类管理的异常,我无法创建使用@ExceptionHandler注释的方法。问题是该方法暴露
WebRequest
而不是HttpServletRequest
。 我需要一个HttpServletRequest
来获取客户端的远程IP地址。有没有办法做我所做的
DataIntegrityViolationException
在我的类中,我可以得到HttpServletRequest
?I've a REST server made with Spring Boot 2.0.1.
I'm customizing exception handling extending ResponseEntityExceptionHandler.
This is my class
@RestControllerAdvice public class ApplicationExceptionHandler extends ResponseEntityExceptionHandler { private Logger log = LogManager.getLogger(); @Autowired private MessageSource messageSource; private MessageSourceAccessor messageSourceAccessor = null; @PostConstruct public void postConstruct() { Assert.notNull(messageSource, "MessageSource must not be null!"); this.messageSourceAccessor = new MessageSourceAccessor(messageSource); } /** * Mapping each constraint name with the corrispondent exception code -> message */ private static Map<String, ExceptionCode> constraintCodeMap = new HashMap<String, ExceptionCode>() { private static final long serialVersionUID = -628747907324708275L; { put("account_username", ExceptionCode.ACCOUNT_DUPLICATE_USERNAME); put("paymenttype_code", ExceptionCode.PAYMENTTYPE_DUPLICATE_CODE); put("ticketblock_number_type", ExceptionCode.TICKETBLOCK_DUPLICATE_CODE); put("ticket_number", ExceptionCode.TICKET_DUPLICATED_CODE); put("licenseplate_plate", ExceptionCode.LICENSEPLATE_DUPLICATED); } }; @Override protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { return response(HttpStatus.BAD_REQUEST, new HttpHeaders(), buildGenericError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale())); } @Override protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { return response(HttpStatus.BAD_REQUEST, new HttpHeaders(), buildGenericError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale())); } @Override protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { if (ExceptionUtils.getRootCauseMessage(ex).contains("Duplicate entry")) { /** * Custom errors and messages for DataIntegrityViolationException checked against the list of indexes names */ return response(HttpStatus.CONFLICT, new HttpHeaders(), buildIntegrityError(ex, request, HttpStatus.CONFLICT, LocaleContextHolder.getLocale())); } else { return response(HttpStatus.BAD_REQUEST, new HttpHeaders(), buildGenericError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale())); } } /** * @see {@link RepositoryRestExceptionHandler} * * @param ex * @param request * @param locale * @return * @throws Exception */ @ExceptionHandler(DataIntegrityViolationException.class) public ResponseEntity<?> handleConflictException(DataIntegrityViolationException ex, HttpServletRequest request, Locale locale) throws Exception { /** * Keep the default Exception format for Violation exception @see {@link RepositoryRestExceptionHandler} */ if (ex instanceof RepositoryConstraintViolationException) { return response(HttpStatus.BAD_REQUEST, new HttpHeaders(), new RepositoryConstraintViolationExceptionMessage((RepositoryConstraintViolationException) ex, messageSourceAccessor)); } /** * Custom errors and messages for DataIntegrityViolationException checked against the list of indexes names */ return response(HttpStatus.CONFLICT, new HttpHeaders(), buildIntegrityError(ex, request, HttpStatus.CONFLICT, locale)); } /** * Handle the exception when the file size is bigger than the maximum set in the configuration * * @param ex * @param request * @param locale * @return * @throws Exception */ @ExceptionHandler(MaxUploadSizeExceededException.class) public ResponseEntity<?> handleFileUpload(MaxUploadSizeExceededException ex, HttpServletRequest request, Locale locale) throws Exception { log.error(String.format("Received a file too big from %s. Error: %s", AppUtils.getRemoteIp(request), ExceptionUtils.getRootCauseMessage(ex))); return response(HttpStatus.BAD_REQUEST, new HttpHeaders(), buildIntegrityError(ex, request, HttpStatus.BAD_REQUEST, LocaleContextHolder.getLocale())); } /** * Build a JSON integrity error compliant to the standard exception * * @param exception * @param request * @param httpStatus * @param message * @return */ private JsonException buildIntegrityError(final Throwable exception, final HttpServletRequest request, final HttpStatus httpStatus, Locale locale) { return buildIntegrityError(exception, request.getRequestURI(), httpStatus, locale); } private JsonException buildIntegrityError(final Throwable exception, final WebRequest request, final HttpStatus httpStatus, Locale locale) { return buildIntegrityError(exception, "", httpStatus, locale); } /** * Build a JSON integrity error compliant to the standard exception * */ private JsonException buildIntegrityError(final Throwable exception, String requestUri, final HttpStatus httpStatus, Locale locale) { String finalMessage = ""; String rootMsg = ExceptionUtils.getRootCauseMessage(exception); Optional<Map.Entry<String, ExceptionCode>> entry = constraintCodeMap.entrySet().stream() .filter((it) -> rootMsg.contains(it.getKey())).findAny(); if (entry.isPresent()) { finalMessage = messageSource.getMessage(entry.get().getValue().getCode(), new Object[] {}, locale); } else { finalMessage = messageSource.getMessage(ExceptionCode.INTEGRITY_VIOLATION.getCode(), new Object[] { rootMsg }, locale); } JsonException jsonException = new JsonException(); jsonException.setError(httpStatus.getReasonPhrase()); jsonException.setStatus(httpStatus.value()); jsonException.setException(exception.getClass().getName()); jsonException.setMessage(finalMessage); jsonException.setPath(requestUri); return jsonException; } /** * Build a JSON integrity error compliant to the standard exception * * @param exception * @param request * @param httpStatus * @param message * @return */ private JsonException buildGenericError(final Throwable exception, final HttpServletRequest request, final HttpStatus httpStatus, Locale locale) { String rootMsg = ExceptionUtils.getRootCauseMessage(exception); String finalMessage = messageSource.getMessage(ExceptionCode.INTERNAL_ERROR.getCode(), new Object[] { rootMsg }, locale); JsonException jsonException = new JsonException(); jsonException.setError(httpStatus.getReasonPhrase()); jsonException.setStatus(httpStatus.value()); jsonException.setException(exception.getClass().getName()); jsonException.setMessage(finalMessage); jsonException.setPath(request.getRequestURI()); return jsonException; } private JsonException buildGenericError(final Throwable exception, final WebRequest request, final HttpStatus httpStatus, Locale locale) { String rootMsg = ExceptionUtils.getRootCauseMessage(exception); String finalMessage = messageSource.getMessage(ExceptionCode.INTERNAL_ERROR.getCode(), new Object[] { rootMsg }, locale); JsonException jsonException = new JsonException(); jsonException.setError(httpStatus.getReasonPhrase()); jsonException.setStatus(httpStatus.value()); jsonException.setException(exception.getClass().getName()); jsonException.setMessage(finalMessage); jsonException.setPath(""); return jsonException; } private static <T> ResponseEntity<T> response(HttpStatus status, HttpHeaders headers, T body) { Assert.notNull(headers, "Headers must not be null!"); Assert.notNull(status, "HttpStatus must not be null!"); return new ResponseEntity<T>(body, headers, status); } }
I want to override the behaviour for
HttpMessageNotReadableException
but I have to Override the methodhandleHttpMessageNotReadable
because it is an exception managed by the superclass and I can't create my method annotated with @ExceptionHandler.The problem is the method exposes
WebRequest
instead of aHttpServletRequest
. I need aHttpServletRequest
to get the remote ip address of the client.Is there a way to do what I did for
DataIntegrityViolationException
in my class where I can get theHttpServletRequest
?
原文:https://stackoverflow.com/questions/50254334
最满意答案
您可以在
.htaccess
或配置文件中使用它:Options -MultiViews
You can use this in your
.htaccess
or config file :Options -MultiViews
相关问答
更多-
好的,这是最终奏效的。 我需要对apache2文件进行一些编辑,以使所有内容协同工作。 这假设您使用某种形式的Linux在您的服务器上运行apache2版本2+。 编辑/etc/apache2/sites-available/000-default.conf以获得以下行,只需将它们附加到末尾(我将它们放在此行之后: # vim: syntax=apache ts=4 sw=4 sts=4 sr noet )。
Options Indexes FollowSy ... -
使用htaccess从url中的任何位置删除文件扩展名(removing file extension from anywhere in the the url with htaccess)[2022-05-06]
只需删除您的规则,并将此行放在您的.htaccess之上,即可在您网站上的任何位置免费访问您的网页: Options +MultiViews Just remove your rule and have this line on top of your .htaccess to extension-less access to you pages anywhere on your site: Options +MultiViews -
防止在url末尾自动添加扩展名(htaccess?)(Prevent extension automatically added at the end of url (htaccess ?))[2021-12-24]
您可以在.htaccess或配置文件中使用它: Options -MultiViews You can use this in your .htaccess or config file : Options -MultiViews -
使用htaccess从url中删除子文件夹名称和文件扩展名(removing subfolder name and file extension from url using htaccess)[2022-02-02]
在我的根文件夹的.htaccess中,使用它 RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^((?!seo/).*)$ seo/$1 [L,NC] 在/seo/ .htaccess中,使用: RewriteEngine On RewriteBase /seo/ RewriteCond %{DOCUMENT_ROOT}/seo/$1\.html - ... -
您可以使用: Options -MultiViews # Redirect to .php RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ^ %{REQUEST_URI}.php [R=301,L] You can use: Options -MultiViews # Redirect to .php RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ^ %{REQUEST_URI}.php [ ...
-
你需要使用这个规则:与大多数其他语言不同, .htaccess中的参数不是基于0的。 要访问第一个参数,您应该使用$1 ,而不是$0 。 以下应该有效: RewriteRule ^blog/(.*)$ blog/index.php?art=$1 [L] 在那里添加一些测试也可能是值得的,例如,您可能只希望将数值传递给art ,因此您可以使用以下方法来改进它: RewriteRule ^blog/([0-9]+)$ blog/index.php?art=$1 [L] 此外,添加QSA标志可能是值得的,因为这还将保留在原始UR ...我在其他地方找到了这个解 RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.html -f RewriteRule ^(.*)$ $1.html 来源:1) http://www.catswhocode.com/blog/10-useful-htaccess-snippets-to-have-in-your-toolbox 2) http://eisabainyo.net/weblog ...您需要一个额外的规则来将foo.html从外部重定向到foo 。 你的.htaccess是这样的: RewriteEngine on RewriteCond %{THE_REQUEST} \s/+(.+?)\.html[\s?] [NC] RewriteRule ^ /%1? [R=301,L] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{DOCUMENT_ROOT}/$1.html -f RewriteRule ^(.+?)/?$ /$1.htm ...试试以下内容。 我还简化了你的代码(首先检查www. ,然后删除index.html ,然后添加.html扩展名,如果文件实际存在。) ErrorDocument 404 /404.html
RewriteEngine On # Force www. RewriteCond %{HTTP_HOST} ^domain\.com [NC] RewriteRule ^(.*)$ http://www.domain.com/$1 ... 相关文章
更多- Spring MVC 3 深入总结
- maven项目使用SOLR时报 previously initiated loading for a different type with name "javax/servlet/http/HttpServletRequest" 错的解决方法
- 精通Spring
- 《Spring Security 3》 【第二章】 Spring Security起步(3)
- 什么是Spring Cloud
- spring 疑问
- Spring与Hibernate集成中的session问题
- Spring与工厂模式
- 快速了解Spring Boot
- 问个spring annotation的问题
最新问答
更多- 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
- 如何通过引用返回对象?(How is returning an object by reference possible?)
- 矩阵如何存储在内存中?(How are matrices stored in memory?)
- 每个请求的Java新会话?(Java New Session For Each Request?)
- css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
- 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
- xcode语法颜色编码解释?(xcode syntax color coding explained?)
- 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
- 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
- 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
- 西安哪有PLC可控制编程的培训
- 在Entity Framework中选择基类(Select base class in Entity Framework)
- 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
- 电脑二级VF有什么用
- Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
- 金华英语角.
- 手机软件如何制作
- 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
- 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
- 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
- Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
- 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
- python的访问器方法有哪些
- DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
- 在Ruby中对组合进行排序(Sorting a combination in Ruby)
- 网站开发的流程?
- 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
- 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
- 透明度错误IE11(Transparency bug IE11)
- linux的基本操作命令。。。