上手 is ordinarily a [形容動詞]{けいようどうし} or "na-adjective". It could be used as a noun on its own, but more commonly it's describing something else.
Like with other 形容動詞, it takes な when describing another noun attributively - just as it would be followed by だ・です to describe something predicatively (like 「彼は日本語(が)上手です」). But here, it is describing a verb (話します, i.e. the formal form of 話す) attributively, so it takes に.
This is common grammar; you may also be familiar with [静]{しず}かに "quietly", or at least [本当]{ほんとう}に "truly", which is practically a set expression by itself. This に is essentially the "-ly" part (disregarding of course that in English we say "well" rather than "goodly").
Using が here would make no sense; it would have to mean something like "As for John, his skill speaks Japanese". (Or his flattery, using an alternate definition.)
I usually see it with が
-- が, not だ ?