Bonjour

On trouve beaucoup d'exemple d'utilisation de Ext avec PHP et moins avec java
je vous poste donc ici un extrait de ce que j'utilise pour traiter les requêtes AJAX pour mes datastore avec des reader JSON
vu que tout est json j'ai pour habitude de nommer mes ressources comme des fichiers json
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Ext.define('Gestion.model.CodeLieu', {
    extend : 'Ext.data.Model',
    fields : [ {
        name : 'DIVISION',
        type : 'string'
    }, {
        name : 'MAGASIN',
        type : 'string'
    }, {
        name : 'CODE_LIEU',
        type : 'string'
    } ],
 
    proxy : {
        type : 'json',
        api : {
            read : 'gestion/codelieu.json',
            update : 'gestion/codelieu.json'
        },
        reader : {
            type : 'json',
            root : 'codelieu',
            totalProperty : 'total',
            successProperty : 'success'
        }
    }
});
dans a première phase de dev gestion/codelieu.json est un simple fichier contenant une réponse statique.
pour passer à java dans le fichier web.xml de ma webapp j'ajoute
Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
    <servlet>
        <servlet-name>codelieu</servlet-name>
        <servlet-class>fr.aphp.ati.eai.olympe.console.web.transco.gestion.CodeLieuServlet</servlet-class>
    </servlet>
...
    <servlet-mapping>
        <servlet-name>codelieu</servlet-name>
        <url-pattern>/transco/gestion/codelieu.json</url-pattern>
    </servlet-mapping>
...
de cette façon les url ne change pas mais deviennent dynamique.
la servlet CodeLieuServlet pour les utilisateurs de php c'est un peut comme le point d'entré d'un script.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package fr.aphp.ati.eai.olympe.console.web.transco.gestion;
 
import javax.servlet.http.HttpServlet;
 
import fr.aphp.ati.eai.olympe.console.domain.transco.gestion.CodeLieuDAO;
import fr.aphp.ati.eai.olympe.console.web.transco.AbstactServlet;
 
 
/**
 * Servlet implementation class Test
 */
public class CodeLieuServlet extends AbstactServlet {
	private static final long serialVersionUID = -64654351713218L;
 
	/**
	 * @throws Exception 
	 * @see HttpServlet#HttpServlet()
	 */
	public CodeLieuServlet() throws Exception {
		super("codelieu", CodeLieuDAO.class);
	}
 
}
là rien à dire vu que j'utilise plein de servlet qui se distinguent que par leur intitulé et le DAO tout est dans l'AbstractServlet
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
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
public abstract class AbstactServlet extends AbstractJsonServlet {
 
	private static final long serialVersionUID = 1259785828935568072L;
	protected TranscoDAO dao;
	protected String name;
 
	public AbstactServlet(String name, Class<? extends TranscoDAO> clazz) throws NamingException, SQLException, InstantiationException, IllegalAccessException {
		super();
		TranscoDAO.init();
		this.dao = clazz.newInstance();
		this.name = name;
	}
 
	protected void doGet(JsonRequest request, JsonMap response) throws Exception {
		setData(request, response);
	}
 
	protected void doPost(JsonRequest request, JsonMap response) throws Exception {
		setData(request, response);
	}
 
	// la seule methode intéressante est ici.
	private void setData(JsonRequest request, JsonMap response) throws Exception {
 
 
		String order = this.getOrder(request);
		String clause = this.getClause(request);
 
		String start = request.getParameter("start", "0");
		String limit = request.getParameter("limit", "1000");
 
                //tout le boulot est ici
		response.put("success", true);
		response.put(this.name, dao.get(start, limit, clause, order));
		response.put("total", dao.count(clause));
	}
 
	protected String getClause(JsonRequest request) throws ParseException {
		//sans intérêt récupère les paramètres des filters et en fait une clause SQl
                ....
		return clause.toString();
	}
 
	protected JsonMap getOrder(JsonArray sorts, int i) throws ParseException {
		return JsonMap.jsonMap(sorts.get(i, JSONObject.class));
	}
 
	protected String getOrder(JsonRequest request) throws ParseException {
		JsonArray sorts = request.getJsonArrayParameter("sort");
		String order = dao.getDefaultOrder();
		StringBuffer sb = new StringBuffer();
		if (0 < sorts.size()) {
			JsonMap sort = this.getOrder(sorts, 0);
			this.addOrder(sb, 
					sort.get("property", String.class),
					sort.get("direction", String.class));
			order = sb.toString();
		}
		return order;
	}
 
	protected void addOrder(StringBuffer sb, String property, String direction) {
		if (0 != sb.length()) {
			sb.append(", ");
		}
		sb.append(property).append(" ").append(direction);
	}
On note que dans cette servlet on travaille en JSON on a en paramètre une jsonRequest et en réponse une JsonMap (hash map java => objet json)Java propose par défaut des HttpServlet. la classe AbstractJsonServlet va donc en dériver et masquer tout le mécanisme http pour que tout soit Json
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
HttpServlet {
	private static final long serialVersionUID = -64654321713218L;
 
	protected Logger log;
 
	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public AbstractJsonServlet() {
		super();
		this.log = LoggerFactory.getLogger(getClass());
	}
 
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//on crée une JsonMap ainsi il suffit d'ajouter des membre à la map pour qu'il soient dans la réponse
		JsonMap obj = new JsonMap();
 
		try {
			JsonRequest jsonRequest = getResquest(request);
			this.doGet(jsonRequest, obj);
			obj.put("success", true);
			this.setResponse(response, obj);
		} catch (Exception e) {
			setError(response, obj, e);
			log.error("doGet error", e);
		}
	}
 
	public void doPost(HttpServletRequest request,HttpServletResponse response) 
			throws ServletException,IOException {
 
		JsonMap obj = new JsonMap();
		try {
 
			JsonRequest jsonRequest = getResquest(request);
			this.doPost(jsonRequest, obj);
			obj.put("success", true);
			this.setResponse(response, obj);
		} catch (Exception e) {
			setError(response, obj, e);
			log.error("doPost error", e);
		}
	}
 
	//creation du jsonRequest une JsonMap qui encapsule toute la demande
	private JsonRequest getResquest(HttpServletRequest request) throws IOException, ParseException {
		return new JsonRequest(request);
	}
 
 
        //envoie de la réponse au client attention out.println ne fonctionne pas UTF-8 obligatoire pour ajax
	protected void setResponse(HttpServletResponse response, JsonMap obj) throws IOException {		
		ServletOutputStream out = response.getOutputStream();
		response.setContentType("application/json");
		response.setCharacterEncoding(CharEncoding.UTF_8);
		Writer goodWriter = new PrintWriter(new OutputStreamWriter(out, CharEncoding.UTF_8 ));
		String s = null;
		try {
			s = obj.toJSONString();
			//System.err.println(s);
		}catch(Exception e) {
			this.setError(response, JsonMap.jsonMap(), e);
		} finally {
			if (null != s) {
				//out.println(s);
				goodWriter.write(s);
				goodWriter.flush();
				goodWriter.close();
				this.log.debug("response: " + s);
			}
		}
	}
 
        //en cas d'erreur on change le succes à false et on place le message d'erreur dans la réponse.
	protected void setError(HttpServletResponse response, JsonMap obj, Exception e) throws IOException {
		obj.set("success", false);
		obj.set("error", new JsonMap());
		if (null==e.getMessage()) {
			obj.get("error", JsonMap.class).set("message", e.toString());
		} else {
			obj.get("error", JsonMap.class).set("message", e.getMessage());
		}
		if (this.log.isDebugEnabled()) {
			obj.get("error", JsonMap.class)
			.set("exception", e.getClass().getSimpleName())
			.set("stack", Arrays.toString(e.getStackTrace()));
		}
		setResponse(response, obj);		
	}
 
	protected abstract void doGet(JsonRequest jsonRequest, JsonMap response) throws Exception;
	protected abstract void doPost(JsonRequest jsonRequest, JsonMap response) throws Exception;
}
reste le JsonRequest pour encapsuler la requête HTTP dans un JsonMap
il n'y a pas grand chose à dire cest un requeswrapper comme un autre. tout les élément de la requête HTTP sont accèssibles sous forme d'élement Json jsonMap ou JsonArray (les éléments propres à l'appli comme userditail de spring y sont ajouté du coup dans les servlet il suffit de consulter l'objet jsonResquest)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
public class JsonRequest extends HttpServletRequestWrapper {
 
	private JsonMap data;
	private Logger logger;
 
	private OlympeUserDetails userDetails;
 
	public JsonRequest(HttpServletRequest request) throws ParseException, IOException {
		super(request);
		this.logger = LoggerFactory.getLogger(getClass());
		this.setUserDetails();
		this.parseRequest(request);	
	}
 
	private void parseRequest(HttpServletRequest request) throws ParseException, IOException {
		JSONParser parser = new JSONParser(JSONParser.DEFAULT_PERMISSIVE_MODE);
 
		Object input = parser.parse(request.getReader());
		if (! "".equals(input)) {
			this.data = JsonMap.jsonMap(input);
		} else {
			this.data = JsonMap.jsonMap();
		}
		@SuppressWarnings("unchecked")
		Enumeration<String> params = this.getParameterNames();
		while(params.hasMoreElements()){
			String param = params.nextElement();
			this.data.set(param, parseJsonParameter(param));
		}
		//this.data.putAll(params);
		if(this.logger.isDebugEnabled()) {
			this.logger.debug("request: " + this.data.toJSONString());
		}
	}
 
	private void setUserDetails() {
		this.userDetails = (OlympeUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
	}
 
	public JsonMap getData() {
		return data;
	}
 
	public void setData(JsonMap data) {
		this.data = data;
	}
 
	public Object parseJsonParameter(String name) throws ParseException {
		String source = super.getParameter(name);
		Object result = null;
		if (null != source) {
			JSONParser parser = new JSONParser(JSONParser.DEFAULT_PERMISSIVE_MODE);
			result = parser.parse(source);
		}
		return result;
	}
 
	public JsonArray getJsonArrayParameter(String name) throws ParseException {
		JsonArray result = new JsonArray();
 
		Object input = this.data.get(name);
		if ((null != input)&& (! "".equals(input))) {
			if (input instanceof JSONArray) {
				result = JsonArray.jsonArray((JSONArray) input);
			} else {
				result = JsonArray.jsonArray().set(input);
			}
		}
		if(this.logger.isDebugEnabled()) {
			this.logger.debug(name + ": " + input);
		}
		return result; 
	}
 
	public String getParameter(String name, String defaultValue) {
		String param = this.data.get(name).toString();
		if ((null == param)||("".equals(param))) {
			param = defaultValue;
		}
		if(this.logger.isDebugEnabled()) {
			this.logger.debug(name + ": " + param);
		}
		return param;
	}
 
	public Logger getLogger() {
		return logger;
	}
 
 
	public OlympeUserDetails getUserDetails() {
		return userDetails;
	}
 
}
l'avantage de la chose c'est que tout reste très homogène. dans une JsonServlet on manipule des jsonMap qui sont pour le développeur java de simple HashMap et des JsonArray qui là encore sont de simple ArrayList
Pas de classe spécifique pas de classe métier etc. si le client envoie un Json avec un champ de plus il sera ajouté à la map. de même côté serveur si la couche métier change les champs de la map de réponse seront changés.

dans cet exemple l'appli ne fait que de la consultation c'est pour cette raison que doGet et doPost font la même chose.

A+JYT