基于 SSM框架的前后端分离

来源:互联网 发布:哈尔滨软件开发88087 编辑:程序博客网 时间:2024/05/16 18:30

文章知识点来源:从MVC到前后端分离(REST-个人也认为是目前比较流行和比较好的方式)
本文主要是抽取我想要的部分快速实现:
1,服务端要解决跨域问题:
前端应用为静态站点且部署在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对象中,代码如下:

import io.netty.util.internal.StringUtil;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;/**         * Title: 跨域访问处理(跨域资源共享)     * Description: 解决前后端分离架构中的跨域问题 * @author cjj        * @created 2017年7月4日 下午5:00:09     */public class CorsFilter implements Filter{    private static final Logger logger = LoggerFactory.getLogger(CorsFilter.class);    private String allowOrigin;    private String allowMethods;    private String allowCredentials;    private String allowHeaders;    private String exposeHeaders;    @Override    public 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");    }    /**      * @description 通过CORS技术实现AJAX跨域访问,只要将CORS响应头写入response对象中即可     * @author rico            * @created 2017年7月4日 下午5:02:38           * @param req     * @param res     * @param chain     * @throws IOException     * @throws ServletException          * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)          */      @Autowired    @Override    public void doFilter(ServletRequest req, ServletResponse res,            FilterChain chain) throws IOException, ServletException {         HttpServletRequest request = (HttpServletRequest) req;           HttpServletResponse response = (HttpServletResponse) res;          String currentOrigin = request.getHeader("Origin");          response.setHeader("Access-Control-Allow-Origin", currentOrigin);           /**          * 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:允许客户端访问的服务端响应头,多个响应头用逗号分割。          */         if (StringUtil.isNullOrEmpty(allowMethods)) {               response.setHeader("Access-Control-Allow-Methods", allowMethods);           }           if (StringUtil.isNullOrEmpty(allowCredentials)) {               response.setHeader("Access-Control-Allow-Credentials", allowCredentials);           }           if (StringUtil.isNullOrEmpty(allowHeaders)) {              response.setHeader("Access-Control-Allow-Headers", allowHeaders);           }           if (StringUtil.isNullOrEmpty(exposeHeaders)) {               response.setHeader("Access-Control-Expose-Headers", exposeHeaders);           }           chain.doFilter(req, res);      }    @Override    public void destroy() {        // TODO Auto-generated method stub    }}

以上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的方法:

    <!-- 解决AJAX跨域访问问题 -->    <filter>      <filter-name>corsFilter</filter-name>      <filter-class>com.ssm.fliter.CorsFilter</filter-class>      <init-param>          <param-name>allowOrigin</param-name>          <param-value>*</param-value>      </init-param>      <init-param>          <param-name>allowMethods</param-name>          <param-value>GET,POST,PUT,DELETE,OPTIONS</param-value>      </init-param>      <init-param>          <param-name>allowCredentials</param-name>          <param-value>true</param-value>      </init-param>      <init-param>          <param-name>allowHeaders</param-name>          <param-value>Content-Type</param-value>      </init-param>    </filter>   <filter-mapping>      <filter-name>corsFilter</filter-name>      <url-pattern>/*</url-pattern>    </filter-mapping>  

前端跨域简单文件上传尝试:

<!DOCTYPE html><html><head>    <meta charset="UTF-8">    <title>XMLHttpRequest上传文件</title>    <script type="text/javascript">        var xhr;        //上传文件方法        function UpladFile() {            var fileObj = document.getElementById("file").files[0]; // js 获取文件对象            var url = "http://localhost:8080/okssm/user/publish/info.json"; // 接收上传文件的后台地址            var form = new FormData(); // FormData 对象            form.append("imgs", fileObj); // 文件对象            form.append("userPhone", "138000000001"); // 文件对象            form.append("type", "1"); // 文件对象            xhr = new XMLHttpRequest();  // XMLHttpRequest 对象            xhr.open("post", url, true); //post方式,url为服务器请求地址,true 该参数规定请求是否异步处理。            xhr.onload = uploadComplete; //请求完成            xhr.onerror =  uploadFailed; //请求失败            xhr.send(form); //开始上传,发送form数据        }        //上传成功响应        function uploadComplete(evt) {            //服务断接收完文件返回的结果            var data = JSON.parse(evt.target.responseText);            if(data.resCode==10000) {                alert("上传成功!");            }else{                alert("上传失败!");            }        }        //上传失败        function uploadFailed(evt) {            alert("上传失败!");        }        //取消上传        function cancleUploadFile(){            xhr.abort();        }    </script></head><body><progress id="progressBar" value="0" max="100" style="width: 300px;"></progress><span id="percentage"></span><span id="time"></span><br /><br /><input type="file" id="file" name="myfile" /><input type="button" onclick="UpladFile()" value="上传" /></body></html>
原创粉丝点击