spring-mvc interview questions
Top spring-mvc frequently asked interview questions
When trying to convert a JPA object that has a bi-directional association into JSON, I keep getting
org.codehaus.jackson.map.JsonMappingException: Infinite recursion (StackOverflowError)
All I found is this thread which basically concludes with recommending to avoid bi-directional associations. Does anyone have an idea for a workaround for this spring bug?
------ EDIT 2010-07-24 16:26:22 -------
Codesnippets:
Business Object 1:
@Entity
@Table(name = "ta_trainee", uniqueConstraints = {@UniqueConstraint(columnNames = {"id"})})
public class Trainee extends BusinessObject {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "id", nullable = false)
private Integer id;
@Column(name = "name", nullable = true)
private String name;
@Column(name = "surname", nullable = true)
private String surname;
@OneToMany(mappedBy = "trainee", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@Column(nullable = true)
private Set<BodyStat> bodyStats;
@OneToMany(mappedBy = "trainee", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@Column(nullable = true)
private Set<Training> trainings;
@OneToMany(mappedBy = "trainee", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@Column(nullable = true)
private Set<ExerciseType> exerciseTypes;
public Trainee() {
super();
}
... getters/setters ...
Business Object 2:
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "ta_bodystat", uniqueConstraints = {@UniqueConstraint(columnNames = {"id"})})
public class BodyStat extends BusinessObject {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "id", nullable = false)
private Integer id;
@Column(name = "height", nullable = true)
private Float height;
@Column(name = "measuretime", nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date measureTime;
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name="trainee_fk")
private Trainee trainee;
Controller:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@Controller
@RequestMapping(value = "/trainees")
public class TraineesController {
final Logger logger = LoggerFactory.getLogger(TraineesController.class);
private Map<Long, Trainee> trainees = new ConcurrentHashMap<Long, Trainee>();
@Autowired
private ITraineeDAO traineeDAO;
/**
* Return json repres. of all trainees
*/
@RequestMapping(value = "/getAllTrainees", method = RequestMethod.GET)
@ResponseBody
public Collection getAllTrainees() {
Collection allTrainees = this.traineeDAO.getAll();
this.logger.debug("A total of " + allTrainees.size() + " trainees was read from db");
return allTrainees;
}
}
JPA-implementation of the trainee DAO:
@Repository
@Transactional
public class TraineeDAO implements ITraineeDAO {
@PersistenceContext
private EntityManager em;
@Transactional
public Trainee save(Trainee trainee) {
em.persist(trainee);
return trainee;
}
@Transactional(readOnly = true)
public Collection getAll() {
return (Collection) em.createQuery("SELECT t FROM Trainee t").getResultList();
}
}
persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="RDBMS" transaction-type="RESOURCE_LOCAL">
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<!-- <property name="dialect" value="org.hibernate.dialect.HSQLDialect"/> -->
</properties>
</persistence-unit>
</persistence>
Source: (StackOverflow)
I am looking for the easiest and simplest way to bind and convert data in Spring MVC. If possible, without doing any xml configuration.
So far I've been using PropertyEditors like so :
public class CategoryEditor extends PropertyEditorSupport {
// Converts a String to a Category (when submitting form)
@Override
public void setAsText(String text) {
Category c = new Category(text);
this.setValue(c);
}
// Converts a Category to a String (when displaying form)
@Override
public String getAsText() {
Category c = (Category) this.getValue();
return c.getName();
}
}
and
...
public class MyController {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Category.class, new CategoryEditor());
}
...
}
It is simple : both conversion are defined in the same class, and the binding is straightforward. If I wanted to do a general binding across all my controllers, I could still add 3 lines in my xml config.
But Spring 3.x introduced a new way to do it, using Converters :
Within a Spring container, this system can be used as an alternative
to PropertyEditors
So let's say I want to use Converters because it is "the latest alternative". I would have to create two converters :
public class StringToCategory implements Converter<String, Category> {
@Override
public Category convert(String source) {
Category c = new Category(source);
return c;
}
}
public class CategoryToString implements Converter<Category, String> {
@Override
public String convert(Category source) {
return source.getName();
}
}
First drawback : I have to make two classes. Benefit : no need to cast thanks to genericity.
Then, how do I simply data bind the converters ?
Second drawback : I haven't found any simple way (annotations or other programmatic facilities) to do it in a controller : nothing like someSpringObject.registerCustomConverter(...);
.
The only ways I've found would be tedious, not simple, and only about general cross-controller binding :
XML config :
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="somepackage.StringToCategory"/>
<bean class="somepackage.CategoryToString"/>
</set>
</property>
</bean>
Java config (only in Spring 3.1+) :
@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
protected void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StringToCategory());
registry.addConverter(new CategoryToString());
}
}
With all these drawbacks, why using Converters ? Am I missing something ? Are there other tricks that I am not aware of ?
I am tempted to go on using PropertyEditors... Binding is much easier and quicker.
Source: (StackOverflow)
Can @Component
, @Repository
& @Service
annotations be used interchangeably in Spring or do they provide any particular functionality besides acting as a notation device?
In other words, if I have a Service class and I change the annotation from @Service
to @Component
, will it still behave the same way?
Or does the annotation also influence the behavior and functionality of the class?
Source: (StackOverflow)
I'm a little confused as to how the inversion of control (IoC
) works in Spring
.
Say I have a service class called UserServiceImpl
that implements UserService
interface.
How would this be @Autowired
?
And in my Controllers
action, how would I instantiate
an instance
of this service?
Would I just do the following?
UserService userService = new UserServiceImpl();
Source: (StackOverflow)
Is it possible to use multiple @RequestMapping spring annotations in a method? Like:
@RequestMapping("/")
@RequestMapping("")
@RequestMapping("/welcome")
public String welcomeHandler(){
return("welcome");
}
Source: (StackOverflow)
How do I get a Spring 3.0 controller to trigger a 404?
I have a controller with @RequestMapping(value = "/**", method = RequestMethod.GET)
and for some URLs accessing the controller, I want the container to come up with a 404.
Source: (StackOverflow)
My handler forwards to internalresourceview 'apiForm' but then i get error 404 RequestURI=/WEB-INF/pages/apiForm.jsp. I'm sure apiForm.jsp located in /WEB-INF/pages/
13:45:02,034 DEBUG [org.springframework.web.servlet.view.JstlView] -
Forwarding to resource [/WEB-INF/pages/apiForm.jsp] in InternalResourceView 'apiForm'
13:45:02,035 DEBUG [org.springframework.web.servlet.DispatcherServlet] -
DispatcherServlet with name 'testapp2' determining Last-Modified value for [/WEB-INF/pages/apiForm.jsp]
13:45:02,038 DEBUG [org.springframework.web.servlet.DispatcherServlet] - No handler found
in getLastModified
13:45:02,038 DEBUG [org.springframework.web.servlet.DispatcherServlet] -
DispatcherServlet with name 'testapp2' processing request for
[/WEB-INF/pages/apiForm.jsp]
13:45:02,038 WARN [org.springframework.web.servlet.PageNotFound] - No mapping found for
HTTP request with URI [/WEB-INF/pages/apiForm.jsp] in DispatcherServlet with name 'testapp2'
13:45:02,045 DEBUG [org.springframework.web.servlet.DispatcherServlet] - Successfully completed request
13:45:02,048 DEBUG [org.springframework.web.servlet.DispatcherServlet] - Successfully completed request
this is how my dispatcher.xml look like..
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
Source: (StackOverflow)
Below is the method I wrote:
public List<Map<String, Object>> loadNotYetInEmployee(int shift, Date date,
int transitionVal, String type, User user) {
DateTime datetime = new DateTime(date);
datetime = datetime
.plus(Period.minutes(shiftTiming.getSession1InTime()));
List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
sql = SqlMapUtils.getSql("attendance.attendancestatus.latein",
parameters);
result = getJdbcTemplate().queryForList(sql);
for (int i = 0; i < result.size(); i++) {
Date punchInTime = (Date) result.get(i).get("punchtime");
DateTime punchTime = new DateTime(punchInTime);
}
return result;
}
Now from my method you can see I have a Joda-Time DateTime object in object named datetime
and from my result I am getting one timestamp which I am converting to jodatime punchTime
. Now I want to find out the diff between these two dates, how do I do that?
Thanks In advance
Source: (StackOverflow)
I see this in my Spring MVC app's web.xml
:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
I'm trying to figure out why it's there and whether it's actually needed.
I found this explanation in the Spring docs but it doesn't help me make sense of it:
It seems to suggest that this component is the "glue" between the servlets defined in web.xml
and the components defined in the Spring applicationContext.xml
.
7.1 DelegatingFilterProxy
When using servlet filters, you obviously need to declare them in your web.xml
, or they will be ignored by the servlet container. In Spring Security, the filter classes are also Spring beans defined in the application context and thus able to take advantage of Spring's rich dependency-injection facilities and lifecycle interfaces. Spring's DelegatingFilterProxy
provides the link between web.xml
and the application context.
When using DelegatingFilterProxy, you will see something like this in the web.xml
file:
<filter>
<filter-name>myFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Notice that the filter is actually a DelegatingFilterProxy
, and not the class that will actually implement the logic of the filter. What DelegatingFilterProxy
does is delegate the Filter's methods through to a bean which is obtained from the Spring application context. This enables the bean to benefit from the Spring web application context lifecycle support and configuration flexibility. The bean must implement javax.servlet.Filter
and it must have the same name as that in the filter-name element. Read the Javadoc for DelegatingFilterProxy for more information
So, if I take this out of my web.xml
, what will happen? My servlets won't be able to communicate with the Spring container?**
Source: (StackOverflow)
Sample URL:
../search/?attr1=value1&attr2=value2&attr4=value4
I do not know the names of attr1, att2, and attr4.
I would like to be able to do something like that (or similar, don't care, just as long as I have access to the Map of request param name -> value:
@RequestMapping(value = "/search/{parameters}", method = RequestMethod.GET)
public void search(HttpServletRequest request,
@PathVariable Map<Spring,Spring> allRequestParams, ModelMap model)
throws Exception {//TODO: implement}
How can I achieve this with Spring MVC?
Source: (StackOverflow)
I'm looking to create a new app from scratch and will probably use Spring MVC and possibly Spring Web Flow. The projects created by Spring Roo use Spring MVC and optionally Web Flow. What are some good alternatives for view technology, or is JSP with Spring and JSTL taglibs and jQuery the way to go?
Source: (StackOverflow)
I have an Enum desrcibed below:
public enum OrderType {
UNKNOWN(0, "Undefined"),
TYPEA(1, "Type A"),
TYPEB(2, "Type B"),
TYPEC(3, "Type C");
private Integer id;
private String name;
private WorkOrderType(Integer id, String name) {
this.id = id;
this.name = name;
}
//Setters, getters....
}
I return enum array with my controller ( new OrderType[] {UNKNOWN,TYPEA,TYPEB,TYPEC};
), and Spring serializes it into the following json string:
["UNKNOWN", "TYPEA", "TYPEB", "TYPEC"]
What is the best approach to force Jackson to serialize enums just like POJOs? E.g.:
[
{"id": 1, "name": "Undefined"},
{"id": 2, "name": "Type A"},
{"id": 3, "name": "Type B"},
{"id": 4, "name": "Type C"}
]
I played with different annotations but couldn't manage to get such result.
Source: (StackOverflow)
What is the difference between @RequestParam
and @PathVariable
while handling special characters? +
was accepted by @RequestParam
as space. In case of @PathVariable
, +
was accepted as +
.
Source: (StackOverflow)