How do Struts2 actions compare to Servlets? Can an action act as a servlet?
Struts is an abstraction layer on top of the vanilla java servlet stuff. Actions themselves are defined by the programmer and are invoked by struts frameworks when a URL is hit (you configure what url maps to which action). So they don't really "compare" to a servlet, they are an abstraction around the functionality the servlet provides. One typical thing you do with an action is output a jsp, which is equivalent to a servlet. so what happens is a) request comes in, gets mapped to action b) action loads some data c) action renders a jsp, passing loaded data to the jsp.
An action can output directly to the request/response, if that is what you want, but in most cases is probably not good practice.
A Struts (Struts1/Struts classic) action was more tied to a servlet. In Struts2, things are very different. A Struts2 action is a POJO, totally decoupled to servlets API - which eases testing. In the typical workflow of a Struts2 webapp, an action will be instantiated for each request and be associated with a Servlet (it can implement the ServletAware if it needs to be aware of this association; normally is not necessary nor advisable).
An important conceptual difference with Servlets (and with Struts actions) is that Struts2 actions are not reused for different requests, and hence are thread safe: say, it can happen that three http requests (simultaneous or not) are served by one servlet instance; but there will be three Struts2 action instances, one for each request.