当前位置: 首页 > news >正文

网站建设策划书模板武进做网站

网站建设策划书模板,武进做网站,做期货应关注什么网站,怎样改变wordpress的封面转载自#xff1a;https://my.oschina.net/huangyong/blog/521891 从MVC到前后端分离 1.理解 MVC MVC是一种经典的设计模式#xff0c;全名为Model-View-Controller#xff0c;即模型-视图-控制器。其中#xff0c;模型是用于封装数据的载体#xff0c;例如#xff0c;在…转载自https://my.oschina.net/huangyong/blog/521891 从MVC到前后端分离 1.理解 MVC MVC是一种经典的设计模式全名为Model-View-Controller即模型-视图-控制器。其中模型是用于封装数据的载体例如在Java 中一般通过一个简单的POJOPlain Ordinary Java Object来表示其本质是一个普通的 Java Bean包含一系列的成员变量及其 getter/setter方法。对于视图而言它更加偏重于展现也就是说视图决定了界面到底长什么样子在 Java 中可通过JSP 来充当视图或者通过纯 HTML的方式进行展现而后者才是目前的主流。模型和视图需要通过控制器来进行粘合例如用户发送一个HTTP 请求此时该请求首先会进入控制器然后控制器去获取数据并将其封装为模型最后将模型传递到视图中进行展现。综上所述MVC 的交互过程如下图所示 2 MVC模式的优点与不足MVC模式早在上个世纪70年代就诞生了直到今天它依然存在可见生命力相当之强。MVC 模式最早用于Smalltalk语言中最后在其它许多开发语言中都得到了很好的应用例如Java 中的 Struts、Spring MVC等框架。正是因为这些MVC框架的出现才让MVC模式真正落地让开发更加高效让代码耦合度尽量减小让应用程序各部分的职责更加清晰。既然MVC模式这么好难道它就没有不足的地方吗我认为MVC至少有以下三点不足1)每次请求必须经过“控制器-模型-视图”这个流程用户才能看到最终的展现的界面这个过程似乎有些复杂。2)实际上视图是依赖于模型的换句话说如果没有模型视图也无法呈现出最终的效果。3)渲染视图的过程是在服务端来完成的最终呈现给浏览器的是带有模型的视图页面性能无法得到很好的优化。为了使数据展现过程更加直接并且提供更好的用户体验我们有必要对MVC模式进行改进。不妨这样来尝试首先从浏览器发送 AJAX 请求然后服务端接受该请求并返回 JSON 数据返回给浏览器最后在浏览器中进行界面渲染。改进后的 MVC 模式如下图所示   也就是说我们输入的是AJAX请求输出的是JSON数据市面上有这样的技术来实现这个功能吗答案是 REST。 REST 全称是 Representational State Transfer表述性状态转移它是 Roy Fielding 博士在 2000 年写的一篇关于软件架构风格的论文此文一出威震四方国内外许多知名互联网公司纷纷开始采用这种轻量级的 Web 服务大家习惯将其称为 RESTful Web Services或简称 REST 服务。 如果将浏览器这一端视为前端而服务器那一端视为后端的话可以将以上改进后的MVC模式简化为以下前后端分离模式   可见有了REST服务前端关注界面展现后端关注业务逻辑分工明确职责清晰。那么如何使用 REST 服务将应用程序进行前后端分离呢我们接下来继续探讨首先我们需要认识 REST。 3 认识 REST REST本质上是使用 URL 来访问资源种方式。众所周知URL 就是我们平常使用的请求地址了其中包括两部分请求方式与请求路径比较常见的请求方式是GET与POST但在REST中又提出了几种其它类型的请求方式汇总起来有六种GET、POST、PUT、DELETE、HEAD、OPTIONS。尤其是前四种正好与 CRUDCreate-Retrieve-Update-Delete增删改查四种操作相对应例如GET查、POST增、PUT改、DELETE删这正是 REST 与 CRUD 的异曲同工之妙需要强调的是REST 是“面向资源”的这里提到的资源实际上就是我们常说的领域对象在系统设计过程中我们经常通过领域对象来进行数据建模。 REST 是一个“无状态”的架构模式因为在任何时候都可以由客户端发出请求到服务端最终返回自己想要的数据当前请求不会受到上次请求的影响。也就是说服务端将内部资源发布REST服务客户端通过URL来访问这些资源这不就是SOA所提倡的“面向服务”的思想吗所以REST也被人们看做是一种“轻量级”的 SOA 实现技术因此在企业级应用与互联网应用中都得到了广泛应用。  下面我们举几个例子对 REST 请求进行简单描述   REST 请求描述GET:/advertisers获取所有的广告主GET:/advertiser/1获取 ID 为 1 的广告主PUT:/advertiser/1更新 ID 为 1 的广告主DELETE:/advertiser/1删除 ID 为 1 的广告主POST:/advertiser创建广告主可见请求路径相同但请求方式不同所代表的业务操作也不同例如/advertiser/1 这个请求带有 GET、PUT、DELETE 三种不同的请求方式对应三种不同的业务操作。 虽然 REST 看起来还是很简单的实际上我们往往需要提供一个 REST 框架让其实现前后端分离架构让开发人员将精力集中在业务上而并非那些具体的技术细节。下面我们将使用 Java 技术来实现这个 REST 框架整体框架会基于 Spring 进行开发。 4 实现 REST 框架 4.1 统一响应结构 使用 REST 框架实现前后端分离架构我们需要首先确定返回的JSON响应结构是统一的也就是说每个REST请求将返回相同结构的JSON响应结构。不妨定义一个相对通用的 JSON 响应结构其中包含两部分元数据与返回值其中元数据表示操作是否成功与返回值消息等返回值对应服务端方法所返回的数据。该 JSON 响应结构如下  {meta: {success: true,message: ok},data: ... } 为了在框架中映射以上 JSON 响应结构我们需要编写一个 Response 类与其对应 public class Response {private static final String OK ok;private static final String ERROR error;private Meta meta;private Object data;public Response success() {this.meta new Meta(true, OK);return this;}public Response success(Object data) {this.meta new Meta(true, OK);this.data data;return this;}public Response failure() {this.meta new Meta(false, ERROR);return this;}public Response failure(String message) {this.meta new Meta(false, message);return this;}public Meta getMeta() {return meta;}public Object getData() {return data;}public class Meta {private boolean success;private String message;public Meta(boolean success) {this.success success;}public Meta(boolean success, String message) {this.success success;this.message message;}public boolean isSuccess() {return success;}public String getMessage() {return message;}} } 以上 Response 类包括两类通用返回值消息ok 与 error还包括两个常用的操作方法success( ) 与 failure( )通过一个内部类来展现元数据结构我们在下文中多次会使用该 Response 类。 实现该 REST 框架需要考虑许多问题首当其冲的就是对象序列化问题。  4.2 实现对象序列化 想要解释什么是 对象序列化不妨通过一些例子进行说明。比如在服务端从数据库中获取了数据此时该数据是一个普通的 Java 对象然后需要将这个Java 对象转换为JSON 字符串并将其返回到浏览器中进行渲染这个转换过程称为序列化再比如通过浏览器发送了一个普通的 HTTP 请求该请求携带了一个 JSON 格式的参数在服务端需要将该 JSON 参数转换为普通的 Java 对象这个转换过程称为反序列化。不管是序列化还是反序列化我们一般都称为序列化。 实际上Spring MVC 已经为我们提供了这类序列化特性只需在 Controller 的方法参数中使用 RequestBody 注解定义需要反序列化的参数即可如以下代码片段 Controller public class AdvertiserController {RequestMapping(value /advertiser, method RequestMethod.POST)public Response createAdvertiser(RequestBody AdvertiserParam advertiserParam) {...} } 若需要对 Controller 的方法返回值进行序列化则需要在该返回值上使用 ResponseBody 注解来定义如以下代码片段 Controller public class AdvertiserController {RequestMapping(value /advertiser/{id}, method RequestMethod.GET)public ResponseBody Response getAdvertiser(PathVariable(id) String advertiserId) {...} } 当然ResponseBody 注解也可以定义在类上这样所有的方法都继承了该特性。由于经常会使用到 ResponseBody 注解所以 Spring 提供了一个名为 RestController 的注解来取代以上的 Controller 注解这样我们就可以省略返回值前面的 ResponseBody 注解了但参数前面的 RequestBody 注解是无法省略的。实际上看看 Spring 中对应 RestController 注解的源码便可知晓 Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Documented Controller ResponseBody public interface RestController {String value() default ; } 可见RestController 注解已经被 Controller 与 ResponseBody 注解定义过了Spring 框架会识别这类注解。需要注意的是该特性在 Spring 4.0 中才引入。 因此我们可将以上代码进行如下改写  RestController public class AdvertiserController {RequestMapping(value /advertiser, method RequestMethod.POST)public Response createAdvertiser(RequestBody AdvertiserParam advertiserParam) {...}RequestMapping(value /advertiser/{id}, method RequestMethod.GET)public Response getAdvertiser(PathVariable(id) String advertiserId) {...} } 除了使用注解来定义序列化行为以外我们还需要使用 Jackson 来提供 JSON 的序列化操作在 Spring 配置文件中只需添加以下配置即可 mvc:annotation-drivenmvc:message-convertersbean classorg.springframework.http.converter.json.MappingJackson2HttpMessageConverter//mvc:message-converters /mvc:annotation-driven 若需要对 Jackson 的序列化行为进行定制比如排除值为空属性、进行缩进输出、将驼峰转为下划线、进行日期格式化等这又如何实现呢 首先我们需要扩展 Jackson 提供的 ObjectMapper 类代码如下 public class CustomObjectMapper extends ObjectMapper {private boolean camelCaseToLowerCaseWithUnderscores false;private String dateFormatPattern;public void setCamelCaseToLowerCaseWithUnderscores(boolean camelCaseToLowerCaseWithUnderscores) {this.camelCaseToLowerCaseWithUnderscores camelCaseToLowerCaseWithUnderscores;}public void setDateFormatPattern(String dateFormatPattern) {this.dateFormatPattern dateFormatPattern;}public void init() {// 排除值为空属性setSerializationInclusion(JsonInclude.Include.NON_NULL);// 进行缩进输出configure(SerializationFeature.INDENT_OUTPUT, true);// 将驼峰转为下划线if (camelCaseToLowerCaseWithUnderscores) {setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);}// 进行日期格式化if (StringUtil.isNotEmpty(dateFormatPattern)) {DateFormat dateFormat new SimpleDateFormat(dateFormatPattern);setDateFormat(dateFormat);}} } 然后将 CustomObjectMapper 注入到 MappingJackson2HttpMessageConverter 中Spring 配置如下 bean idobjectMapper classcom.xxx.api.json.CustomObjectMapper init-methodinitproperty namecamelCaseToLowerCaseWithUnderscores valuetrue/property namedateFormatPattern valueyyyy-MM-dd HH:mm:ss/ /beanmvc:annotation-drivenmvc:message-convertersbean classorg.springframework.http.converter.json.MappingJackson2HttpMessageConverterproperty nameobjectMapper refobjectMapper//bean/mvc:message-converters /mvc:annotation-driven 通过以上过程我们已经完成了一个基于 Spring MVC 的 REST 框架只不过该框架还非常单薄还缺乏很多关键性特性尤其是异常处理。 4.3 处理异常行为 在 Spring MVC 中我们可以使用 AOP 技术编写一个全局的异常处理切面类用它来统一处理所有的异常行为在 Spring 3.2 中才开始提供。使用法很简单只需定义一个类并通过 ControllerAdvice 注解将其标注即可同时需要使用 ResponseBody 注解表示返回值可序列化为 JSON 字符串。代码如下 ControllerAdvice ResponseBody public class ExceptionAdvice {/*** 400 - Bad Request*/ResponseStatus(HttpStatus.BAD_REQUEST)ExceptionHandler(HttpMessageNotReadableException.class)public Response handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {logger.error(参数解析失败, e);return new Response().failure(could_not_read_json);}/*** 405 - Method Not Allowed*/ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)ExceptionHandler(HttpRequestMethodNotSupportedException.class)public Response handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {logger.error(不支持当前请求方法, e);return new Response().failure(request_method_not_supported);}/*** 415 - Unsupported Media Type*/ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)ExceptionHandler(HttpMediaTypeNotSupportedException.class)public Response handleHttpMediaTypeNotSupportedException(Exception e) {logger.error(不支持当前媒体类型, e);return new Response().failure(content_type_not_supported);}/*** 500 - Internal Server Error*/ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)ExceptionHandler(Exception.class)public Response handleException(Exception e) {logger.error(服务运行异常, e);return new Response().failure(e.getMessage());} } 可见在 ExceptionAdvice 类中包含一系列的异常处理方法每个方法都通过 ResponseStatus 注解定义了响应状态码此外还通过 ExceptionHandler 注解指定了具体需要拦截的异常类。以上过程只是包含了一部分的异常情况若需处理其它异常可添加方法具体的方法。需要注意的是在运行时从上往下依次调用每个异常处理方法匹配当前异常类型是否与 ExceptionHandler 注解所定义的异常相匹配若匹配则执行该方法同时忽略后续所有的异常处理方法最终会返回经 JSON 序列化后的 Response 对象。 4.4 支持参数验证 我们回到上文所提到的示例这里处理一个普通的 POST 请求代码如下 RestController public class AdvertiserController {RequestMapping(value /advertiser, method RequestMethod.POST)public Response createAdvertiser(RequestBody AdvertiserParam advertiserParam) {...} } 其中AdvertiserParam 参数包含若干属性通过以下类结构可见它是一个传统的 POJO public class AdvertiserParam {private String advertiserName;private String description;// 省略 getter/setter 方法 } 如果业务上需要确保 AdvertiserParam 对象的 advertiserName 属性必填如何实现呢 若将这类参数验证的代码写死在 Controller 中势必会与正常的业务逻辑搅在一起导致责任不够单一违背于“单一责任原则”。建议将其参数验证行为从 Controller 中剥离出来放到另外的类中这里仅提供一个 Valid 注解来定义 AdvertiserParam 参数并在 AdvertiserParam 类中通过 NotEmpty 注解来定义 advertiserName 属性就像下面这样 RestController public class AdvertiserController {RequestMapping(value /advertiser, method RequestMethod.POST)public Response createAdvertiser(RequestBody Valid AdvertiserParam advertiserParam) {...} }public class AdvertiserParam {NotEmptyprivate String advertiserName;private String description;// 省略 getter/setter 方法 } 这里的 Valid 注解实际上是 Validation Bean 规范提供的注解该规范已由 Hibernate Validator 框架实现因此需要添加以下 Maven 依赖到 pom.xml 文件中 dependencygroupIdorg.hibernate/groupIdartifactIdhibernate-validator/artifactIdversion${hibernate-validator.version}/version /dependency 需要注意的是Hibernate Validator 与 Hibernate 没有任何依赖关系唯一有联系的只是都属于 JBoss 公司的开源项目而已。 实现 NotEmpty 注解的功能我们需要做以下几件事情。 首先定义一个 NotEmpty 注解类代码如下 Documented Target({ElementType.FIELD, ElementType.PARAMETER}) Retention(RetentionPolicy.RUNTIME) Constraint(validatedBy NotEmptyValidator.class) public interface NotEmpty {String message() default not_empty;Class?[] groups() default {};Class? extends Payload[] payload() default {}; } 以上注解类必须包含 message、groups、payload 三个属性因为这是规范所要求的此外需要通过 Constraint 注解指定一个验证器类这里对应的是 NotEmptyValidator其代码如下 ublic class NotEmptyValidator implements ConstraintValidatorNotEmpty, String {Overridepublic void initialize(NotEmpty constraintAnnotation) {}Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {return StringUtil.isNotEmpty(value);} } 以上验证器类实现了 ConstraintValidator 接口并在该接口的 isValid( ) 方法中完成了具体的参数验证逻辑。需要注意的是实现接口时需要指定泛型第一个参数表示验证注解类型NotEmpty第二个参数表示需要验证的参数类型String。 然后我们需要在 Spring 配置文件中开启该特性需添加如下配置  bean classorg.springframework.validation.beanvalidation.MethodValidationPostProcessor/ 最后需要在全局异常处理类中添加参数验证处理方法代码如下 ControllerAdvice ResponseBody public class ExceptionAdvice {/*** 400 - Bad Request*/ResponseStatus(HttpStatus.BAD_REQUEST)ExceptionHandler(ValidationException.class)public Response handleValidationException(ValidationException e) {logger.error(参数验证失败, e);return new Response().failure(validation_exception);} } 至此REST 框架已集成了 Bean Validation 特性我们可以使用各种注解来完成所需的参数验证行为了。 看似该框架可以在本地成功跑起来整个架构包含两个应用前端应用提供纯静态的 HTML 页面后端应用发布 REST API前端需要通过 AJAX 调用后端发布的 REST API然而 AJAX 是不支持跨域访问的也就是说前后端两个应用必须在同一个域名下才能访问。这是非常严重的技术障碍一定需要找到解决方案。  4.5 解决跨域问题 比如前端应用为静态站点且部署在 http://web.xxx.com 域下后端应用发布 REST API 并部署在 http://api.xxx.com 域下如何使前端应用通过 AJAX 跨域访问后端应用呢这需要使用到 CORS 技术来实现这也是目前最好的解决方案了。 CORS 全称为 Cross Origin Resource Sharing跨域资源共享服务端只需添加相关响应头信息即可实现客户端发出 AJAX 跨域请求。 CORS 技术非常简单易于实现目前绝大多数浏览器均已支持该技术IE8 浏览器也支持了服务端可通过任何编程语言来实现只要能将 CORS 响应头写入 response 对象中即可。 下面我们继续扩展 REST 框架通过 CORS 技术实现 AJAX 跨域访问。 首先我们需要编写一个 Filter用于过滤所有的 HTTP 请求并将 CORS 响应头写入 response 对象中代码如下  public class CorsFilter implements Filter {private String allowOrigin;private String allowMethods;private String allowCredentials;private String allowHeaders;private String exposeHeaders;Overridepublic void init(FilterConfig filterConfig) throws ServletException {allowOrigin filterConfig.getInitParameter(allowOrigin);allowMethods filterConfig.getInitParameter(allowMethods);allowCredentials filterConfig.getInitParameter(allowCredentials);allowHeaders filterConfig.getInitParameter(allowHeaders);exposeHeaders filterConfig.getInitParameter(exposeHeaders);}Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {HttpServletRequest request (HttpServletRequest) req;HttpServletResponse response (HttpServletResponse) res;if (StringUtil.isNotEmpty(allowOrigin)) {ListString allowOriginList Arrays.asList(allowOrigin.split(,));if (CollectionUtil.isNotEmpty(allowOriginList)) {String currentOrigin request.getHeader(Origin);if (allowOriginList.contains(currentOrigin)) {response.setHeader(Access-Control-Allow-Origin, currentOrigin);}}}if (StringUtil.isNotEmpty(allowMethods)) {response.setHeader(Access-Control-Allow-Methods, allowMethods);}if (StringUtil.isNotEmpty(allowCredentials)) {response.setHeader(Access-Control-Allow-Credentials, allowCredentials);}if (StringUtil.isNotEmpty(allowHeaders)) {response.setHeader(Access-Control-Allow-Headers, allowHeaders);}if (StringUtil.isNotEmpty(exposeHeaders)) {response.setHeader(Access-Control-Expose-Headers, exposeHeaders);}chain.doFilter(req, res);}Overridepublic void destroy() {} } 以上 CorsFilter 将从 web.xml 中读取相关 Filter 初始化参数并将在处理 HTTP 请求时将这些参数写入对应的 CORS 响应头中下面大致描述一下这些 CORS 响应头的意义 Access-Control-Allow-Origin允许访问的客户端域名例如http://web.xxx.com若为 *则表示从任意域都能访问即不做任何限制。Access-Control-Allow-Methods允许访问的方法名多个方法名用逗号分割例如GET,POST,PUT,DELETE,OPTIONS。Access-Control-Allow-Credentials是否允许请求带有验证信息若要获取客户端域下的 cookie 时需要将其设置为 true。Access-Control-Allow-Headers允许服务端访问的客户端请求头多个请求头用逗号分割例如Content-Type。Access-Control-Expose-Headers允许客户端访问的服务端响应头多个响应头用逗号分割。需要注意的是CORS 规范中定义 Access-Control-Allow-Origin 只允许两种取值要么为 *要么为具体的域名也就是说不支持同时配置多个域名。为了解决跨多个域的问题需要在代码中做一些处理这里将 Filter 初始化参数作为一个域名的集合用逗号分隔只需从当前请求中获取 Origin 请求头就知道是从哪个域中发出的请求若该请求在以上允许的域名集合中则将其放入 Access-Control-Allow-Origin 响应头这样跨多个域的问题就轻松解决了。  以下是 web.xml 中配置 CorsFilter 的方法 filterfilter-namecorsFilter/filter-namefilter-classcom.xxx.api.cors.CorsFilter/filter-classinit-paramparam-nameallowOrigin/param-nameparam-valuehttp://web.xxx.com/param-value/init-paraminit-paramparam-nameallowMethods/param-nameparam-valueGET,POST,PUT,DELETE,OPTIONS/param-value/init-paraminit-paramparam-nameallowCredentials/param-nameparam-valuetrue/param-value/init-paraminit-paramparam-nameallowHeaders/param-nameparam-valueContent-Type/param-value/init-param /filter filter-mappingfilter-namecorsFilter/filter-nameurl-pattern/*/url-pattern /filter-mapping 完成以上过程即可实现 AJAX 跨域功能了但似乎还存在另外一个问题由于 REST 是无状态的后端应用发布的 REST API 可在用户未登录的情况下被任意调用这显然是不安全的如何解决这个问题呢我们需要为 REST 请求提供安全机制。 4.6 提供安全机制 解决 REST 安全调用问题可以做得很复杂也可以做得特简单可按照以下过程提供 REST 安全机制  当用户登录成功后在服务端生成一个 token并将其放入内存中可放入 JVM 或 Redis 中同时将该 token 返回到客户端。在客户端中将返回的 token 写入 cookie 中并且每次请求时都将 token 随请求头一起发送到服务端。提供一个 AOP 切面用于拦截所有的 Controller 方法在切面中判断 token 的有效性。当登出时只需清理掉 cookie 中的 token 即可服务端 token 可设置过期时间使其自行移除。首先我们需要定义一个用于管理 token 的接口包括创建 token 与检查 token 有效性的功能。代码如下  public interface TokenManager {String createToken(String username);boolean checkToken(String token); } 然后我们可提供一个简单的 TokenManager 实现类将 token 存储到 JVM 内存中。代码如下 public class DefaultTokenManager implements TokenManager {private static MapString, String tokenMap new ConcurrentHashMap();Overridepublic String createToken(String username) {String token CodecUtil.createUUID();tokenMap.put(token, username);return token;}Overridepublic boolean checkToken(String token) {return !StringUtil.isEmpty(token) tokenMap.containsKey(token);} } 需要注意的是如果需要做到分布式集群建议基于 Redis 提供一个实现类将 token 存储到 Redis 中并利用 Redis 与生俱来的特性做到 token 的分布式一致性。  然后我们可以基于 Spring AOP 写一个切面类用于拦截 Controller 类的方法并从请求头中获取 token最后对 token 有效性进行判断。代码如下 public class SecurityAspect {private static final String DEFAULT_TOKEN_NAME X-Token;private TokenManager tokenManager;private String tokenName;public void setTokenManager(TokenManager tokenManager) {this.tokenManager tokenManager;}public void setTokenName(String tokenName) {if (StringUtil.isEmpty(tokenName)) {tokenName DEFAULT_TOKEN_NAME;}this.tokenName tokenName;}public Object execute(ProceedingJoinPoint pjp) throws Throwable {// 从切点上获取目标方法MethodSignature methodSignature (MethodSignature) pjp.getSignature();Method method methodSignature.getMethod();// 若目标方法忽略了安全性检查则直接调用目标方法if (method.isAnnotationPresent(IgnoreSecurity.class)) {return pjp.proceed();}// 从 request header 中获取当前 tokenString token WebContext.getRequest().getHeader(tokenName);// 检查 token 有效性if (!tokenManager.checkToken(token)) {String message String.format(token [%s] is invalid, token);throw new TokenException(message);}// 调用目标方法return pjp.proceed();} } 若要使 SecurityAspect 生效则需要添加如下 Spring 配置 bean idsecurityAspect classcom.xxx.api.security.SecurityAspectproperty nametokenManager reftokenManager/property nametokenName valueX-Token/ /beanaop:configaop:aspect refsecurityAspectaop:around methodexecute pointcutannotation(org.springframework.web.bind.annotation.RequestMapping)//aop:aspect /aop:config 最后别忘了在 web.xml 中添加允许的 X-Token 响应头配置如下 init-paramparam-nameallowHeaders/param-nameparam-valueContent-Type,X-Token/param-value /init-param 5 总结  本文从经典的 MVC 模式开始对 MVC 模式是什么以及该模式存在的不足进行了简述。然后引出了如何对 MVC 模式的改良让其转变为前后端分离架构以及解释了为何要进行前后端分离。最后通过 REST 服务将前后端进行解耦并提供了一款基于 Java 的 REST 框架的主要实现过程尤其是需要注意的核心技术问题及其解决方案。希望本文对正在探索前后端分离的读者们有所帮助期待与大家共同探讨。  转载于:https://www.cnblogs.com/winner-0715/p/6385426.html
http://www.zqtcl.cn/news/460491/

相关文章:

  • 网站内容规范外贸电商怎么做
  • 郑州做网站齿轮wordpress 文章h标签美化
  • 建设银行网站怎么修改手机号码吗网站建设怎样容易
  • 网站建设风险管理计划书户外媒体网站建设免费
  • 学到什么程度可以做网站网站维护的要求包括
  • 泉州网站设计平台南阳响应式网站
  • 阿里云 企业网站选哪种推广普通话的文字内容
  • 广州市南沙建设局网站中山建网站咨询电话
  • 怎么创建网站快捷方式网络服务器搭建配置与管理 下载
  • 现在什么类型网站没有人做wordpress get_categories()
  • 石家庄网站推广优化闲鱼网络营销方式
  • 精诚时代 网站谁做的北京网站设计必看刻
  • 长沙网站排名报价企业管理培训课程网课
  • 怎样做婚庆网站外贸网站怎么注册
  • 网站设计制作公司推荐自己做商务网站有什么利弊
  • 传媒网站杨浦网站建设哪家好
  • 500m主机空间能做视频网站吗做中文网站的公司
  • 网站建设规划模板公司网站建设论文
  • p2p网站开发的内容广东世纪达建设集团有限公司官方网站
  • 网站基本建设是什么o元做网站
  • 南昌做购物网站的公司mc做弊端网站
  • 汕头制作网站推荐文化建设五大工程
  • 公司购物网站备案遵义市乡村街道建设投诉网站
  • ps做景观有哪些素材网站网站推广软文
  • 医疗类网站备案dw网页设计期末作业源代码
  • 网站建设开发合同别具光芒 Flash互动网站设计
  • app导航网站建设多少钱网页游戏破解版
  • 布吉做棋牌网站建设哪家服务好青海做高端网站建设的公司
  • 邙山郑州网站建设好看手机网站推荐
  • 北京建设网官方网站外贸wordpress收款插件