Spring MVC · Drill Round 2 · 16 misses · 27 drills

Spring MVC — Drill Round 2

A second batch of 16 MVC misses, and the failure pattern in them is the opposite of the one on your exam papers. On the real papers you over-select — ticking two or three options where one is right. Here, 7 of the 16 were under-selection: you ticked only correct options and still lost the mark because you stopped too early. On one question all four options were correct. Same instinct, opposite direction — and both are fixed by the same habit.

7
Under-selections (44%)
4
Two wrong options ticked
1
Polarity error (Q38)
50%
Latest MVC score

The finding: on MVC multi-selects, you stop too early

Seven of these sixteen were under-selection — every option you ticked was correct, and you still scored zero because at least one correct option went unticked. Look at how generous these questions actually were:

QuestionCorrect optionsOnly wrong option
Q30 · view technologies4 of 4none — everything was true
Q15 · auto-provided arguments4 of 4none — everything was true
Q12 · RestTemplate headers4 of 5"getForEntity accepts an HttpEntity"
Q14 · controller method arguments4 of 5ModelAndView (a return type)
Q44 · message converters3 of 4SOAP
Q26 · request workflow2 of 4the two swapping HandlerMapping/HandlerAdapter
Q27 · RestTemplate methods2 of 4two false claims about return types

Two of them had no wrong answer at all. On Q30 and Q15 the correct response was to tick everything — and "everything is true" has now appeared six times across your papers and banks. It is a real and repeated pattern, not a trick.

The fix is one habit, and it cures both directions. A multi-select is not one question — it is N independent true/false questions. Rule each option true or false on its own merits, then tick every true one. Do that and you cannot over-select (you'd have to call a false statement true) or under-select (you'd have to leave a true one unticked). On your exam papers that habit is worth ~9 marks; here it is worth 7.

Master table — arguments in, values out

Four of these sixteen turn on this one distinction, and it is the same thing that cost you marks in attempts #4, #8 and #9. Learn it as two lists, not one.

TypeParameter?Return?
HttpServletRequest / ServletRequestyesNO
HttpServletResponse / ServletResponseyesNO
HttpSessionyesno
Principalyesno
Locale, TimeZoneyesno
Errors / BindingResultyesno
@PathVariable, @RequestParam, @RequestBody, @RequestHeader, @ModelAttributeyesno
Model / ModelMap / Mapyesyes
ModelAndViewNOyes
String (view name), View, voidnoyes
ResponseEntity, HttpEntity, HttpHeadersnoyes

The two traps, in both directions: servlet objects go IN only (missed in #4, #8 and the round-1 bank), and ModelAndView comes OUT only (missed here in Q14). Model is the one type that legitimately does both — as a parameter you populate it, as a return value it is the model.

Jump to a section

① The request lifecycle — 3 ② Method arguments — 2 ③ Mapping & status codes — 4 ④ RestTemplate — 2 ⑤ Views & converters — 3 ⑥ REST semantics & MVC theory — 2

① The request lifecycle 3 misses

  request
     │
     ▼
┌──────────────────┐
│ DispatcherServlet │  the FRONT CONTROLLER — orchestrates, never does the work itself
└──────────────────┘
     │ 1. WHICH handler?  ──►  HandlerMapping   (finds — does not invoke)
     │ 2. INVOKE it       ──►  HandlerAdapter   (invokes — does not find)
     │ 3. name → View     ──►  ViewResolver     (a CHAIN, tried in order)
     │ 4. render          ──►  View
     ▼
  response
Q6 · "The central piece for HTTP request handlers, with mapping and exception handling"

DispatcherServlet

Your answer: Controller and WebServlet. @Controller handles specific requests; the question asks for the central piece. @WebServlet is Jakarta EE, not Spring at all.

The word doing the work in the stem is "central". A controller is a leaf; the DispatcherServlet is the hub every request passes through. It also owns exception handling (via HandlerExceptionResolver), which no individual controller does.

Memory hook: "Central" / "front controller" / "dispatches" ⇒ DispatcherServlet. @WebServlet is Jakarta EE, never a Spring answer.
Q26 · The mapping workflow under-selected

HandlerMapping finds; HandlerAdapter invokes

Your answer: under-selected — you took one of the two true statements. The two false ones had the roles swapped, which is the whole question.
StatementVerdict
DispatcherServlet uses both HandlerMapping and HandlerAdapterTRUE
DispatcherServlet is the front controllerTRUE
"HandlerAdapter defines a strategy for mapping requests"false — that's HandlerMapping
"HandlerMapping handles requests by invoking the method"false — that's HandlerAdapter

Read the verb, not the noun. Both false options name a real component and pair it with the other one's verb. Mapping ⇒ HandlerMapping. Adapting/invoking ⇒ HandlerAdapter. The names literally say what they do.

Why two components rather than one: HandlerAdapter exists so the DispatcherServlet can invoke different kinds of handler uniformly — an @RequestMapping method, an old Controller interface implementation, an HttpRequestHandler. Finding and invoking are genuinely separate concerns.

Memory hook: Mapping finds. Adapter invokes. Both false options swap the verbs.
Q42 · ViewResolvers

You can register many, ordered — and you needn't register any

Your answer: you ticked "an application can have only one ViewResolver". An absolute — and the opposite of how the chain works.

The contract is designed for chaining. Each resolver returns null when it can't handle a name, and the DispatcherServlet tries the next:

public interface ViewResolver {
    View resolveViewName(String viewName, Locale locale) throws Exception;
    // null ⇒ "not mine, try the next resolver"
}
StatementVerdict
Multiple resolvers, priority controlled by Ordered/setOrderTRUE
They map a String view name to a ViewTRUE
Spring ships implementations; registering one isn't obligatoryTRUEDispatcherServlet.properties supplies a default
"Only one implementation allowed"false

Lower order value = higher priority. A typical chain is ContentNegotiatingViewResolverThymeleafViewResolverInternalResourceViewResolver, with InternalResourceViewResolver last because it never returns null — it always forwards, so nothing after it would ever run.

Memory hook: ViewResolvers are a CHAIN, ordered, null = "pass". InternalResourceViewResolver must go last.

② Controller method arguments 2 misses

Both under-selected, and both answered by the master table above.

Q14 · What may be used as controller method arguments under-selected

Four of the five — ModelAndView is the odd one out because it's a return type

Your answer: under-selected. @PathVariable, Principal, ServletRequest and HttpSession are all valid parameters.

Everything Spring can inject goes through a HandlerMethodArgumentResolver. The list is long and generous — when a question asks "which may be arguments", the answer is usually "most of them":

@PostMapping("/orders/{id}")
public String handle(@PathVariable Long id,          // URI template
                     @RequestParam String mode,       // query string
                     @RequestBody OrderDto dto,       // body
                     @RequestHeader("X-Trace") String trace,
                     Principal principal,             // authenticated user
                     HttpSession session,             // session
                     HttpServletRequest request,      // raw request
                     Locale locale,                   // request locale
                     Model model) { … }               // model to populate

ModelAndView is the exception, and it's a clean rule: it bundles the model and the chosen view — a decision the handler makes, so it can only be produced, never supplied. Spring has nothing to put in it before your method runs.

Memory hook: Almost anything can be a parameter. ModelAndView is an OUTPUT — it carries a decision only your method can make.
Q15 · Arguments Spring provides automatically all four correct

All four — Errors, Model, ServletRequest, ServletResponse

Your answer: under-selected. There was no wrong option to avoid. The second "everything is true" question in this bank.

The one worth learning properly is Errors/BindingResult, because it has a positional rule the exam likes:

@PostMapping("/users")
public String create(@Valid @ModelAttribute UserForm form,
                     BindingResult errors,        // ← MUST come immediately after
                     Model model) {
    if (errors.hasErrors()) return "form";
    …
}

Errors/BindingResult must be declared directly after the validated argument. Put anything between them and Spring can't associate the two — validation failures then throw MethodArgumentNotValidException (a 400) instead of populating the object you're holding. That's not a style rule; it's how the resolver pairs them.

ServletRequest/ServletResponse being valid is the mirror of the trap you keep meeting: valid as parameters, never as return types.

Memory hook: Errors/BindingResult goes IMMEDIATELY after the @Valid argument. Servlet request and response are parameters — both of them.

③ Mapping & status codes 4 misses

Q32 · @RequestMapping with no method attribute

It handles every HTTP method

Your answer: "an exception will be thrown" and "only OPTIONS requests". Neither happens — and "an exception is thrown" is almost never the answer when the code is ordinary.

This is the third time this fact has appeared across your papers and banks, so it's worth over-learning:

DeclarationHandles
@RequestMapping("/endpoint")GET, POST, PUT, DELETE, PATCH — all of them
@RequestMapping(value="/endpoint", method=GET)GET only
@GetMapping("/endpoint")GET only — identical to the line above

This is precisely why the shortcuts exist. A bare @RequestMapping quietly exposes your GET handler to POST and DELETE too — so @GetMapping is a security improvement as much as a readability one.

Note the general technique lesson in the distractor: "an exception will be thrown" on unremarkable code is nearly always wrong. The exam shows you broken code only when it says so.

Memory hook: No method ⇒ every verb. That's why @GetMapping exists.
Q38 · Which is NOT a way to set the status code polarity error

There is no statusCode attribute on @RequestMapping

Your answer: ResponseEntity and @ResponseStatus on a methodthe two most standard ways there are. The question asked which is not valid.

The three genuine mechanisms:

MechanismWhereUse for
ResponseEntity.status(…).body(…)return valuestatus decided at runtime
@ResponseStatus(HttpStatus.CREATED)a handler methoda fixed status for that endpoint
@ResponseStatus(...)a class — controller or exceptiona default for all its methods / an error mapping
@GetMapping(statusCode = …)does not exist

Why no statusCode attribute: mapping annotations describe which requests reach this method — path, verb, headers, content types. The response is a different concern, so it lives in a different annotation. Recognising that separation makes the invented attribute obvious.

And the polarity habit, since this is your fourth "which is NOT" slip across the papers: circle the negative word before reading the options, then say "I am looking for the wrong one" before you tick anything.

Memory hook: Status comes from ResponseEntity or @ResponseStatus. Mapping annotations describe the REQUEST, never the response.
Q45 · What @PathVariable does

Binds a URI template variable to a method parameter

Your answer: the descriptions of @RequestHeader and @RequestMapping. Every option described a real annotation — you had to match description to name.
DescriptionAnnotation
Binds parts of a URI marked with template variables@PathVariable/users/{id}
Binds a web request parameter@RequestParam?name=John
Binds a request header@RequestHeader
Maps web requests onto handler methods@RequestMapping

Match on the noun in the description — "URI template" / "parameter" / "header" / "maps". Each description contains the word that names its annotation, so the pairing is mechanical once you look for it.

Memory hook: Path ⇒ @PathVariable · query ⇒ @RequestParam · header ⇒ @RequestHeader · routing ⇒ @RequestMapping.
Q49 · Statements about Spring MVC controllers

Three true — a shared path prefix is optional

Your answer: you ticked "endpoint paths must all have the same prefix". An absolute. A class-level @RequestMapping is a convenience, not a requirement.
StatementVerdict
@Controller is a stereotype annotationTRUE — a specialisation of @Component
Annotated controllers have no direct Servlet/Portlet dependencyTRUE
No specific superclass or interface is requiredTRUE
"All paths must share a prefix"false — the class-level mapping is optional

The historical point behind the two middle statements is worth having: Spring MVC used to require inheritance — you extended AbstractController or implemented the Controller interface, and your class was coupled to the Servlet API. Annotation-driven controllers (Spring 2.5+) removed that entirely, which is what "non-invasive" means in practice: a POJO with annotations.

Memory hook: @Controller is a @Component. No superclass, no Servlet dependency, no required prefix. "Must" statements about controllers are usually false.

④ RestTemplate 2 misses

Both under-selected — and headers on a RestTemplate call have now appeared in three separate banks and papers.

Q12 · Custom headers on a GET under-selected · third appearance

Four of five true — the false one is "getForEntity accepts an HttpEntity"

Your answer: under-selected. The code in that question is a bug: it builds an HttpEntity and then passes it to getForEntity, which ignores it.

Why that call silently does the wrong thing — this is the genuinely interesting bit:

restTemplate.getForEntity(url, String.class, requestEntity);
//                                            ^^^^^^^^^^^^^
// getForEntity(String url, Class<T> type, Object... uriVariables)
// the varargs are URI TEMPLATE VARIABLES — the entity is treated as a
// value for {0} in the URL, and the headers are never sent.

It compiles, it runs, and the Authorization header simply isn't there. That's what makes it a good exam question and a nasty real-world bug.

MethodTakes an HttpEntity?
getForObject / getForEntityno — trailing args are URI variables
postForObject / postForEntityyes, as the body argument
exchangeyes — any verb, headers and body
Memory hook: Custom headers ⇒ exchange(). On getFor*, trailing arguments are URI variables, not entities — the headers vanish silently.
Q27 · RestTemplate method return types under-selected

postForObject hides the status · put and delete return void

Your answer: under-selected. The two false options misdescribed return types — getForEntity returns a ResponseEntity, not a bare entity, and getForObject takes a Class, not an ObjectFactory.

The naming convention makes the whole API predictable:

SuffixReturnsStatus visible?
…ForObjectthe deserialised bodyno
…ForEntityResponseEntity<T> — body + status + headersyes
put, deletevoidno
exchangeResponseEntity<T>yes

Read the suffix and you know the answer: Object = just the body, Entity = the whole response. So "with postForObject it is impossible to check the status code" is true by construction — there's nowhere for it to appear.

Note also that RestTemplate throws on 4xx/5xx by default (HttpClientErrorException / HttpServerErrorException), so "checking the status" mostly means distinguishing among the 2xx codes.

Memory hook: ForObject = body only. ForEntity = ResponseEntity (status + headers + body). put/delete = void.

⑤ Views & message converters 3 misses

Q30 · Out-of-the-box view technologies all four correct

All four — Tiles, Thymeleaf, XSLT and JSP

Your answer: under-selected. No wrong option existed. Spring MVC ships a ViewResolver for every one of them.
TechnologyResolver
JSPInternalResourceViewResolver
ThymeleafThymeleafViewResolver — Boot's default
FreeMarkerFreeMarkerViewResolver
Groovy MarkupGroovyMarkupViewResolver
XSLTXsltViewResolver
TilesTilesViewResolver
JSON / XMLMappingJackson2JsonView, MarshallingView

The instinct to correct: "supported by Spring" is much broader than "the Boot default". Thymeleaf is the default; JSP, XSLT and Tiles are older but genuinely supported. Only reject a view technology if it isn't one — which is how JSON slipped past you on a paper question.

Memory hook: Spring supports many view technologies; Thymeleaf is merely the Boot default. Supported ≠ default.
Q44 · Default HttpMessageConverters under-selected

Byte arrays, JAXB and JSON — not SOAP

Your answer: under-selected. You correctly rejected SOAP, which is the hard part — then stopped short on the rest.
ConverterHandlesMedia type
ByteArrayHttpMessageConverterbyte[]application/octet-stream
StringHttpMessageConverterStringtext/plain
FormHttpMessageConverterform dataapplication/x-www-form-urlencoded
Jaxb2RootElementHttpMessageConverterJAXB2-annotated objectsapplication/xml
MappingJackson2HttpMessageConverterJSON (if Jackson is present)application/json

Why SOAP is excluded is a real architectural point: message converters map a body to an object. SOAP isn't a body format — it's a full protocol with an envelope, headers, a WSDL contract and its own addressing. It can't be handled by a body converter, which is why it lives in a separate project, Spring-WS.

Converters are tried in order and the first supporting the negotiated media type wins — the same chain-of-responsibility shape as the ViewResolver chain.

Memory hook: Converters handle BODY formats: bytes, String, form, XML/JAXB, JSON. SOAP is a protocol — Spring-WS, separate project.
Q34 · What Boot's MVC auto-configuration provides

Static resources, ContentNegotiatingViewResolver, HttpMessageConverters — no "testing pages"

Your answer: you ticked "RestController testing pages". There is no such feature — Boot never generates a UI for your endpoints.

What WebMvcAutoConfiguration actually gives you:

FeatureDetail
Static resourcesserved from /static, /public, /resources, /META-INF/resources
ContentNegotiatingViewResolverpicks a view by the Accept header
HttpMessageConvertersJackson for JSON, plus the defaults above
Error handlingBasicErrorController — Whitelabel page + JSON
Favicon, welcome pageindex.html from a static location
Converter/Formatter beansauto-registered
Testing pages for @RestControllersdoes not exist

The idea the distractor exploits is real but comes from elsewhere: an interactive UI for your endpoints is Swagger/OpenAPI (springdoc-openapi), a third-party library you add. Boot ships nothing like it.

Memory hook: Boot MVC auto-config: static resources, view resolution, message converters, error pages. Never a UI for your API — that's Swagger.

⑥ REST semantics & MVC theory 2 misses

Q9 · Which HTTP method is not idempotent

PATCHGET, PUT and DELETE all are

Your answer: GET and DELETE. GET is the most idempotent method there is, and DELETE is the one people most often get wrong in the other direction.
MethodSafeIdempotentWhy
GET, HEAD, OPTIONSyesyeschanges nothing at all
PUTnoyesreplaces — same body, same end state
DELETEnoyesgone after one call, still gone after five
PATCHnoNOpartial change — may be relative ("add 5")
POSTnonocreates a new resource each time

Idempotent means the end state is the same, not the response. That's the misunderstanding that makes DELETE look non-idempotent: the second call returns 404 rather than 204, but the resource is absent either way — and it's the state that defines idempotency.

Why PATCH isn't: PUT {"balance": 100} sets the balance to 100 however many times you send it. PATCH {"op":"increment","by":5} adds 5 each time. PUT states a destination; PATCH describes a change — and repeated changes accumulate.

And safe ≠ idempotent: safe means "no side effects at all" (only the read methods). Idempotent is the weaker property — "repeating it changes nothing further". Every safe method is idempotent; PUT and DELETE are idempotent without being safe.

Memory hook: Not idempotent: POST and PATCH. Idempotent but not safe: PUT and DELETE. Safe and idempotent: GET, HEAD, OPTIONS.
Q40 · "The main idea of MVC is three decoupled, easily swappable components"

No — the main idea is separation of concerns

Your answer: Yes. The statement is half-right, which is what makes it a good question: the components are decoupled, but swappability isn't the goal.

MVC exists to give each part one reason to change:

ComponentOwnsChanges when…
Modeldata and business logicthe business rules change
Viewpresentationthe UI changes
Controllerinput handling and coordinationthe interaction flow changes

Swappability is a consequence, not the purpose — and a partial one. You can realistically swap the View (JSP → Thymeleaf) because rendering is genuinely pluggable. Swapping the Model or Controller means rewriting your application, since they hold the behaviour. The statement overclaims by treating all three as interchangeable parts.

Note the exam-technique signal: a statement containing "easily" or "each of them" is usually overclaiming. Absolutes and universals on conceptual questions are a reliable tell — the same shape as "@Required is for handling dependencies" or "an application can have only one ViewResolver".

Memory hook: MVC = separation of concerns, so each part has one reason to change. Swappability is a side effect, and mainly of the View.

The 16 facts, one line each

Your pre-exam pass for this batch
The one habit to take into the next attempt Treat every multi-select as N separate true/false questions. Rule each option on its own merits, then tick every true one. That single habit is worth 7 marks in this batch (under-selection) and about 9 on your last exam paper (over-selection) — it is the same fix for both, and it is the largest single lever available to you. Then three supporting checks: (1) Circle the polarity word — not, NOT, incorrect — before reading the options. Q38 here, and four others across your papers. (2) Distrust absolutes: "only one", "must all", "easily", "always". Q42, Q49 and Q40 in this batch were all that shape. (3) "An exception will be thrown" on ordinary-looking code is nearly always wrong. And use the clock: you have ~87 minutes spare. All three checks fit comfortably in them.
I'm your teacher — ask me anything. Say "drill MVC round 2" to run all 27 of these interleaved, "drill the multi-selects" for a set built entirely of select-all-that-apply questions, or work through round 1 of the MVC clinic if you haven't yet — between them they now cover 37 MVC misses.
← Dashboard MVC clinic — round 1 Boot clinic Lesson 11 · Spring MVC