Para checar meus 5 centavos:
TL, DR
Uso MimetypesFileTypeMap e adiciono qualquer mímica que não esteja lá e preciso especificamente dela, no arquivo mime.types.
E agora, a longa leitura:
Primeiro, a lista de tipos MIME é enorme , veja aqui: https://www.iana.org/assignments/media-types/media-types.xhtml
Gosto de usar as instalações padrão fornecidas pelo JDK primeiro e, se isso não funcionar, irei procurar outra coisa.
Determinar o tipo de arquivo da extensão do arquivo
Desde a versão 1.6, o Java possui MimetypesFileTypeMap, conforme apontado em uma das respostas acima, e é a maneira mais simples de determinar o tipo mime:
new MimetypesFileTypeMap().getContentType( fileName );
Na sua implementação de baunilha, isso não faz muito (ou seja, funciona para .html, mas não para .png). No entanto, é super simples adicionar qualquer tipo de conteúdo que você possa precisar:
- Crie um arquivo chamado 'mime.types' na pasta META-INF no seu projeto
- Adicione uma linha para cada tipo MIME que você precisa e a implementação padrão não fornece (existem centenas de tipos MIME e a lista aumenta à medida que o tempo passa).
As entradas de exemplo para arquivos png e js seriam:
image/png png PNG
application/javascript js
Para o formato de arquivo mime.types, veja mais detalhes aqui: https://docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html
Determinar o tipo de arquivo a partir do conteúdo do arquivo
Desde 1.7, Java possui java.nio.file.spi.FileTypeDetector , que define uma API padrão para determinar um tipo de arquivo de maneira específica de implementação .
Para buscar o tipo MIME para um arquivo, basta usar Arquivos e fazer isso no seu código:
Files.probeContentType(Paths.get("either file name or full path goes here"));
A definição da API fornece recursos que suportam a determinação do tipo de mímica de arquivo a partir do nome do arquivo ou do conteúdo do arquivo (bytes mágicos). É por isso que o método probeContentType () lança IOException, caso uma implementação dessa API use o Path fornecido para tentar realmente abrir o arquivo associado a ela.
Novamente, a implementação baunilha disso (a que acompanha o JDK) deixa muito a desejar.
Em algum mundo ideal em uma galáxia muito distante, todas essas bibliotecas que tentam resolver esse problema de arquivo a mimo simplesmente implementariam java.nio.file.spi.FileTypeDetector , você deixaria o jar da biblioteca de implementação preferida arquivo em seu caminho de classe e seria isso.
No mundo real, aquele em que você precisa da seção TL, DR, você deve encontrar a biblioteca com mais estrelas ao lado do nome e usá-la. Para este caso em particular, não preciso de um (ainda;)).