Easiest and likely most preferable would be to use some replacement of standard select as it's not much customizable.
You can try 'Chosen' jQuery plugin. This will require external js and css. However, seems to fully satisfy you requirements without pain and workarounds.
Simply 4 extra lines in your jsp:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<form:form id="form" method="post" modelAttribute="form" action="/submit2">
<form:select path="productType" required="required" >
<form:option value="" label="" />
<form:options items="${availableProductTypesForAdd}" />
</form:select>
<label for="productType">Product Type</label>
<input type="submit" name="action" value="Submit" />
</form:form>
<script src="https://harvesthq.github.io/chosen/docsupport/jquery-3.2.1.min.js"></script>
<script src="https://harvesthq.github.io/chosen/chosen.jquery.js"></script>
<link rel="stylesheet" href="https://harvesthq.github.io/chosen/chosen.css">
<script>$(function(){ $('select').chosen(); })</script>
and here you are:
(it works like a charm in more or less fresh chrome, safari, and FF on OSX)

$(function(){
$('select').chosen();
});
<link href="https://harvesthq.github.io/chosen/chosen.css" rel="stylesheet"/>
<script src="https://harvesthq.github.io/chosen/docsupport/jquery-3.2.1.min.js"></script>
<script src="https://harvesthq.github.io/chosen/chosen.jquery.js"></script>
<form id="form" action="/submit2" method="post">
<select id="productType" name="productType" required="required">
<option value=""></option>
<option value="232">232 - Monitor</option><option value="310">310 - Bad</option><option value="201">201 - Chair</option><option value="555">555 - Sofa</option><option value="191">191 - Table</option><option value="999">999 - Bookcase</option><option value="618">618 - Armchair</option><option value="230">230 - Desk</option>
</select>
<label for="productType">Product Type</label>
<input type="submit" name="action" value="Submit">
</form>
Also you can take a look at HTML Data List element
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
<form:form id="form" method="post" modelAttribute="form" action="/submit">
<form:input path="productType" list="productTypes" required="required" autocomplete="off" />
<datalist id="productTypes">
<c:forEach items="${availableProductTypesForAdd}" var="productType">
<option value="${productType.key}">${productType.value}</option>
</c:forEach>
</datalist>
<label for="productType">Product Type</label>
<button type="submit">Ok</button>
</form:form>

You can even remove keys from options as it shows and searches in both value and text
HashMap<String, String> availableProductTypesForAdd = new HashMap<>();
availableProductTypesForAdd.put("191", "Table");
availableProductTypesForAdd.put("201", "Chair");
availableProductTypesForAdd.put("230", "Desk");
availableProductTypesForAdd.put("232", "Monitor");

However, it is not as strict as select and allows to input anything not limited by options (it's by nature kind of suggestions, that's why autocomplete is off)
But if you are fine with some tiny js, you can add some extra logic to cover this gap, here is one of the options (cleans out input if it does not match one of the options):
<script>
(function() {
function verify() {
var input = document.getElementById("productType");
var o = [].map.call(input.list.options, opt => opt.value);
var opts = o.reduce((result, v) => (result[v.toUpperCase()] = v, result), {});
var value = input.value.toUpperCase();
if (!opts[value]) {
input.value = '';
return false;
}
}
document.getElementById("productType").addEventListener("focusout", verify);
document.getElementById("form").addEventListener("focusout", verify);
})();
</script>
Basically you can slightly improve default . But only if you are fine with this search not fully working when menu is opened (because that menu is not accessible from js because it's OS specific and seems to not even be a part of html).
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<form:form id="form" method="post" modelAttribute="form" action="/submit2">
<form:select path="productType" required="required" >
<form:option value="" label="" />
<form:options items="${availableProductTypesForAdd}" />
</form:select>
<label for="productType">Product Type</label>
<input type="submit" name="action" value="Submit" />
</form:form>
<script>
(function() {
var lastKeysForSearchNumber = 7; // tune # of keys entered to keep
var lastKeys = [];
var select = document.querySelector('[name=productType]');
function search(e) {
if (e.key.match(/^\w$/i)) {
lastKeys.push(e.key);
if (lastKeys.length > lastKeysForSearchNumber) {
lastKeys.shift();
}
select.value = bestMatch(select.options, lastKeys.join(''));
e.preventDefault();
}
}
function bestMatch(options, input) {
for (var i = 0; i < input.length; i++) {
for (var j = 0; j < options.length; j++) {
if (options[j].text.match(new RegExp(input.substring(i), 'i'))) { // contains ignore case
return options[j].value;
}
}
}
return '';
}
select.addEventListener("keydown", search);
})();
</script>
The idea here is to store last 7 (or whatever) keys and check every option if it contains as much as possible.

This could require some tuning and/or some adaptation for specific browsers (IE?)
Here is snipped for that, try it out:
(function() {
var lastKeysSorSearchNumber = 7;
var lastKeys = [];
var select = document.querySelector('[name=productType]');
function search(e) {
if (e.key.match(/^\w$/i)) {
lastKeys.push(e.key);
if (lastKeys.length > lastKeysSorSearchNumber) {
lastKeys.shift();
}
select.value = bestMatch(select.options, lastKeys.join(''));
e.preventDefault();
}
}
function bestMatch(options, input) {
for (var i = 0; i < input.length; i++) {
for (var j = 0; j < options.length; j++) {
if (options[j].text.match(new RegExp(input.substring(i), 'i'))) {
return options[j].value;
}
}
}
return '';
}
select.addEventListener("keydown", search);
})();
<form id="form" action="/submit2" method="post">
<select id="productType" name="productType" required="required">
<option value=""></option>
<option value="310">310 - Bad</option><option value="201">201 - Chair</option><option value="2324">2324 - Monitor</option><option value="555">555 - Sofa</option><option value="191">191 - Table</option><option value="999">999 - Bookcase</option><option value="618">618 - Armchair</option><option value="230">230 - Desk</option>
</select>
<label for="productType">Product Type</label>
<input type="submit" name="action" value="Submit">
</form>