Reputation: 29
so I am trying to fill jQuery plugin dataTables with data from my database - the problem now is how do I add a mapping for a custom servlet in java (config) only?
What this guy has to say is close Spring JavaConfig: Add mapping for custom Servlet , but I dont have a "onStartup" method anywhere in my classes - all javaconfig by the way no XML
When i dont try an ajax call and load my data from the controller to the jsp page the datatable plugin works fine and renders the table correctly so I know the problem has to be AJAX related.
I have a servlet UserDataSerlvet
package com.crutchclothing.json.datatable;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import com.crutchclothing.users.model.User;
import com.crutchclothing.users.service.UserService;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class UserDataServlet extends HttpServlet {
@Autowired
@Qualifier("userService")
UserService userService;
private static final long serialVersionUID = 1L;
public UserDataServlet() {
super();
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/json");
PrintWriter out = response.getWriter();
List<User> lisOfUsers = userService.findAllUsers();
DataTableObject dataTableObject = new DataTableObject();
dataTableObject.setAaData(lisOfUsers);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(dataTableObject);
out.print(json);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
And now in my JSP this is my javascript code to call datatables
<script type="text/javascript">
$(document).ready(function() {
$('#users').dataTable({
'bPaginate': true,
'sAjaxSource': './UserDataServlet',
'iDisplayLength': 5,
'bSort' : false,
'aoColumns' : [{'mData' : 'username'},
{ 'mData': 'firstName' },
{ 'mData': 'middleInit' },
{ 'mData': 'lastName' },
{ 'mData': 'phoneNumber' },
{ 'mData': 'address1' },
{ 'mData': 'city' },
{ 'mData': 'state' },
{ 'mData': 'email' }]
});
});
</script>
Does the amount of mData tags have to match up with the objects property? For example my user class has more properties than listed but those are the useful ones.
And finally my config classes - this is where I think the mapping needs to be added but unsure how to do it
package com.crutchclothing.config;
import java.util.Properties;
import org.apache.commons.dbcp.BasicDataSource;
import org.hibernate.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBuilder;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import com.crutchclothing.web.controller.RegistrationValidator;
@EnableWebMvc
@Configuration
@ComponentScan({ "com.crutchclothing.*" })
@EnableTransactionManagement
@Import({ SecurityConfig.class })
public class AppConfig {
@Bean
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(dataSource());
builder
.scanPackages("com.crutchclothing.users.model",
"com.crutchclothing.products.model",
"com.crutchclothing.cart.model",
"com.crutchclothing.orders.model")
.addProperties(getHibernateProperties());
return builder.buildSessionFactory();
}
private Properties getHibernateProperties() {
Properties prop = new Properties();
prop.put("hibernate.format_sql", "true");
prop.put("hibernate.show_sql", "true");
prop.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
return prop;
}
@Bean(name = "dataSource")
public BasicDataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/crutch_db");
ds.setUsername("bobby");
ds.setPassword("password");
return ds;
}
@Bean
public HibernateTransactionManager txManager() {
return new HibernateTransactionManager(sessionFactory());
}
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/pages/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
@Bean
public RegistrationValidator registrationValidator() {
return new RegistrationValidator();
}
}
package com.crutchclothing.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("userDetailsService")
UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/admin/**")
.access("hasRole('ROLE_ADMIN')").and().formLogin()
.loginPage("/login").failureUrl("/login?error")
.usernameParameter("username")
.passwordParameter("password")
.and().logout().logoutSuccessUrl("/login?logout")
.and().csrf()
.and().exceptionHandling().accessDeniedPage("/403");
}
@Bean
public PasswordEncoder passwordEncoder(){
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
}
The relavent info in the console
23:56:45.260 DEBUG o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 'dispatcher' processing GET request for [/crutchclothing/UserDataServlet]
23:56:45.260 DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Looking up handler method for path /UserDataServlet
23:56:45.261 DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Did not find handler method for [/UserDataServlet]
23:56:45.261 WARN o.s.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/crutchclothing/UserDataServlet] in DispatcherServlet with name 'dispatcher'
When I run on server from within eclipse I get an error
"DataTables warning: table id=users - ajax error. For more information about this error, please see http://datatables.net/tn/7"
But nothing when run in IE 9 and Chrome (Latest) Thank you
Upvotes: 0
Views: 10859
Reputation: 1387
This is the way I connect dataTables with Spring:
My html table:
<table id="listaVideos2" class="display">
<thead>
<tr>
<th>nombre</th>
<th>descripcion</th>
<th>codigoYoutube</th>
<th>bpm</th>
</tr>
</thead>
</table>
My JavaScript:
$.ajax({
"url": "listado2",
"type": "GET",
"datatype": 'json',
"success": function (data) {
$('#listaVideos2').DataTable({
"fixedHeader" : true,
"paging": false,
"info": true,
"autoWidth": true,
"order": [],
data: data,
select: true,
columns: [
{ "data": "nombre" },
{ "data": "descripcion" },
{ "data": "codigoYoutube",
"title": "Youtube",
"orderable": false
},
{ "data": "bpm" },
]
});
}
});
or another way you can use:
$('#listaVideos2').DataTable({
"fixedHeader" : true,
"paging": false,
"info": true,
"autoWidth": true,
"order": [],
ajax: {
url: 'listado2',
dataSrc: ''
},
select: true,
columns: [
{ "data": "nombre" },
{ "data": "descripcion" },
{ "data": "codigoYoutube",
"title": "Youtube",
"orderable": false
},
{ "data": "bpm" },
],
buttons: [
{ extend: "create", editor: editor },
{ extend: "edit", editor: editor },
{ extend: "remove", editor: editor }
],
dom: "Bfrtip",
});
And my Controller: (if your controller is a @RestController I think you wouldn't need the @ResponseBody)
@GetMapping("/listado2")
@ResponseBody
public List<Video> apiListadoVideos() {
return videosServicio.buscarTodosLosVideos();
}
where my Video class is this simple (I just remove de getters, setters...):
public class Video {
private Integer id;
@NotEmpty
@NotBlank
private String nombre;
private String descripcion;
@NonNull @NotBlank
private String codigoYoutube;
private String bpm;
private Categoria categoria;
private Tono tono;
private Modo modo;
}
Upvotes: 0
Reputation: 502
The main error is 404 - Spring did not find the handler for the url /crutchclothing/UserDataServlet.
You mixed servlet spec. and Spring MVC things up. Spring MVC has it's own servlet and you don't need to provide yours.
If you want to work with Spring MVC you should remove extends HttpServlet and add @RestController, @RequestMapping annotations with correct url as parameter, then you'll need to correct the datatable's data url in config.
Here is the tutorial on how to create Rest service with Spring from Spring.io team.
Upvotes: 1
Reputation: 15
In javascript you may need to parse the json object like this
var obj = JSON.parse(JsonString);
And the obj need to pass it to the datatable.
Upvotes: 0