Я работал над одностраничным приложением, где я хотел использовать функциональность сетки в одной части приложения, которое использовало Spring MVC. Прошло некоторое время с тех пор, как я в последний раз использовал JQGrid, и найти информацию, необходимую, чтобы вывести меня из строя, было немного сложно. В этом посте я хотел собрать всю информацию и включить ее в учебное пособие, чтобы каждый, кто может использовать ту же функцию, мог бы найти полезным для настройки JQGrid .
Прежде всего, мы настроим пример веб-проекта на Eclipse и определим web.xml следующим образом;
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<? xml version = "1.0" encoding = "UTF-8" ?> < web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns = "http://java.sun.com/xml/ns/javaee" xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id = "WebApp_ID" version = "2.5" > < display-name >JQGridExample</ display-name > < welcome-file-list > < welcome-file >index.html</ welcome-file > < welcome-file >index.htm</ welcome-file > < welcome-file >index.jsp</ welcome-file > < welcome-file >default.html</ welcome-file > < welcome-file >default.htm</ welcome-file > < welcome-file >default.jsp</ welcome-file > </ welcome-file-list > < servlet > < servlet-name >JQGridExample</ servlet-name > < servlet-class > org.springframework.web.servlet.DispatcherServlet </ servlet-class > < load-on-startup >1</ load-on-startup > </ servlet > < servlet-mapping > < servlet-name >JQGridExample</ servlet-name > < url-pattern >/</ url-pattern > </ servlet-mapping > </ web-app > |
Чтобы подключить Spring MVC, я зарегистрировал DispatcherServlet для загрузки при запуске. Именно так вы зарегистрируете любое приложение Spring MVC. Далее нам нужно создать конфигурацию пружины, чтобы зарегистрировать необходимые компоненты / элементы нашего приложения MVC пружины.
В этом случае я сохранил имя файла контекста пружины на «имя сервлета», указанное в моем файле web.xml, поскольку по умолчанию при загрузке контейнера пружины он будет искать файл в формате <servletname> -servlet. XML
Если вы хотите использовать любое другое имя для файла конфигурации Spring, вы можете это сделать. Вам просто нужно зарегистрировать загрузчик контекста в вашем файле web.xml.
Итак, давайте посмотрим, как выглядит наш весенний конфигурационный файл контекста;
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<? xml version = "1.0" encoding = "UTF-8" ?> xsi:schemaLocation="http://www.springframework.org/schema/beans < context:component-scan base-package = "com.example.jqgrid.controller" /> < bean id = "multipartResolver" class = "org.springframework.web.multipart.commons.CommonsMultipartResolver" /> < bean id = "viewResolver" class = "org.springframework.web.servlet.view.InternalResourceViewResolver" > < property name = "prefix" value = "/WEB-INF/jsp/" /> < property name = "suffix" value = ".jsp" /> </ bean > < mvc:resources mapping = "/resources/**" location = "/resources/" /> < mvc:annotation-driven /> </ beans > |
Сначала мы регистрируем пакет, который содержит все наши классы контроллера. В этом случае это будет только один контроллер. С элементом component-scan он будет сканировать все классы в пакете «controller».
Далее мы сообщаем контейнеру Spring, как разрешать наши файлы JSP. В этом случае используется внутренний преобразователь представлений, и мы указываем, где находятся наши файлы JSP в приложении.
Следующая интересная часть этой конфигурации — элемент <mvc: resources> . Причина, по которой это нужно определить, — сообщить контейнеру Spring о наших статических ресурсах, таких как файлы JavaScript, изображения, таблицы стилей. Если мы не определим их как ресурсы, всякий раз, когда вы ссылаетесь на файл javascript, например, в своем приложении, Spring mvc будет пытаться сопоставить существующий контроллер, просматривая определенные шаблоны URL. В этом случае все мои файлы css, javascript, image находятся в папке ресурсов .
Затем я определяю index.jsp, который является точкой входа в наше приложение. Теперь я не хочу ничего делать на этой странице, и я просто перенаправляю это на другую страницу, которая разрешается через spring-mvc. Наш файл index.jsp выглядит следующим образом;
1
2
3
|
<script type= "text/javascript" > window.location.replace( "jqGridExample" ); </script> |
Я просто перенаправляю URL на jqGridExample . Теперь, чтобы понять, как это решается из spring-mvc, нам нужно взглянуть на наш класс контроллера. Наш класс контроллеров выглядит следующим образом;
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
package com.example.jqgrid.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.example.jqgrid.common.util.JsonUtil; import com.example.jqgrid.dto.JQGridDTO; import com.example.jqgrid.dto.SuperHeroDTO; import com.example.jqgrid.handler.JQGridHandler; /** * This class acts as the controller for JQGrid related functionality. * * @author Dinuka Arseculeratne * */ @Controller public class JQGridController { /** * This method will display the page used to display the grid. * * @param req * @param res * @return */ @RequestMapping (method = { RequestMethod.POST, RequestMethod.GET }, path = "/jqGridExample" ) public String jqGrid(HttpServletRequest req, HttpServletResponse res) { String forward = "jqgrid/jqGridData" ; return forward; } /** * This method will handle fetching data required for the JQGrid. * * @param req * @param res * @return */ @RequestMapping (method = { RequestMethod.POST, RequestMethod.GET }, path = "/loadData" ) public String loadData(HttpServletRequest req, HttpServletResponse res) { String forward = "common/formData" ; JQGridDTO<SuperHeroDTO> gridData = new JQGridHandler().loadSuperHeroes(req); req.setAttribute( "formData" , JsonUtil.toJsonObj(gridData)); return forward; } } |
Итак, если мы посмотрим на первый метод, вы увидите, что мы просто возвращаем текст с именем « jqgrid / jqGridData». Теперь, чтобы понять, что это делает, нам нужно вернуться и посмотреть на наш конфигурационный файл Spring. Мы указали, что все наши файлы JSP находятся в папке « WEB-INF / jsp », а суффикс — « .jsp ». Таким образом, в этом случае путь, который мы возвращаем из этого метода, сообщает контейнеру Spring, что возвращаемый JSP на самом деле находится в « WEB-INF / jsp / jqgrid / jqGridData.jsp ». Обратите внимание, что нам не нужно было указывать суффикс как «.jsp», потому что мы уже настроили его в нашей весенней конфигурации контекста.
Мы вернемся ко второму методу после того, как посмотрим на нашу страницу, где мы определили JQGrid. JqGridData.jsp выглядит следующим образом;
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
|
<! DOCTYPE html> < html > < head > < title >JQGrid Example</ title > < link href = "resources/css/jquery-ui.css" rel = "stylesheet" > < link href = "resources/css/jquery-ui.theme.css" rel = "stylesheet" > < link href = "resources/css/jquery-ui.structure.min.css" rel = "stylesheet" > < link rel = "stylesheet" href = "resources/css/ui.jqgrid.css" > </ head > < body > < div > < table id = "list" > < tr > < td /> </ tr > </ table > < div id = "pager" ></ div > < div style = "margin-top:10px;" > < input type = "button" id = "showSelected" value = "Show Selected" /> </ div > </ div > < script src = "resources/js/jquery-1.11.1.min.js" ></ script > < script src = "resources/js/jquery-ui.min.js" ></ script > < script src = "resources/js/i18n/grid.locale-en.js" ></ script > < script src = "resources/js/jquery.jqGrid.min.js" ></ script > < script type = "text/javascript" > $(document).ready(function(){ $("#list").jqGrid({ url : "loadData", datatype : "json", mtype : 'POST', colNames : [ 'Name','Alias','Super Power'], colModel : [ { name : 'name', index : 'name', width : 150 }, { name : 'alias', index : 'alias', width : 150, editable : false }, { name : 'power', index : 'power', width : 550, editable : false }], pager : '#pager', rowNum : 10, height: 'auto', rowList : [ 10 ], sortname : 'invid', sortorder : 'desc', viewrecords : true, gridview : true, multiselect: true, multiboxonly: false, caption : 'Super Heroes', jsonReader : { repeatitems : false, } }); jQuery("#list").jqGrid('navGrid', '#pager', { edit : false, add : false, del : false, search : false }); $('#showSelected').on('click',function(){ var selRowArr = jQuery("#list").getGridParam('selarrrow'); var selectedAppIds = []; for(var i=0;i< selRowArr.length ;i++){ var celValue = $('#list').jqGrid('getCell', selRowArr[i], 'alias'); selectedAppIds.push(celValue); } alert(selectedAppIds); $('#list').trigger( 'reloadGrid' ); }); }); </script> </ body > </ html > |
Прежде всего, нам нужно определить элемент, по которому будет загружаться JQGrid. В данном случае это элемент таблицы HTML с идентификатором « list ». И так как мы хотим иметь возможность разбивки на страницы, мы определяем наш раздел разбивки на страницы под сеткой. В этом случае раздел нумерации страниц определяется с помощью div с идентификатором « pager ».
Затем мы смотрим на код java-скрипта как нижний. Здесь мы загружаем JQGrid, вызывая метод jqGrid (), передавая необходимые атрибуты. Я не буду объяснять все атрибуты, определенные здесь, поскольку есть много других, которые я не использовал в этом случае. Наиболее важные атрибуты для этого урока будут объяснены. Итак, во-первых, URL . Это определяется как « loadData ». Нам нужно вернуться к нашему классу контроллера, чтобы понять, как это отображается.
На контроллере мы определили второй метод как « loadData », который выбирает данные, необходимые для сетки. Интересно, что JQGrid ожидает данные, передаваемые в определенном формате. Чтобы придерживаться этого формата, я определил класс для хранения этой структуры, который определен как JQGridDTO . Давайте посмотрим, как выглядит этот класс;
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
package com.example.jqgrid.dto; import java.io.Serializable; import java.util.List; /** * This class acts as common template for all pages that use the JQGrid. * * @author Dinuka Arseculeratne * * @param <T> */ public class JQGridDTO < T extends Serializable > { private int page; private String total; private String records; private List<T> rows; public int getPage() { return page; } public void setPage( int page) { this .page = page; } public String getTotal() { return total; } public void setTotal(String total) { this .total = total; } public String getRecords() { return records; } public void setRecords(String records) { this .records = records; } public List<T> getRows() { return rows; } public void setRows(List<T> rows) { this .rows = rows; } } |
Это структура данных, необходимых для JQGrid. Я сохранил общую структуру данных строк , чтобы можно было использовать этот класс для передачи различных типов данных в сетку по мере необходимости. Это может быть объект любого типа, если он реализует интерфейс Serializable .
Так что я большой поклонник супергероев, и поэтому в этом случае я буду показывать некоторую информацию о некоторых супергероях. Я включил супергероев из вселенной DC и Marvel, чтобы все были счастливы.
Итак, давайте посмотрим на наш объект данных и класс обработчика, который будет загружать наши данные;
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
package com.example.jqgrid.dto; import java.io.Serializable; /** * * @author Dinuka Arseculeratne * */ public class SuperHeroDTO implements Serializable { /** * */ private static final long serialVersionUID = 1420635747715993129L; private String name; private String alias; private String power; public SuperHeroDTO(String name, String alias, String power) { this .name = name; this .alias = alias; this .power = power; } public String getName() { return name; } public void setName(String name) { this .name = name; } public String getAlias() { return alias; } public void setAlias(String alias) { this .alias = alias; } public String getPower() { return power; } public void setPower(String power) { this .power = power; } } |
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
package com.example.jqgrid.handler; import java.util.LinkedList; import java.util.List; import javax.servlet.http.HttpServletRequest; import com.example.jqgrid.dto.JQGridDTO; import com.example.jqgrid.dto.SuperHeroDTO; /** * The handler class used to fetch the data required. * * @author Dinuka Arseculeratne * */ public class JQGridHandler { /** * This method will fetch the super hero list. Of course i have mixed and * matched DC and Marvel in order to keep peace on the universe. * * @return */ public JQGridDTO<SuperHeroDTO> loadSuperHeroes( final HttpServletRequest req) { /** * The page and rows are sent from the JQGrid component with the Ajax * query. * */ int page = Integer.valueOf(req.getParameter( "page" )).intValue(); int pageSize = Integer.valueOf(req.getParameter( "rows" )).intValue(); /** * I am not using the star index and end index in this case, but in an * ideal situation, you will be passing the start and end index to your * pagination SQL query. * */ int startIndex = page == 1 ? 0 : (pageSize * (page - 1 )); int endIndex = page == 1 ? pageSize : pageSize * page; int total = - 1 ; JQGridDTO<SuperHeroDTO> jqGridData = new JQGridDTO<SuperHeroDTO>(); List<SuperHeroDTO> superHeroList = new LinkedList<SuperHeroDTO>(); SuperHeroDTO flash = new SuperHeroDTO( "Barry Allen" , "Flash" , "Super speed, Taping into the speed force" ); superHeroList.add(flash); SuperHeroDTO superMan = new SuperHeroDTO( "Clark Kent" , "Superman" , "Flying, super speed" ); superHeroList.add(superMan); SuperHeroDTO batman = new SuperHeroDTO( "Bruce Wayne" , "Batman" , "Cool toys, Intelligence" ); superHeroList.add(batman); SuperHeroDTO professorX = new SuperHeroDTO( "Professor Xavier" , "Professor X" , "Mind control" ); superHeroList.add(professorX); /** * The total in the ideal situation would be the count of the records of * your SQL query from the table you want to fetch data from. * */ total = superHeroList.size(); jqGridData.setPage(page); jqGridData.setTotal(String.valueOf(Math.ceil(( double ) total / pageSize))); jqGridData.setRecords(String.valueOf(total)); jqGridData.setRows(superHeroList); return jqGridData; } } |
Как правило, вы будете использовать базу данных для получения ваших данных. Чтобы сохранить краткость этого урока, я только что загрузил статические данные. В комментариях к коду я упомянул, как вы будете передавать данные при использовании реальной базы данных.
В этом случае JQGrid настроен на получение данных в формате JSON. Поэтому, чтобы преобразовать наш объект супергероя в его JSON-эквивалент, я использовал библиотеку GSON от Google. Я написал вспомогательный класс для преобразования объектов JSON в объекты Java и объекты Java в объекты JSON, которыми я поделился в одной из моих предыдущих статей, которые вы можете найти здесь .
Я не использовал функциональность по умолчанию spring-mvc для отправки ответа JSON. В этом примере я устанавливаю вывод JSON в атрибуте запроса, а затем пересылаю страницу на общую страницу, где он просто распечатывает этот атрибут, и ответ отправляется обратно на запрос Ajax, сделанный компонентом JQGrid. Эта общая страница определяется следующим образом;
1
|
<%=request.getAttribute( "formData" )%> |
Возвращаясь к нашему файлу JSP, который определил JQGrid, следующим важным атрибутом, на котором я хочу сосредоточиться, является « colModel » . Это отображает данные, отправленные на вывод JSON, в отображаемые столбцы сетки. В этом случае вы можете увидеть имена, упомянутые здесь, это имена переменных экземпляра, определенные в нашем объекте данных супергероя. Остальные атрибуты говорят сами за себя, поэтому я не буду углубляться в детали этих атрибутов.
Еще один важный вариант использования, который мне потребовался, состоял в том, чтобы иметь возможность отправлять выбранные строки на сервер. Для этого вы можете использовать встроенные функции JQGrid. В следующем коде показан код, который извлекает имя супергероя во всех выбранных строках (в данном случае, поскольку в сетке включена функция множественного выбора) и помещает его в массив сценариев Java.
01
02
03
04
05
06
07
08
09
10
11
12
13
|
$( '#showSelected' ).on( 'click' ,function(){ var selRowArr = jQuery( "#list" ).getGridParam( 'selarrrow' ); var selectedAppIds = []; for (var i= 0 ;i<selRowArr.length;i++){ var celValue = $( '#list' ).jqGrid( 'getCell' , selRowArr[i], 'alias' ); selectedAppIds.push(celValue); } alert(selectedAppIds); $( '#list' ).trigger( 'reloadGrid' ); }); |
- И это заканчивается обучением по настройке JQGrid с помощью Spring MVC и Gson. Рабочий код проверен в моем GIT-репозитории и может быть найден здесь .
При необходимости вы можете клонировать репозиторий и запустить приложение.
Ссылка: | Интеграция JQGrid со Spring MVC и Gson от нашего партнера по JCG Динуки Арурилератне в блоге My Journey By IT . |