Chandler Redmond put the visitors on top with an RBI groundout, Mateo Gil added a two-run single and Zach Jackson stroked a run-scoring double in the top of the first.
The Cardinals (23-18) scored three more times in the third for a 7-1 lead and went up 9-2 with a two-run sixth. Johnson City surrendered three runs in the lower half of the sixth, but Hector Soto came in to blank the Rays for two innings before Wilfredo Pereira hurled a scoreless ninth.
Julio Puello (3-2) turned in a five-inning start for the Redbirds, yielding two runs on six hits. He put up seven strikeouts against just one walk.
Johnson City banged out 14 hits, with Kyle Skeels going 3 for 4 with a double and three runs. Liam Sabino went 2 for 3, drove in two runs and scored twice.
Also for the Cards, Jackson and Todd Lott each batted 2 for 5. Jackson, Redmond and Gil both contributed two RBIs while Lott chipped in a pair of runs.
A 12-hit Princeton attack included two hits apiece from Gionti Turner (double, 2 RBIs), Jelfry Marte, Diego Infante and Jake Guenther.
Johnson City, which took two of three in the series, hosts Bluefield on Friday beginning at 6:30 p.m. Princeton (19-22) will be at Danville.