java服务器端解决跨域问题【工具包系列】

现在很多开发的API都支持ajax直接请求,这样就会导致跨域的问题,解决跨域的问题一方面可以从前端,另一方面就是服务器端。
既然是搞服务器端,做对外的API服务,当然是做到越简单越好,前端只需要傻傻的使用就好。

目前我接触来的情况是有2种实现方式,下面直接代码,你们根据自己项目情况,选择或者修改其中的代码,所有代码都是项目实战中运行的。
*种情况,比较简单,让所有的controller类继承自定义的BaseController类,改类中将对返回的头部做些特殊处理。

public abstract class BaseController {
/**
* description:send the ajax response back to the client side
* @param responseObj
* @param response
*/
protected void writeAjaxJSONResponse(Object responseObj, HttpServletResponse response) {
response.setCharacterEncoding(“UTF-8”);

response.setHeader(“Cache-Control”, “no-cache, no-store, must-revalidate”); // HTTP 1.1
response.setHeader(“Pragma”, “no-cache”); // HTTP 1.0

/**
* for ajax-cross-domain request TODO get the ip address from
* configration(ajax-cross-domain.properties)
*/
response.setHeader(“Access-Control-Allow-Origin”, “*”);

response.setDateHeader(“Expires”, 0); // Proxies.

PrintWriter writer = getWriter(response);

writeAjaxJSONResponse(responseObj, writer);
}
/**
*
* @param response
* @return
*/
protected PrintWriter getWriter(HttpServletResponse response) {
if(null == response){
return null;
}

PrintWriter writer = null;

try {
writer = response.getWriter();
} catch (IOException e) {
logger.error(“unknow exception”, e);
}

return writer;
}

/**
* description:send the ajax response back to the client side.
*
* @param responseObj
* @param writer
* @param writer
*/
protected void writeAjaxJSONResponse(Object responseObj, PrintWriter writer) {
if (writer == null || responseObj == null) {
return;
}
try { writer.write(JSON.toJSONString(responseObj,SerializerFeature.DisableCircularReferenceDetect));
} finally {
writer.flush();
writer.close();
}
}
}

接下来就是我们自己业务的controller了,其中主要是要调用 writeAjaxJSONResponse(result, response);这个方法

@Controller
@RequestMapping(value = “/account”)
public class AccountController extends BaseController {
@RequestMapping(value = “/add”, method = RequestMethod.POST)
public void addAccount(HttpSession session,HttpServletRequest request,HttpServletResponse response){
ViewerResult result = new ViewerResult();
//实现自己业务逻辑代码
writeAjaxJSONResponse(result, response);
}

}

好了,这种简单的方式就实现了。

接下来介绍第二种方式,filter。我们在写springMVC的时候,更喜欢的方式是通过@ResponseBody给返回对象进行封装直接返回给前端,这样简单而且容易。
如果使用@ResponseBody就不能使用*种方法了,所有就使用filter给所有的请求都封装一下跨域,接下来直接实现代码:

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.HttpServletResponse;

public class HeadersCORSFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub

}

@Override
public void doFilter(ServletRequest request, ServletResponse servletResponse,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader(“Access-Control-Allow-Origin”, “*”);
response.setHeader(“Access-Control-Allow-Methods”, “POST, GET, OPTIONS, DELETE”);
response.setHeader(“Access-Control-Max-Age”, “3600”);
response.setHeader(“Access-Control-Allow-Headers”, “x-requested-with,Authorization”);
response.setHeader(“Access-Control-Allow-Credentials”,”true”);
chain.doFilter(request, servletResponse);

}

@Override
public void destroy() {
// TODO Auto-generated method stub

}

}

好了,filter实现了,然后就是要在web.xml里面把这个filter运用起来了。
打开项目的web.xml,填写下面的几行代码:

<filter>
<filter-name>cors</filter-name>
<filter-class>xxx.xxxx.xxxxx.xxxx.HeadersCORSFilter</filter-class><!–你过滤器的包 –>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/open/*</url-pattern><!– 你开放的接口前缀 –>
</filter-mapping>

好了,通过上面的2种方式,可以解决百分之80的跨域问题,也许还有更好的解决方案,可以提出来大家一起学习学习。
*好的方案是*符合当前需求且易于扩展的。

服务器端解决跨域问题的三种方法

跨域是指html文件所在的服务器与ajax请求的服务器是不同的ip+port,例如:
– ‘192.168.1.1:8080’ 与 ‘192.168.1.2:8080’是不同的域。
– ‘192.168.1.1:8080’ 与 ‘192.168.1.1:8081’是不同的域。

解决此类问题的方法很多,有需要客户端和服务端都要更改的,例如jsonp,iframe等等;有只需要客户端更改的,这种情况只能出现在hybrid app开发中,即通过调用native方法来进行网络请求;有只需要服务端配置的,下面介绍3种服务端配置的方法。

*种

如果您使用的mvc框架是spring4.2以上的话,一个@CrossOrigin就可以搞定。将@CrossOrigin加到Controller上,那么这个Controller所有的请求都是支持跨域的,代码如下:

  1. @Controller
  2. @CrossOrigin
  3. public class GreetingController {
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

将@CrossOrigin加到请求方法上,那么这个请求是支持跨域的,代码如下

  1. @CrossOrigin
  2. @RequestMapping(“/greeting”)
  3. public @ResponseBody Greeting greeting(@RequestParam(required=false, defaultValue=“World”) String name) {
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

更详细的@CrossOrigin介绍,请参看这里

第二种

全局配置,也需要spring4.2以上。

  1. @Bean
  2. public WebMvcConfigurer corsConfigurer() {
  3. return new WebMvcConfigurerAdapter() {
  4. @Override
  5. public void addCorsMappings(CorsRegistry registry) {
  6. registry.addMapping(“/greeting-javaconfig”).allowedOrigins(“http://localhost:9000”);
  7. }
  8. };
  9. }

.addCorsMappings()中的参数代表支持跨域的url,.allowedOrigins()中的参数代表可以访问该接口的域名,设置为”*”可支持所有域。

第三种

这种方法就跟框架无关了,需要两个jar包,点击这里进行下载,两个jar包可以放的程序里,也可以放到tomcat中,然后将下面的配置写到web.xml中就可以了

  1. < filter >
  2. < filter-name > CORS </ filter-name >
  3. < filter-class > com.thetransactioncompany.cors.CORSFilter </ filter-class >
  4. < init-param >
  5. < param-name > cors.allowOrigin </ param-name > <!–配置授信的白名单的域名!–>
  6. < param-value > * </ param-value >
  7. </ init-param >
  8. < init-param >
  9. < param-name > cors.supportedMethods </ param-name >
  10. < param-value > GET, POST, HEAD, PUT, DELETE </ param-value >
  11. </ init-param >
  12. < init-param >
  13. < param-name > cors.supportedHeaders </ param-name >
  14. < param-value > Accept, Origin, X-Requested-With, Content-Type, Last-Modified </ param-value >
  15. </ init-param >
  16. < init-param >
  17. < param-name > cors.exposedHeaders </ param-name >
  18. < param-value > Set-Cookie </ param-value >
  19. </ init-param >
  20. < init-param >
  21. < param-name > cors.supportsCredentials </ param-name >
  22. < param-value > true </ param-value >
  23. </ init-param >
  24. </ filter >
  25. < filter-mapping >
  26. < filter-name > CORS </ filter-name >
  27. < url-pattern > /* </ url-pattern >
  28. </ filter-mapping >

Nodejs搭建web服务器

使用Nodejs + http 创建web服务器
1、首先创建一个server.js文件,创建服务器,以及对应css和js文件的引入和判断
var http=require(‘http’);
var fs = require(‘fs’);
var url = require(‘url’);

//创建服务器
http.createServer(function(request,response) {
//解析请求,包括文件名
var pathname= url.parse(request.url).pathname;
//输出请求的文件名
console.log(“Request for “+ pathname + ” received.”);
//获取后缀,判断是js还是css文件,如果目录结构不同,此处需要修改
var firstDir = pathname && pathname.split(‘/’)[1];
var ContentType = {‘Content-Type’: ‘text/html’};

// js – application/x-javascript
if (firstDir && firstDir === ‘static’) {
ContentType = {‘Content-Type’: ‘text/css’};
}
if (firstDir && firstDir === ‘js’) {
ContentType = {‘Content-Type’: ‘application/x-javascript’}
}

//从文件系统中去请求的文件内容
fs.readFile(pathname.substr(1),function(err, data) {
if(err) {
console.log(err);
//HTTP 状态码 404 : NOT FOUND
//Content Type:text/plain
response.writeHead(404, {‘Content-Type’: ‘text/html’});
}
else {
//HTTP 状态码 200 : OK
//Content Type:text/plain
response.writeHead(200, ContentType);

//写会回相应内容
response.write(data.toString());
}
//发送响应数据
response.end();
});
}).listen(8080);

console.log(‘Server running at http://127.0.0.1:8080/’);

2、 创建一个简单的html页面 ,此处是两个边框,然后是一个表格,并在第二个边框添加上一个点击事件,
作为引入另一个js文件

<!–

3、css样式文件和上面写的style标签内容一样
body {
border: 1px solid blue;
}

div {
border-radius: 10px;
width: 400px;
height: 200px;
border: 2px solid yellow;
}

4、这个是js文件
console.log(’-成功引入js文件-’);
function onClickDiv () {
alert(‘second点击事件’);
}

整体上就这么多了!详细的都有注释,大家可以自己看看,相对上也比较简单,具体步骤我也简单说下:

1、下载安装nodejs,官网就可以了,此处使用的是http,也有的例子使用的是express(需要在nodejs中下载,
详细的自己可以百度下看看)
2、进入到此项目中js文件那层目录,执行node server.js(此处取名为server,具体看自己的名称)
3、执行成功会打印服务器启动,并显示ip和端口号
4、打开浏览器http://127.0.0.1:8080/index.html即可查看效果

*后上图:
%title插图%num %title插图%num

web项目打包部署到服务器上的步骤

一、将项目打包成war包。(这里以eclipse如何打包为例)

项目(右键)——>Export——>War file(Web)——>选择war包保存路径——>Finished。

二、发布到Tomcat上。

2.1  解压tomcat

2.2  将打包好的war包拷贝到tomcat文件夹下的webapps里。

2.3  在tomcat的config文件中修改server.xml信息。(在<Valve className=”org.apache.catalina.valves.AccessLogValve” directory=”logs” pattern=”%h %l %u %t &quot;%r&quot; %s %b” prefix=”localhost_access_log.” suffix=”.txt”/>后面添加<Context docBase=”你的项目名” path=”/项目名” reloadable=”true”  “/>)

注意:如果没有配置好JAVA_HOME与JRE_HOME信息的,还要在bin文件中修改setclasspath.bat信息。(在rem Make sure prerequisite environment variables are set 这句上面添加set JAVA_HOME= ‘java安装路径’  set JRE_HOME=’JRE安装路径’)。

三、运行项目。

在tomcat的bin文件中找到startup.bat,双击运行,即可启动项目。

用*容易理解的方式,来解释云计算行业的SaaS、PaaS和IaaS

现在我一般采用一种比较简单粗暴的方式来告诉你什么是云计算,这种方式就好像你问我金庸的武侠是什么样的?我就告诉你郭啸天、郭靖、郭襄。今天我会用云计算行业*主要的三个词:SaaS、PaaS、IaaS来和你聊聊什么是云计算。

SaaS
SaaS是云计算的*上层,别误会,这个上层不是武侠中“上层武功”的那个意思,而是你住五楼、我住六楼,我是你的“上层”的那个意思。在云计算中的SssS(层),是基于平台上的具体应用,SssS层是距离用户*近的那一层。例如多备份就是让用户可以通过一个简单应用直接在云端进行数据的管理和保护,同时,用户还可以依据多备份实现多个云之间的数据互通,比如,你如果想把阿里云的数据备份到百度云,需要做的就是先把阿里云的数据从云端拿下来然后再上传。如果使用多备份的话,就可以省去将数据下载到本地的这一步骤。这里的SssS甚至可以定义为一种软件,所以才会有“软件即服务”的说法。

PaaS
所谓PaaS实际上是指将软件研发的平台作为一种服务,提供给用户。用户或者企业基于PaaS平台可以快速开发自己所需要的应用和产品。同时,PaaS 平台开发的应用能更好地搭建基于SOA架构的企业应用。PaaS作为一个完整的开发服务,提供了从开发工具、中间件,到数据库软件等开发者构建应用程序所需的所有开发平台的功能。Azure就是一个具体的PaaS。Azure服务平台包括了以下主要组件:Windows Azure;Microsoft SQL数据库服务、Microsoft .Net服务;用于分享、储存和同步文件的Live服务;针对商业的Microsoft SharePoint和Microsoft Dynamics CRM服务等。

IaaS
所谓云存储就是就是将网络中大量各类不同类型的存储设备通过应用软件结合起来协同工作,共同对外提供数据存储和业务访问功能的一个系统,说的直白一点就是按需分配。当然在具体的实现过程中*对不会像说得那么简单。说白了一点这种IaaS是云的制造者。IaaS(Infrastructure as a Service),指基础设施即服务,消费者通过Internet可以从完善的计算机基础设施获得服务。基于Internet的服务(如存储和数据库)是 IaaS的一部分。Internet上其他类型的服务包括平台即服务(Platform as a Service,PaaS)和软件即服务(Software as a Service,SaaS)。PaaS提供了用户可以访问的完整或部分的应用程序开发,SaaS则提供了完整的可直接使用的应用程序,比如通过 Internet管理企业资源。

SaaS、PaaS、IaaS云计算的三层结构,但是三者之间并没有也不需要非常明确的划分。云计算的根本目的是解决问题, SaaS、PaaS、IaaS都试图去解决同一个商业问题——用尽可能少甚至是为零的资本支出,获得功能、扩展能力、服务和商业价值。当某种云计算的模式获得了成功,这三者之间的界限就会进一步模糊。成功的SaaS或IaaS服务可以很容易地延伸到平台领域 (PaaS)。

云端存储数据,主要的安全因素是什么?

云端存储数据的5大不安全因素,具体如下:

1、滥用和恶意使用云计算

基础设施即服务(IaaS)提供商往往会声称可以为客户提供无限制的计算、网络和存储容量,但这些都是幻觉,是浮云。

如果提供商提供免费的有限的试用期,大门也将会向垃圾邮件发送者,恶意软件作者和网络犯罪人员敞开,他们可以在云中匿名操作,以逃避惩罚。

过去,只有平台即服务(PaaS)提供商是攻击者的目标,但世界在变化,现在IaaS提供商也不再安全了,组织需要担心诸如密钥破解,分布式拒*服务攻击(DDoS),托管恶意数据和彩虹表等因素。

2、不安全的接口和API

对大多数组织而言,转移到云是不可避免的,遗憾的是,服务提供商只是热心于叫你迁移到云,而不思考他们API和接口中的不安全因素。

通常情况下,管理、业务流程、配置和监控都是通过这些接口执行的,安全和可用性完全依赖于每个基础API内置的安全性。

从身份认证到访问控制,再到加密和监控都在在这些API中体现出来,但现在它们通常没有这样设计,这意味着不但可能发生无辜的事故,恶意活动的成功几率也会越来越高。

通常,组织和第三方都会使用这些现成的API走捷径,要实现对数据的保护,你需要脱去这些API的外衣,重新封装一层安全保护层。

3、不怀好意的内部人员

这些人不会消失,大多数组织已经意识到不怀好意的雇员可能会破坏数据,遗憾的是,在云端一样不能幸免,事实上,转移到云中后,内部人员破坏数据的可能性还越来越大。

由于客户只有一个管理域,加上提供商缺乏透明度,导致缺陷被放大。

例如,云提供商可能不会透露它是如何授权雇员访问物理或虚拟数据,如何监控这些雇员,或如何分析服从报告的,他们仅仅为你提供了一个快速,划算的业务增长方法,但不会提供任何有关雇员在云中如何工作的可视化报告。

这使得黑客,企业间谍,犯罪集团,甚至国家赞助的入侵者对云中的数据更感兴趣。

4、共享的技术问题

IaaS提供商的基础设施是自己建立的,因此具有良好的扩展能力,但这种架构解决方案的挑战是底层组件通常没有为多租户架构提供强大的隔离措施。

解决这个缺陷的快速方法是,使用虚拟化Hypervisor在客户机操作系统和物理计算资源之间起到隔离作用,但如果Hypervisor本身也有缺陷,可能会给上层的客户机操作系统或底层平台带入隐患。

总之,客户不应该有权访问其它客户的数据,但遗憾的是,云一样不能保证这一点。

5、未知的风险预测

云计算的一个信条是减少硬件和软件所有权和维护权,释放*终用户的压力,让他们专注于核心业务的强项。

但财务和运营方面的好处需要结合所有安全担心进行权衡,毫无疑问,云会让你的生活更加简单,但它也可能让你死于安乐。

你在调查云提供商时,诸如软件代码更新,安全补丁,缺陷预测,入侵尝试和安全设计等都应该被涉及。

数据本身需要得到保护才能确保它在云中的安全,不能只依靠云提供商,他们顶多能保证环境100%的安全,你自己必须确保对数据采取了切实有效的保护措施,那么什么措施才是切实有效的呢?

虽然没有银弹,我认为保护云中的数据*核心的需求是断词(tokenization),断词是使用别名值或无意义的标识符代替敏感数据,以达到保护敏感数据的过程。

这种方法可以用来保护敏感信息,如信用卡号,个人身份信息(PII),如与健康相关的数据,email,密码和登录信息等。

云计算和物联网之间是什么关系,主要都面临哪些挑战?

物联网与云计算都是基于互联网的,可以说互联网就是它们相互连接的一个纽带。物联网就是互联网通过传感网络向物理世界的延伸,它的*终目标就是对物理世界进行智能化管理。

物联网的这一使命,也决定了它必然要由一个大规模的计算平台作为支撑。云计算从本质上来说就是一个用于海量数据处理的计算平台,因此,云计算技术是物联网涵盖的技术范畴之一。随着物联网的发展,未来物联网将势必产生海量数据,而传统的硬件架构服务器将很难满足数据管理和处理要求。

如果将云计算运用到物联网的传输层与应用层,采用云计算的物联网,将会在很大程度上提高运行效率。可以说,如果把物联网当作一台主机的话,云计算就是它的CPU。

1. 建设物联网所面临的主要挑战

标准问题;

安全问题;

协议问题;

IP地址问题。

2. 云计算平台所面临的主要挑战

数据安全性问题;

个人隐私的保护问题;

服务互操作性问题。

以上所说的只是物联网与云计算发展过程中所遇到的一部分主要问题,不可能面面俱到。在实践过程中我们仍可能遇到这样或那样的问题。有些问题我们可能无法预料,但可以肯定是,只有把来自物联网及来自云计算两个方面的问题都解决之后,实现云计算在物联网系统中的完美利用才可能取得突破性进展。

关于私有云,公共云,混合云,以及多云架构,我们应该选择?

以往是关于云计算的有无进行探讨,而如今是关于私有云,公共云,混合云,以及多云架构的争论。人们希望不会做出错误的选择。

云架构的纯粹学术欺诈

他们的理由是自私的:大型企业软件和硬件供应商必须相信混合云计算,因为他们有数据中心方面的考虑,并在那里获得利益。因此,即使大多数现有工作负载将驻留在私有云中或仍保留在传统的数据中心平台上,他们承认公有云将会发挥作用。

由于同样的原因,企业IT部门也在采用这个论点因。他们的动机不是出售或坚持传统的计算方法,而是为了保持控制,这将让公共云的敏捷性和成本效率得到抑制。而这种做法是不诚实的。

当然,这不仅仅是混合云的支持者这样做,促进公共云架构或多云架构(使用多个公共云)的工作人员同样糟糕。更糟糕的是,采用私有云的企业会认为对这种架构的推动是可怕的。

事实是,并不是所有的工作负载都可以转移到公共云端,所以现在很多传统的系统仍然保持在“伟大的云迁移”的*后阶段(大约20%到30%的工作量不会运行在公共云)。

组织的确需要为其工作选择权利工具

没有不好的云方法。混合云,多云,私有云和公共云总有一个可以满足组织的需求。应该使用哪种云架构?这个答案完全取决于企业的技术和业务需求。

在使用云计算解决方案之前,组织需要做好功课以了解数据,流程,安全性和治理以及性能,成本和操作。换句话说,组织需要做这些无聊的东西,但却经常忽略,并在这方面犯了巨大的错误,为此将付出数百万美元的高昂代价。

尽管如此人们需要了解,并不是所有的云架构都是平等的:一些云架构本质上比其他的更好,如果选择了一个不太理想的云体系结构,需要意识到自己正在做这件事,并理解它的含义,即使是针对特定需要的正确方法。

对于大多数企业而言,私有云和混合云是一种不好的选择。然而,将传统系统与公共云(实用混合云)匹配是传统混合云架构的有效的,具有成本效益的替代方案。不要忽视公共云给企业带来重要价值,服务和安全的现实,现在是承认这个事实的时候了,无论过去担心什么。

企业软件和硬件厂商在营销方面上共花费数百万美元,甚至投入更多的资金重建技术。企业IT部门如果采信这些资金充足和被动攻击的营销宣传后果是可怕的,有风险的,他们的信息是专为高级企业管理人员而设的,而不仅仅是信息技术。

然而,企业需要迅速摆脱云架构的两*分化。这没有一个单一的答案。无论是恐惧,低调,控制欲望,管理压力或营销力量,技术专家和业务经理为此可能会犯结束其职业生涯的错误。这个代价是巨大的,如果错了,却不会有一个重置按钮,那么就会困在一个错误的计算架构中。

手动修改tomcat版本号

1.找到tomcat所在位置进入lib目录            apache-tomcat-8.0.0\lib

2.lib目录县有个catalina.jar                        用解压缩软件打开(可以先解压再修改版本号再打成jar包这样太麻烦所以直接用解压缩软件打开就行)

3.打开后 ,在catalina.jar\org\apache\catalina\util目录下找到ServerInfo.properties

4.用编辑软件(记事本就可以)打开ServerInfo.properties再进行修改就行了

5.修改版本号

原有的                                                                      修改后的

server.info=Apache Tomcat/8.5.0                        server.info=Apache Tomcat/8.0.0
server.number=8.5.0                                             server.number=8.0.0
server.built=Jun 21 2017 17:01:09 UTC            server.built=Jun 21 2017 17:01:09 UTC

根据自己的需要将其改为自己想要的版本就行了

服务器上的tomcat怎么判断版本

先找到tomcat的安装路径,在lib目录下有catalina.jar, 执行以下命令就可以显示出了.

java -cp catalina.jar org.apache.catalina.util.ServerInfo

Server version: Apache Tomcat/7.0.52
Server built:   May 15 2015 01:37:14
Server number:  7.0.52.0
OS Name:        Linux
OS Version:     2.6.18-164.el5
Architecture:   amd64
JVM Version:    1.7.0_71-b14
JVM Vendor:     Oracle Corporation

上边不仅列出了Tomcat的版本, 还将tomcat依赖的JVM版本,OS版本也列出来了。

原文:http://blog.csdn.net/hongchangfirst/article/details/49472579

作者:hongchangfirst

hongchangfirst的主页:http://blog.csdn.net/hongchangfirst