1.首先要有对应的context实体类, 多个实体类的构造函数的参数都应该是集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public class firstContext : DbContext { //多个数据库应该使用这个构造函数,参数是上下文的集合 public GalpOnlineContext(DbContextOptions<firstContext> options) : base(options) { } //自定义DbContext实体属性名与数据库表对应名称(默认 表名与属性名对应是 User与Users) protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<User>().ToTable("user"); modelBuilder.Entity<Project>().ToTable("project"); //相关表名称的和类的对应 base.OnModelCreating(modelBuilder); } public DbSet<User> User { get; set; } //.... //第二种方法,重载父级的构造函数,和配置,这个只能是一个数据库时候的构造函数 /* public firstContext(DbContextOptions options) : base(options) { // Using the default constructor }*/ } } |
2.在appsettings.json中进行配置数据库连接的信息
1 2 3 4 5 6 7 8 9 10 |
{ "Logging": { "LogLevel": { "Default": "Warning" } }, "ConnectionStrings": { "firstContext": "Server=localhost;database=test;uid=root;pwd=123456;sslmode=none", "secondContext": "Server=localhost;database=test2;uid=root;pwd=123456;sslmode=none" }, |
3.在startup.cs文件中注册数据库上下文的信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // options.CheckConsentNeeded = context => false;实现session,默认是true options.CheckConsentNeeded = context => false; options.MinimumSameSitePolicy = SameSiteMode.None; }); //注册数据库的服务 string connectionString = Configuration.GetConnectionString("firstContext"); string connectionString2 = Configuration.GetConnectionString("secondContext"); services.AddDbContext<firstContext>(options => options.UseMySql(connectionString)); services.AddDbContext<secondContext>(options => options.UseMySql(connectionString2)); //注册session services.AddDistributedMemoryCache(); services.AddSession(Options => { Options.IdleTimeout = TimeSpan.FromSeconds(1000); Options.Cookie.HttpOnly = true; }); //services.AddMemoryCache();//使用本地缓存必须添加 //注册mvc服务 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); } |
然后就可以了,在使用的地方引入上下文就可以了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class TestController : Controller { public readonly firstContext _context; //构造函数,依赖注入数据库上下文就可以了 public TestController(firstContext context) { _context = context; } public ActionResult Index(string page) { List<Project> projects = _context.Project.ToList(); ViewBag.projects = projects; return View(); } } |
from:https://www.cnblogs.com/xuqp/p/9707469.html
View DetailsGitHub demo https://github.com/zhanglilong23/Asp.NetCore.Demo 本项目使用中间件拦截请求数据,并对请求数据解密。 访问接口成功后拦截返回数据,然后将返回数据加密后返回。 其中log4net部分不再赘述(demo中有介绍) 将Post方法中Body中的数据进行AES解密 将返回数据进行AES加密 1:自定义中间件,并默认实现Invoke方法. 附带使用日志记录错误和访问时间等,写的比较糙。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
public class HttpContextMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; /// <summary> /// 计时器 /// </summary> private Stopwatch _stopwatch; //加密解密key private readonly string securitykey = "0123456789abcdef"; /// <summary> /// 构造 Http 请求中间件 /// </summary> /// <param name="next"></param> /// <param name="loggerFactory"></param> /// <param name="cacheService"></param> public HttpContextMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) { _next = next; _logger = loggerFactory.CreateLogger<HttpContextMiddleware>(); } /// <summary> /// 1:将Post方法中Body中的数据进行AES解密 /// 2:将返回数据进行AES加密 /// </summary> /// <param name="context"></param> /// <returns></returns> public async Task Invoke(HttpContext context) { context.Request.EnableBuffering(); _stopwatch = new Stopwatch(); _stopwatch.Start(); _logger.LogInformation($"Handling request: " + context.Request.Path); var api = new ApiRequestInputViewModel { HttpType = context.Request.Method, Query = context.Request.QueryString.Value, RequestUrl = context.Request.Path, RequestName = "", RequestIP = context.Request.Host.Value }; var request = context.Request.Body; var response = context.Response.Body; try { using (var newRequest = new MemoryStream()) { //替换request流 context.Request.Body = newRequest; using (var newResponse = new MemoryStream()) { //替换response流 context.Response.Body = newResponse; using (var reader = new StreamReader(request)) { //读取原始请求流的内容 api.Body = await reader.ReadToEndAsync(); if (string.IsNullOrEmpty(api.Body)) await _next.Invoke(context); //示例加密字符串,使用 AES-ECB-PKCS7 方式加密,密钥为:0123456789abcdef // 加密参数:{"value":"哈哈哈"} // 加密后数据: oedwSKGyfLX8ADtx2Z8k1Q7+pIoAkdqllaOngP4TvQ4= api.Body = SecurityHelper.AESDecrypt(api.Body, securitykey); } using (var writer = new StreamWriter(newRequest)) { await writer.WriteAsync(api.Body); await writer.FlushAsync(); newRequest.Position = 0; context.Request.Body = newRequest; await _next(context); } using (var reader = new StreamReader(newResponse)) { newResponse.Position = 0; api.ResponseBody = await reader.ReadToEndAsync(); if (!string.IsNullOrWhiteSpace(api.ResponseBody)) { api.ResponseBody = SecurityHelper.AESEncrypt(api.ResponseBody, securitykey); } } using (var writer = new StreamWriter(response)) { await writer.WriteAsync(api.ResponseBody); await writer.FlushAsync(); } } } } catch (Exception ex) { _logger.LogError($" http中间件发生错误: " + ex.ToString()); } finally { context.Request.Body = request; context.Response.Body = response; } // 响应完成时存入缓存 context.Response.OnCompleted(() => { _stopwatch.Stop(); api.ElapsedTime = _stopwatch.ElapsedMilliseconds; _logger.LogDebug($"RequestLog:{DateTime.Now.ToString("yyyyMMddHHmmssfff") + (new Random()).Next(0, 10000)}-{api.ElapsedTime}ms", $"{JsonConvert.SerializeObject(api)}"); return Task.CompletedTask; }); _logger.LogInformation($"Finished handling request.{_stopwatch.ElapsedMilliseconds}ms"); } } |
2:实现中间件扩展
1 2 3 4 5 6 7 |
public static class MiddlewareExtensions { public static IApplicationBuilder UseHttpContextMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<HttpContextMiddleware>(); } } |
3:在Startup使用中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public void Configure(IApplicationBuilder app, IHostingEnvironment env,ILoggerFactory loggerFactory) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpContextMiddleware(); //引入自定义的HtppContextMiddleware中间件 loggerFactory.AddLog4Net(); //引入log4net app.UseHttpsRedirection(); app.UseMvc(); } |
from:https://blog.csdn.net/a123_z/article/details/94011395
View Details如果要得到传统的ASP.Net应用程序中的相对路径或虚拟路径对应的服务器物理路径,只需要使用使用Server.MapPath()方法来取得Asp.Net根目录的物理路径,如下所示:
1 2 3 4 5 6 7 8 9 10 |
// Classic ASP.NET public class HomeController : Controller { public ActionResult Index() { string physicalWebRootPath = Server.MapPath("~/"); return Content(physicalWebRootPath); } } |
但是在ASPNET Core中不存在Server.MapPath()方法,Controller基类也没有Server属性。 在Asp.Net Core中取得物理路径: 从ASP.NET Core RC2开始,可以通过注入 IHostingEnvironment 服务对象来取得Web根目录和内容根目录的物理路径,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; namespace AspNetCorePathMapping { public class HomeController : Controller { private readonly IHostingEnvironment _hostingEnvironment; public HomeController(IHostingEnvironment hostingEnvironment) { _hostingEnvironment = hostingEnvironment; } public ActionResult Index() { string webRootPath = _hostingEnvironment.WebRootPath; //F:\数据字典\Centa.Data.Dictionary\Centa.Data.Web\wwwroot string contentRootPath = _hostingEnvironment.ContentRootPath; //F:\数据字典\Centa.Data.Dictionary\Centa.Data.Web return Content(webRootPath + "\n" + contentRootPath); } } } |
ASP.NET Core RC1 在ASP.NET Core RC2之前 (就是ASP.NET Core RC1或更低版本),通过 IApplicationEnvironment.ApplicationBasePath 来获取 Asp.Net Core应用程序的根目录(物理路径) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using Microsoft.AspNet.Mvc; using Microsoft.Extensions.PlatformAbstractions; namespace AspNetCorePathMapping { public class HomeController : Controller { private readonly IApplicationEnvironment _appEnvironment; public HomeController(IApplicationEnvironment appEnvironment) { _appEnvironment = appEnvironment; } public ActionResult Index() { return Content(_appEnvironment.ApplicationBasePath); } } } |
from:https://www.cnblogs.com/gygtech/p/9909222.html
View Details公司旧的项目用play,新的项目改用springboot,前端同学问我,新的项目怎么拿baseUrl? 其实springboot+thymeleaf是可以做到的,我就贴个代码记录一下吧 后端代码如下:
1 2 3 4 5 6 7 8 9 |
@Resource private void configureThymeleafStaticVars(ThymeleafViewResolver viewResolver) { if(viewResolver != null) { Map<String, Object> vars = Maps.newHashMap(); vars.put("picUrl", env.getProperty("picUrl")); vars.put("baseUrl", env.getProperty("baseUrl")); viewResolver.setStaticVariables(vars); } } |
只要放在spring能扫描到的地方就可以了. 不过这里有个问题,一般来说,这些地址都是通过properties文件,或者yml文件,分环境配置的,要拿配置文件的值,我第一时间就想用@value,但是由于加载顺序的关系,@value加载在后面,所以这里就不能用@value了,用environment
1 2 |
@Resource private Environment env; |
然后到前端的代码: 把这段代码放到header.html,统一加载就行了
1 2 3 4 |
<script th:inline="javascript"> const baseUrl = '[(${baseUrl})]'; const picUrl = '[(${picUrl})]'; </script> |
from:https://blog.csdn.net/bear_lam/article/details/80278590
View Details
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package com.example.thymeleaf.commons; import org.springframework.stereotype.Component; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * 配置静态资源映射 * * @author sunziwen * @version 1.0 * @date 2018-11-16 14:57 **/ @Component public class WebMvcConfig implements WebMvcConfigurer { /** * 添加静态资源文件,外部可以直接访问地址 * * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); } } |
from:https://blog.csdn.net/wenxingchen/article/details/84139845
View Details目录 spring boot程序的static目录默认资源路径源码 application.yml增加配置 spring boot程序的static目录默认资源路径源码
1 2 3 4 5 |
<code class="prism language-java has-numbering"><span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> String<span class="token punctuation">[</span><span class="token punctuation">]</span> CLASSPATH_RESOURCE_LOCATIONS <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"classpath:/META-INF/resources/"</span><span class="token punctuation">,</span> <span class="token string">"classpath:/resources/"</span><span class="token punctuation">,</span> <span class="token string">"classpath:/static/"</span><span class="token punctuation">,</span> <span class="token string">"classpath:/public/"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> |
可以看到springboot默认加载资源的路径是在calsspath下,这样jar打包的web项目资源文件只能放在jar内。这样修改和维护起来非常不方便。 参考官方文档,static资源也可以放在jar包外部,只要在配置文件中增加static-locations: 就可以直接在配置文件中覆盖默认的静态资源路径的配置信息 application.yml增加配置
1 2 3 4 5 6 7 8 |
<span class="token key atrule">spring</span><span class="token punctuation">:</span> <span class="token key atrule">resources</span><span class="token punctuation">:</span> <span class="token comment">#web静态页面路径</span> <span class="token comment"># static-locations: file:///E:/workspace/demo/target/demo/static/,file:///E:/workspace/demo/target/demo/public/</span> <span class="token comment">#当前启动目录下相对路径</span> <span class="token key atrule">static-locations</span><span class="token punctuation">:</span> file<span class="token punctuation">:</span>./static/<span class="token punctuation">,</span>file<span class="token punctuation">:</span>./public/ |
from:https://blog.csdn.net/u014155356/article/details/82862683
View Details一、概述 1.是什么 简单说, Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP 。 2.feature 1.Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。 2.Thymeleaf 开箱即用的特性。它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、该jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。 3. Thymeleaf 提供spring标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。 3.文档 官方教程:http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#what-is-thymeleaf 推荐教程:http://blog.didispace.com/springbootweb/ http://blog.csdn.net/u012706811/article/details/52185345 二、HelloWorld 1.引入依赖 springboot直接引入:
1 2 3 4 |
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> |
非springboot项目使用如下依赖:
1 2 3 4 5 |
<dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>2.1.4</version> </dependency> |
默认的模板映射路径是:src/main/resources/templates,springboot1.4之后,可以使用thymeleaf3来提高效率,并且解决标签闭合问题,配置方式:
1 2 3 4 5 6 7 8 |
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- set thymeleaf version --> <thymeleaf.version>3.0.0.RELEASE</thymeleaf.version> <thymeleaf-layout-dialect.version>2.0.0</thymeleaf-layout-dialect.version> <!--set java version--> <java.version>1.8</java.version> </properties> |
之前的model/modelMap/modelAndView等页面数据传递参考之前随笔:点击查看 快速回顾:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
package com.learndemo.controller; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller @RequestMapping(value = "/return") public class LearnReturnType { /** * Model本身不能设置页面跳转的url地址别名或者物理跳转地址,那么我们可以通过控制器方法的返回值来设置跳转url * 地址别名或者物理跳转地址 * * @param model * 一个接口, 其实现类为ExtendedModelMap,继承了ModelMap类 * @return 跳转url地址别名或者物理跳转地址 */ @RequestMapping(value = "/index1") public String index1(Model model) { model.addAttribute("result", "后台返回index1"); return "result"; } /** * ModelMap对象主要用于传递控制方法处理数据到结果页面,类似于request对象的setAttribute方法的作用。 用法等同于Model * * @param model * @return 跳转url地址别名或者物理跳转地址 */ @RequestMapping(value = "/index2") public String index2(ModelMap model) { model.addAttribute("result", "后台返回index2"); return "result"; } /** * ModelAndView主要有两个作用 设置转向地址和传递控制方法处理结果数据到结果页面 * @return 返回一个模板视图对象 */ @RequestMapping(value = "/index3") public ModelAndView index3() { ModelAndView mv = new ModelAndView("result"); // ModelAndView mv = new ModelAndView(); // mv.setViewName("result"); mv.addObject("result", "后台返回index3"); return mv; } /** * map用来存储递控制方法处理结果数据,通过ModelAndView方法返回。 * 当然Model,ModelMap也可以通过这种方法返回 * @return 返回一个模板视图对象 */ @RequestMapping(value = "/index4") public ModelAndView index4() { Map<String, String> map = new HashMap<String, String>(); map.put("result", "后台返回index4"); return new ModelAndView("result", map); } } |
2.配置thymeleaf视图解析器 这点与springMVC是相类似的:
1 2 3 4 5 6 7 |
#thymeleaf start spring.thymeleaf.mode=HTML5 spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.content-type=text/html #开发时关闭缓存,不然没法看到实时页面 spring.thymeleaf.cache=false #thymeleaf end |
实际项目中可能会有不太严格的HTML格式,此时设置mode=HTML5将会对非严格的报错,可以参考以下配置:
1 |
spring.thymeleaf.mode=LEGACYHTML5 |
1 2 3 4 5 6 7 8 9 10 |
你可能会发现在默认配置下,thymeleaf对.html的内容要求很严格,比如<meta charset="UTF-8" />, 如果少最后的标签封闭符号/,就会报错而转到错误页。也比如你在使用Vue.js这样的库,然后有<div v-cloak></div>这样的html代码, 也会被thymeleaf认为不符合要求而抛出错误。 因此,建议增加下面这段: spring.thymeleaf.mode = LEGACYHTML5 spring.thymeleaf.mode的默认值是HTML5,其实是一个很严格的检查,改为LEGACYHTML5可以得到一个可能更友好亲切的格式要求。 需要注意的是,LEGACYHTML5需要搭配一个额外的库NekoHTML才可用。 |
<dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> <version>1.9.22</version> </dependency>
1 |
最后重启项目就可以感受到不那么严格的thymeleaf了。 |
这样,需要的配置项如下:
1 2 3 4 |
# 一项是非严格的HTML检查,一项是禁用缓存来获取实时页面数据,其他采用默认项即可 thymeleaf: mode: LEGACYHTML5 cache: false |
// 完整配置项参考类ThymeleafProperties 3.编写控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/** * 测试demo的controller * * @author zcc ON 2018/2/8 **/ @Controller public class HelloController { private static final Logger log = LoggerFactory.getLogger(HelloController.class); @GetMapping(value = "/hello") public String hello(Model model) { String name = "jiangbei"; model.addAttribute("name", name); return "hello"; } } |
4.编写模板html
1 2 3 4 5 6 7 8 9 10 11 |
<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>hello</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> </head> <body> <!--/*@thymesVar id="name" type="java.lang.String"*/--> <p th:text="'Hello!, ' + ${name} + '!'">3333</p> </body> </html> |
其中,注释是通过alt+enter进行自动生成的,便于IDEA补全,如果不加,IDEA将会报错cannot reslove。 当然也可以通过如下方式解决,解决之前推荐在maven项目中reimport一下!(据说新版本的IDEA中已经修复此问题,待更新至2017.3以后) 5.测试 三、基础语法 1.创建HTML 由上文也可以知道需要在html中添加:
1 |
<html xmlns:th="http://www.thymeleaf.org"> |
这样,下文才能正确使用th:*形式的标签! 2.获取变量值${…} 通过${…}进行取值,这点和ONGL表达式语法一致!
1 2 |
<!--/*@thymesVar id="name" type="java.lang.String"*/--> <p th:text="'Hello!, ' + ${name} + '!'">3333</p> |
选择变量表达式*{…}
1 2 3 4 5 6 7 8 9 10 11 |
<div th:object="${session.user}"> <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p> <p>Surname: <span th:text="*{lastName}">Pepper</span>.</p> <p>Nationality: <span th:text={nationality}">Saturn</span>.</p> </div> 等价于 <div> <p>Name: <span th:text="${session.user.firstName}">Sebastian</span>.</p> <p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p> <p>Nationality: <span th:text="${session.user.nationality}">Saturn</span>.</p> </div> |
至于p里面的原有的值只是为了给前端开发时做展示用的.这样的话很好的做到了前后端分离。 这也是Thymeleaf非常好的一个特性:在无网络的情况下也能运行,也就是完全可以前端先写出页面,模拟数据展现效果,后端人员再拿此模板修改即可! 3.链接表达式: […]
View Details1. Druid是什么? Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。 2. 在哪里下载druid 正式版本下载: maven中央仓库: http://central.maven.org/maven2/com/alibaba/druid/ 3. 怎么获取Druid的源码 Druid是一个开源项目,源码托管在github上,源代码仓库地址是 https://github.com/alibaba/druid。同时每次Druid发布正式版本和快照的时候,都会把源码打包,你可以从上面的下载地址中找到相关版本的源码 4. 怎么配置maven Druid 0.1.18 之后版本都发布到maven中央仓库中,所以你只需要在项目的pom.xml中加上dependency就可以了。例如:
1 2 3 4 5 |
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid-version}</version> </dependency> |
也可以选择 Maven仓库查找公共的仓库地址:http://www.mvnrepository.com/artifact/com.alibaba/druid 5. 怎么打开Druid的监控统计功能 Druid的监控统计功能是通过filter-chain扩展实现,如果你要打开监控统计功能,配置StatFilter,具体看这里:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatFilter 6. 怎样使用Druid的内置监控页面 内置监控页面是一个Servlet,具体配置看这里:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatViewServlet%E9%85%8D%E7%BD%AE 7. 内置监控中的Web和Spring关联监控怎么配置? Web关联监控配置 https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_%E9%85%8D%E7%BD%AEWebStatFilter Spring关联监控配置 https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_Druid%E5%92%8CSpring%E5%85%B3%E8%81%94%E7%9B%91%E6%8E%A7%E9%85%8D%E7%BD%AE 8. 怎么配置防御SQL注入攻击 Druid提供了WallFilter,它是基于SQL语义分析来实现防御SQL注入攻击的。具体配置看这里:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE-wallfilter 9. Druid有没有参考配置 不同的业务场景需求不同,你可以使用我们的参考配置,但建议你仔细阅读相关文档,了解清楚之后做定制配置。https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_DruidDataSource%E5%8F%82%E8%80%83%E9%85%8D%E7%BD%AE 10. 我想日志记录JDBC执行的SQL,如何配置 Druid提供了Log4jFilter、CommonsLogFilter和Slf4jFilter,具体配置看这里https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_LogFilter 11. 我的程序可能产生连接泄漏了,有什么办法? Druid提供了多种监测连接泄漏的手段,具体看这里:https://github.com/alibaba/druid/wiki/%E8%BF%9E%E6%8E%A5%E6%B3%84%E6%BC%8F%E7%9B%91%E6%B5%8B 12. 在Druid中使用PSCache会有内存占用过大问题么? 连接Oracle数据库,打开PSCache,在其他的数据库连接池都会存在内存占用过多的问题,Druid是唯一解决这个问题的连接池。具体看这里:https://github.com/alibaba/druid/wiki/Oracle%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%8BPreparedStatementCache%E5%86%85%E5%AD%98%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88 13. 有没有和其他数据库连接池的对比? 各种数据库连接池对比https://github.com/alibaba/druid/wiki/%E5%90%84%E7%A7%8D%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0%E5%AF%B9%E6%AF%94 14. 从其他连接池迁移要注意什么? 不同连接池的参数参照对比: http://code.alibabatech.com/wiki/pages/viewpage.action?pageId=6947005 DBCP迁移 https://github.com/alibaba/druid/wiki/DBCP%E8%BF%81%E7%A7%BB 15. Druid中有没有类似Jboss DataSource中的ExceptionSorter ExceptionSorter是JBoss DataSource中的优秀特性,Druid也有一样功能的ExceptionSorter,但不用手动配置,自动识别生效的。具体看这里:https://github.com/alibaba/druid/wiki/ExceptionSorter_cn 16. Druid中的maxIdle为什么是没用的? maxIdle是Druid为了方便DBCP用户迁移而增加的,maxIdle是一个混乱的概念。连接池只应该有maxPoolSize和minPoolSize,druid只保留了maxActive和minIdle,分别相当于maxPoolSize和minPoolSize。 17. 我的应用配置的是JNDI数据源,可以用DruidDataSource么? DruidDataSource支持JNDI配置,具体看这里:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_JNDI_Tomcat 具体实现的类是这个:com.alibaba.druid.pool.DruidDataSourceFactory,你可以阅读代码加深理解。 18. 我的应用已使用DBCP,是代码中写死的,怎样更换为Druid? 可以的,Druid提供了一个中完全平滑迁移DBCP的办法。 1) 从http://repo1.maven.org/maven2/com/alibaba/druid/druid-wrapper/ 下载druid-wrapper-xxx.jar 2) 加入druid-xxx.jar 3) 从你的WEB-INF/lib/中删除dbcp-xxx.jar 4) 按需要加上配置,比如JVM启动参数加上-Ddruid.filters=stat,动态配置druid的filters […]
View Detailsthymeleaf的模板默认路径是resources的templates,我想把模板放到webapp下,然后就弄了半天,最后终于发现问题了(想饿自己三天不吃饭~),记录一下这次惨痛的教训😂 springboot使用thymeleaf在pom文件中引包,然后修改项目结构,修改yml配置就ok了 pom文件中引包 org.springframework.boot spring-boot-starter-thymeleaf 修改项目结构 最后点击ok然后去设置yml文件 from:https://blog.csdn.net/zhaocongc/article/details/87183872
View Details首先堆栈和堆(托管堆)都在进程的虚拟内存中。(在32位处理器上每个进程的虚拟内存为4GB) 堆栈stack 堆栈中存储值类型。 堆栈实际上是向下填充,即由高内存地址指向低内存地址填充。 堆栈的工作方式是先分配内存的变量后释放(先进后出原则)。 堆栈中的变量是从下向上释放,这样就保证了堆栈中先进后出的规则不与变量的生命周期起冲突! 堆栈的性能非常高,但是对于所有的变量来说还不太灵活,而且变量的生命周期必须嵌套。 通常我们希望使用一种方法分配内存来存储数据,并且方法退出后很长一段时间内数据仍然可以使用。此时就要用到堆(托管堆)! 堆(托管堆)heap 堆(托管堆)存储引用类型。 此堆非彼堆,.NET中的堆由垃圾收集器自动管理。 与堆栈不同,堆是从下往上分配,所以自由的空间都在已用空间的上面。 比如创建一个对象: Customer cus; cus = new Customer(); 申明一个Customer的引用cus,在堆栈上给这个引用分配存储空间。这仅仅只是一个引用,不是实际的Customer对象! cus占4个字节的空间,包含了存储Customer的引用地址。 接着分配堆上的内存以存储Customer对象的实例,假定Customer对象的实例是32字节,为了在堆上找到一个存储Customer对象的存储位置。 .NET运行库在堆中搜索第一个从未使用的,32字节的连续块存储Customer对象的实例! 然后把分配给Customer对象实例的地址赋给cus变量! 从这个例子中可以看出,建立对象引用的过程比建立值变量的过程复杂,且不能避免性能的降低! 实际上就是.NET运行库保存对的状态信息,在堆中添加新数据时,堆栈中的引用变量也要更新。性能上损失很多! 有种机制在分配变量内存的时候,不会受到堆栈的限制:把一个引用变量的值赋给一个相同类型的变量,那么这两个变量就引用同一个堆中的对象。 当一个应用变量出作用域时,它会从堆栈中删除。但引用对象的数据仍然保留在堆中,一直到程序结束 或者 该数据不被任何变量应用时,垃圾收集器会删除它。 装箱转化 using System; class Boxing { public static void Main() { int i=110; object obj=i; i=220; Console.WriteLine("i={0},obj={1}",i,obj); obj=330; Console.WriteLine("i={0},obj={1}",i,obj); } } 定义整数类型变量I的时候,这个变量占用的内存是内存栈中分配的,第二句是装箱操作将变量 110存放到了内存堆中,而定义object对象类型的变量obj则在内存栈中,并指向int类型的数值110,而该数值是付给变量i的数值副本。 所以运行结果是 i=220,obj=110 i=220,obj=330 内存格局通常分为四个区 全局数据区:存放全局变量,静态数据,常量 代码区:存放所有的程序代码 栈区:存放为运行而分配的局部变量,参数,返回数据,返回地址等, 堆区:即自由存储区 值类型变量与引用类型变量的内存分配模型也不一样。为了理解清楚这个问题,读者首 先必须区分两种不同类型的内存区域:线程堆栈(Thread Stack)和托管堆(Managed Heap)。 每个正在运行的程序都对应着一个进程(process),在一个进程内部,可以有一个或多 个线程(thread),每个线程都拥有一块“自留地”,称为“线程堆栈”,大小为1M,用于保 存自身的一些数据,比如函数中定义的局部变量、函数调用时传送的参数值等,这部分内存 区域的分配与回收不需要程序员干涉。 所有值类型的变量都是在线程堆栈中分配的。 另一块内存区域称为“堆(heap)”,在.NET 这种托管环境下,堆由CLR 进行管理,所 以又称为“托管堆(managed heap)”。 用new 关键字创建的类的对象时,分配给对象的内存单元就位于托管堆中。 在程序中我们可以随意地使用new 关键字创建多个对象,因此,托管堆中的内存资源 是可以动态申请并使用的,当然用完了必须归还。 打个比方更易理解:托管堆相当于一个旅馆,其中的房间相当于托管堆中所拥有的内存 单元。当程序员用new 方法创建对象时,相当于游客向旅馆预订房间,旅馆管理员会先看 一下有没有合适的空房间,有的话,就可以将此房间提供给游客住宿。当游客旅途结束,要 办理退房手续,房间又可以为其他旅客提供服务了。 […]
View Details