SpringMVC校验数据方式总结(含示例源码)

SpringMVC对于提交表单(form submit)的数据校验与异常信息回显,个人常用有两种方式

方式一:使用Validator接口,实现Validator接口并编写校验的代码,

1

Validator是一个单独类处理,示例源码链接:https://gitee.com/shengzhao/spring-oauth-server/tree/1.0/src/main/java/com/monkeyk/sos/web/controller

在使用时示例如下:

2

示例源码链接:https://gitee.com/shengzhao/spring-oauth-server/blob/1.0/src/main/java/com/monkeyk/sos/web/controller/UserController.java

此方式简单明了,validator与controller分开。

 

方式二:使用全注解,需要扩展实现一些业务需要的数据校验(此文重点)

不需要额外增加一个类来处理,注解加在Model对象属性中,

3

UserFormDto是一个Model对象,@Size, @NotBlank,@Length, @Email为 java validation API中定义的注解类型,

示例源码链接:https://gitee.com/mkk/MyOIDC/blob/1.1.0/myoidc-server/src/main/java/myoidc/server/service/dto/UserFormDto.java

@UsernameValidation 是扩展自定义实现的数据校验(主要增加业务逻辑,如此处username要求唯一),其具体实现为:

5

其实现的关键是 UsernameValidator.java的实现,如下:

6

UsernameValidator实现ConstraintValidatior接口并提供实现,在isValid()方法中实现具体业务逻辑,返回true表示校验成功

示例源码链接:https://gitee.com/mkk/MyOIDC/tree/1.1.0/myoidc-server/src/main/java/myoidc/server/service/validation

 

——————————–

对于表单校验异常后的展示,SpringMVC提供了一套页面标签实现,如果是JSP页面,示例如下:

8

示例源码链接:https://gitee.com/shengzhao/spring-oauth-server/blob/config/src/main/webapp/WEB-INF/jsp/user_form.jsp

如果是 SpringBoot中的 thymeleaf,示例如下:

7

示例源码链接:https://gitee.com/mkk/MyOIDC/blob/1.1.0/myoidc-server/src/main/webapp/WEB-INF/view/admin/user_form.html

(页面展示的标签方式有多种形式,可根据实际需要进行选择,如可以针对单个的字段进行异常显示)

 

Spring-Boot工程自定义配置http状态码404,500页面

Spring-Boot工程默认出现404,500时的页面如下:

error-404

但是这样不够友好,若需要自定义配置http状态码出现404,500时的页面,最有效的方式是写一个bean实现
ErrorViewResolver接口,实现 resolveErrorView()方法,根据status状态来判断处理,并返回对应的ModelAndView即可,
一个示例实现如下:
error-view-resolver

参数model中可获取异常状态时的属性,包括status(状态码),error(异常信息),path(异常出现的路径),message(描述信息).

spring-oauth-server 2.0.0 发布,使用Spring-Boot2.0实现

经过一年多的时间后,我们发布了 spring-oauth-server 2.0.0版本.

使用Spring-Boot 2.0版本重构, 进入模块化,零配置时代. 更符合技术发展与实际需要.

相比之前的版本(1.0及之前版本), 更新如下:

1. 全新的 Spring-Boot风格

2.ClientDetails中的 client_secret 字段加密保存

3.密码加密方式由MD5变成 BCrypt

4.增加CSRF机制支持

5.resourceId变为可选(但建议使用固定的resourceId)

https://gitee.com/shengzhao/spring-oauth-server/tree/2.0.0/

Java HeartBeat 2.0.0 发布,心跳检测应用服务器的Spring-Boot程序

Java HeartBeat 2.0.0版本已经发布, 使用Spring-Boot框架, 全新的”零配置”设计,向微服务化靠近,抛掉沉重的XML配置文件.Java HeartBeat 是心跳检测应用服务器(如 Tomcat,Jetty)的 Java Web 应用程序。

2.0.0版本主要更新如下:

1).使用 Spring-Boot 框架重构, 向微服务靠近
2).使用log4j2替换旧的log4j
3).更新登录页面样式,增加版本显示
4).单元测试使用Junit替换旧的TestNG
5).Sitemesh使用3.0版本替换2.0版本

HeartBeat 2.0.0版本访问地址: https://gitee.com/mkk/HeartBeat/tree/V-2.0.0/

https://gitee.com/mkk/HeartBeat

Java HeartBeat 1.0.0 发布

在经历近一年的不知所措后(2016-08-15到2017-07-09), 更新了 HeartBeat 1.0.0 版本,Java HeartBeat是心跳检测应用服务器(如Tomcat,Jetty)的JAVA WEB应用程序。

1.0.0版本主要是功能完善与修复BUG, 主要内容如下:

1).添加更多监控时间,如2分钟,3分钟,5分钟,10分钟,半小时,1小时
2).Fix 设置多次失败后在提醒时的错误,以及恢复后的提醒
3).增加设置定期清理一段时间(默认为30天)前的监控日志记录,防止frequency_monitor_log表太大导致查询慢
4).修复未登录时不能查看到私有实例的日志
5).Fixed Issue #26 关于邮件发送次数的问题

 

HeartBeat 1.0.0版本访问地址: http://git.oschina.net/mkk/HeartBeat/tree/V-1.0.0/

http://git.oschina.net/mkk/HeartBeat

Java HeartBeat 0.5-beta2 发布

HeartBeat 0.5版本的第二个版本 0.5-beta2发布了,Java HeartBeat是心跳检测应用服务器(如Tomcat,Jetty)的JAVA WEB应用程序.

0.5-beta2版本相比0.5-beta1主要增加一些实用的功能, 具体更新如下:

1. (148) – 在检测链接状态的时候,不要发现一次链接故障的时候就马上发邮件通知,这个过程可能因为网络故障(如常见的:丢包、dns故障)而出现问题, 可以增加一个判断参数,当连续发现n次有故障时再去发邮箱等信息通知!(ISSUE #19)

2. (156) – 优化数据库,以及连接, 提高性能,页面响应速度

HeartBeat 0.5-beta2 的访问地址: http://git.oschina.net/mkk/HeartBeat/tree/V-0.5-beta2

在线测试地址: https://andaily.com/hb/

该版本是0.5的最后一个beta版本, 待测试,校验稳定后,将正式发布0.5-release版本

http://git.oschina.net/mkk/HeartBeat

spring-oauth-server中添加 resource 的配置

resource,资源, resource-id资源ID, 在spring-oauth-server中添加 client details时有两个resource可以选择(mobile-resource, unity-resource); 这些resource-id从哪来的呢? 如果我需要添加自己的resource将如何办呢, 请继续向下看.

resource用于将系统提供的各类资源进行分组管理,每一个resource对应一个resource-id, 而一个client details至少要有一个resource-id(对应OauthClientDetails.java中的resourceIds字段).

在spring-oauth-server的security.xml配置文件的70行左右, 你会看到两行配置,如下:

<!--unity resource server filter-->
<oauth2:resource-server id="unityResourceServer" resource-id="unity-resource" token-services-ref="tokenServices"/>

<!--mobile resource server filter-->
<oauth2:resource-server id="mobileResourceServer" resource-id="mobile-resource" token-services-ref="tokenServices"/>

这儿就是配置resource的地方, 看见里面的两个resource-id值.

在这配置往上, 能看见两个<http>的配置, 一个的pattern为/m/**, 另一个为/unity/**, 这就是资源与Spring Security整合后的配置, 注意每个<http>配置里的 ROLE_UNITY与ROLE_MOBILE, 这对应Spring Security的权限; 截图如下:

resource-config

有了以上基础, 及下看我们要添加一个自己的resource, 假设resource-id = myResource, url pattern为/my/api/**, 权限为ROLE_MY_RESOURCE, scope为 read; 其配置如下:

1.添加<oauth2:resource-server> , resource-id=myResource, 如下:

<oauth2:resource-server id="myResourceServer" resource-id="myResource" token-services-ref="tokenServices"/>

注意, id值需要唯一
2.添加<http>配置, 如下:

<http pattern="/my/api/**" create-session="never" entry-point-ref="oauth2AuthenticationEntryPoint"
      access-decision-manager-ref="oauth2AccessDecisionManager" use-expressions="false">
    <anonymous enabled="false"/>

    <intercept-url pattern="/my/api/**" access="ROLE_MY_RESOURCE,SCOPE_READ"/>

    <custom-filter ref="myResourceServer" before="PRE_AUTH_FILTER"/>
    <access-denied-handler ref="oauth2AccessDeniedHandler"/>
    <csrf disabled="true"/>
</http>

说明: 一个<resource-server>可以配置多个<http>, 使用不同的url pattern

OK, 配置完成, 新增resource: myResource; 这时候, 所有以/my/api/** 开头的URL请求都将受到 OAUTH2的保护, 及下来在业务中创建client details, 记得把resourceIds设置为myResource,且要有ROLE_MY_RESOURCE的权限.

 

spring-oauth-server

spring-oauth-server 0.5 发布,OAuth2 与 Spring Security 安全应用整合

spring-oauth-server 0.5版本发布,该版本的功能更新如下:

  • (144) – Add MongoDB branch
  • (143) – Add project API document
  • (139) – User Overview/ user add/archive
  • (138) – OAuth Restful API
  • (118) – Add java-config(零配置) 的支持, 以及启用 新的注解.

spring-oauth-server 是一个整合OAuth2与Spring Security的安全应用项目,是从https://github.com/spring-projects/spring-security-oauth/tree/master/spring-security-oauth2扩展的符合实际项目需要的开源项目,可扩展为SSO解决方案。

0.5版本访问地址: http://git.oschina.net/shengzhao/spring-oauth-server/tree/0.5/

oauth2-shiro中将authz与resources模块合并到一个项目中如何配置

oauth2-shiro的设计是分模块, 将authz与resources分成不同的子项目来实现. 但现实中有时需要将其合成一个项目, 对于此类场景中,该如何配置security, 具体如下:

1. 在security配置中使用OAuth2CredentialsMatcher类替换authz模块中的HashedCredentialsMatcher与resources模块中的SimpleCredentialsMatcher配置; 具体的配置可参考OAuth2CredentialsMatcher.java类的中注释.

2.在配置ShiroFilterFactoryBean中的filterChainDefinitions的value中添加

/oauth/** = anon

(另外注意合并时的url pattern不要有重复)

配置示例图
OAuth2CredentialsMatcher

注意截图中的OAuth2JdbcRealm只用于resources模块, 在合并后不能使用, 使用其父类MkkJdbcRealm.
http://git.oschina.net/mkk/oauth2-shiro

解决Spring Security 表单上传文件CSRF失效的问题

在Spring Security4中引入的CSRF是不错的安全机制. 但在常用的上传文件中(form提交, post, 使用commons-fileupload)会导致CSRF失效,

这问题的根源在于CSRF无法获取表单中的_csrf 的值引起的(可在CsrfFilter打断点查看).

之前我也被这问题困惑了一天, 不知如何是好.

解决之道如下:

1.升级项目中使用的Servlet API版本至3.0及以上.

2.不要使用commons-fileupload组件,即CommonsMultipartResolver , 而使用Servelt提供的组件对象StandardServletMultipartResolver

其在Spring MVC中的配置如下:

<bean id=”multipartResolver”
class=”org.springframework.web.multipart.support.StandardServletMultipartResolver”>
</bean>

3.在Spring MVC的DispatchServlet配置中添加如下配置(web.xml中)

<multipart-config>
<!–location>/tmp</location–>
<max-file-size>1000000</max-file-size>
</multipart-config>

其中的<max-file-size>即限制上传文件的大小. 完整的DispatchServelt配置如下:

<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
<multipart-config>
<!–location>/tmp</location–>
<max-file-size>1000000</max-file-size>
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

 

注意在升级Servlet API后需要将web.xml的状况声明也更新为3.0的,如下:

<?xml version=”1.0″ encoding=”UTF-8″?>
<web-app xmlns=”http://java.sun.com/xml/ns/javaee” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd”
version=”3.0″>

 

至此, CSRF工作正常.

分析大概的原因是commons-fileupload组件对request进行封装时对CSRF的支持有问题. 没将_csrf值传递.

参考文章: http://stackoverflow.com/questions/25185578/spring-security-3-2-csrf-and-multipart-requests