There's a risk with the .htaccess approach. He has to write specific rules to target only posts. Not all URLs on the server.
This is another approach. Works within WordPress, is 'kind-of' safer but a bit performance taxing as it needs to load the plugins before it kicks in. Theory is simple. Redirect any URL not containing . in the last segment like /uri or /uri/ to /uri.html ... ONLY IF WordPress signals a is_404() error.
// Only here we have a valid is_404() to check if occurs.
add_action('wp', function(){
if(!is_404()) return; // Bail if not a 404 (WordPress has got your back)
// Extract the URI and the Query-String (which is used later again)
list($uri, $qs) = explode('?', $_SERVER['REQUEST_URI']);
// Bail if current URL contains a . in the last segment of the URI
if(!preg_match('~/[^/\.]+/?$~', $uri)) return;
// Right-trim the last ./ and append the .html to it
$uri = rtrim($uri, '/.').".html".(!empty($qs) ? "?{$qs}" : null);
// Redirect to the new URL (with a 301 to keep link juice flowing) and hope it works :)
wp_redirect($uri, 301); die; // Over and out!
});

