powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / покритикуйте код и может чего посоветуйте чего?
41 сообщений из 41, показаны все 2 страниц
покритикуйте код и может чего посоветуйте чего?
    #34663874
krot-s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет всем. В java я новичек, но по работе надо написать небольшой servlet, код которого потом будут читать другие люди. Вобщем я наваял этот сервлет и прежде чем сдавать его очень хотелось бы послушать мнения профессионалов о качестве кода. Заранее благодарю за помощь и понимание.

// сам сервлет
Код: plaintext
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.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
 import  java.io.*;
 import  java.sql.*;
 import  javax.servlet.*;
 import  javax.servlet.http.*;
// include JSON libs
 import  org.json.*;
// our package
 import  ua.od.intes.*;

/**
 * Main servlet class. Gets request from client and returns answer in json format. All possible requests are predefined. 
 * @author 
 *
 */
 public   class  CBackEnd  extends  HttpServlet {
	 public   void  doGet(HttpServletRequest request,
					  HttpServletResponse response)
					   throws  ServletException, IOException
	{		
		// always return data in json format
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		
		/*
		 *  check whitch action user requests. Action is proveded by dojo frontend
		 */
		String strAction = request.getParameter("action");
		 if (strAction ==  null )
		{
			// no action specified. return error.
			out.write(jsonError("No action specified in request", "-2"));
			out.close();
			 return ;
		}
		
		 if (strAction.equalsIgnoreCase("get_types"))
		{
			// client requies types stored in database
			out.write(getStaticData(eActions.GET_TYPES,  null ));
		}
		 else   if (strAction.equalsIgnoreCase("get_categories"))
		{
			// client requires categories stored in database		
			/*
			 * get type, for which we get categories
			 */
			 int  type =  0 ;
			 try 
			{
				type = Integer.parseInt(request.getParameter("type"));
				// params 
				Object [] pParams = {type}; 
				out.write(getStaticData(eActions.GET_CATEGORIES, pParams));		
			}
			 catch (NumberFormatException ex)
			{
				out.write(jsonError("Invalid type format", "-4"));
			}
		}
		 else   if (strAction.equalsIgnoreCase("search"))
		{
			// client requies to search for specified entity
			/*try
			{
				JSONObject jsonObj = new JSONObject();	
				jsonObj.put("result", "hello from search request");
				out.write(jsonObj.toString());
			}
			catch (JSONException ex)
			{
				throw new 
				ServletException("error forming json string", ex);		
			}*/
			String strKeyword = request.getParameter("keyword");
			 if (strKeyword.length() ==  0 )
			{
				out.write(jsonError("No keyword specified", "-4"));				
			}
			 else 
			{
				Object [] pParams = {strKeyword};
				out.write(getStaticData(eActions.GET_SEARCH_RES, pParams));
			}
		}
		
		 else   if (strAction == "homepage_data")
		{
			// client requies text for start homepage
			out.write(getStaticData(eActions.GET_HOMEPAGE_DATA,  null ));		
		}
		 else 
		{
			// this type of action is not implemented, thus return error	
			out.write(jsonError("Action: " + strAction + " not implemented", "-1"));
		}
			 
		// close output
		out.close();	  
	}


	/**
	 * Gets error code and error text and return string in json format for transmition it to client
	 * @param strError_text description of error
	 * @param strError_code numeric code of error
	 * @return				String in json format	
	 * @throws ServletException
	 */
	 private  String jsonError(String strError_text, String strError_code)
				    throws  ServletException
	{
		 try 
		{
			JSONObject jsonObj =  new  JSONObject();			
			jsonObj.put("error_text", strError_text);
			jsonObj.put("error_code", strError_code);
			 return  jsonObj.toString();			
		}
		 catch  (JSONException ex)
		{
			 throw   new  
				ServletException("error forming json string", ex);			  
		}					
	}
		
	/**
	 * 
	 * @return
	 * @throws ServletException
	 */
	 private  String getStaticData(eActions action, Object [] params )
				    throws  ServletException
	{
		/*
		 *  local variables requiered to get data from database
		 */
		Connection dbConn;
		PreparedStatement sql =  null ;
		ResultSet results;
		// open new connection
		 try 
		{
			CDBConn conn =  new  CDBConn();
			conn.connect("localhost", "root", "qwerty", "test_db");
			dbConn = conn.getConn();
		}
		 catch (ServletException ex)
		{
			 return  jsonError("Error connecting to database: " + ex.getMessage(), "-11");
		}
		// json object for returning data
		JSONObject jsonObj =  new  JSONObject();		
		org.json.JSONArray pData =  new  org.json.JSONArray();	
		 try 
		{
			// now look what we should return
			 if (action == eActions.GET_TYPES)
			{
				sql = dbConn.prepareStatement("SELECT id as id, name as name FROM types");
			} else   if  (action == eActions.GET_CATEGORIES)
			{
				sql = dbConn.prepareStatement("SELECT id as id, name as name FROM categories where type = ?");
				sql.setInt( 1 , (Integer)params[ 0 ]);
			}
			 else   if (action == eActions.GET_HOMEPAGE_DATA)
			{
				sql = dbConn.prepareStatement("SELECT descr as descr FROM texts");
			}
			 else   if (action == eActions.GET_SEARCH_RES)
			{
				// sql = dbConn.prepareStatement("SELECT descr as descr FROM texts");
				/*
				 * not implemented yet
				 */
			}

			// execute query and put results in json object
			results = sql.executeQuery();
			ResultSetMetaData metaData = results.getMetaData();
			 try 
			{									
				 while (results.next())
				{		
					JSONArray pSubData =  new  JSONArray();
					// put all returned fields into array
					 for ( int  i =  0 ; i < metaData.getColumnCount(); i++)
					{					
						pSubData.put(results.getString(i+ 1 ));
					}
					pData.put(pSubData);					
				}
				jsonObj.put("result", pData);
			}
			 catch  (JSONException ex)
			{
				 return  jsonError("internal error", "-10");		  		
			}			
		} catch (SQLException ex)
		{
			 return  jsonError("error accessing database", "-3");
		}
		// return string in json format with requiered data
		//return jsonObj.toString();
		 return  pData.toString();
	}
}

// доп. классы
Код: plaintext
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.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
 package  ua.od.intes;

 import  java.sql.*;
 import  javax.servlet.ServletException;
//libs for connection polling
 import  javax.sql.DataSource;
 import  javax.naming.*;


/**
 *	This class establishes connection to database and provides connection descriptor. 
 *	Supports connection polling. 
 *	@author		
 *  @version	0.1
 */ 


/**
 * 	Database connection class
 */
 public   class  CDBConn {
	// connection descriptor
	 private  Connection dbConn;
	
	/**	Connection to database with connection polling. You would configure Tomcat properly to use this
	 * 
	 * @throws ServletException
	 */
	 public   void  connect()
				    throws  ServletException
	{
		 try 
		{
			// load proper class for mysql jdbc driver at runtime
			 Class .forName("org.gjt.mm.mysql.Driver");
			
			 try 
			{
				/*
				 *  connection polling
				 */
				 try  
				{	
					Context initCtx =  new  InitialContext();
					 if (initCtx ==  null  ) 
				           throw   new  ServletException("No Context");
		            Context envCtx = (Context) initCtx.lookup("java:comp/env");
		            Object obj = envCtx.lookup("jdbc/conversion");
		            DataSource ds = (DataSource)obj;
					dbConn = ds.getConnection();
				}
				 catch  (NamingException ex)
				{
				       throw   new  ServletException(
					        "Cannot retrieve java:comp/env/jdbc/conversion",ex);
				}
			}
			 catch  (SQLException ex)
			{
				 throw   new  
			      ServletException("error connecting to database.", ex);
			}
		}
		 catch (ClassNotFoundException ex)
		{
			 throw   new  
		      ServletException("JDBC Driver not found.", ex);			
		}	
	}
	
	/**
	 * Connection to database without connection polling. 
	 * @param username
	 * @param passwd
	 * @param dbName
	 * @throws ServletException
	 */
	 public   void  connect(String host, String username, String passwd, String dbName)
				    throws  ServletException
	{
		 try 
		{
			// load proper class for mysql jdbc driver at runtime
			 Class .forName("org.gjt.mm.mysql.Driver");
			
			 try 
			{
				dbConn = DriverManager.getConnection("jdbc:mysql://"+host+"/"+dbName+"?" + "user="+username+"&password=" + passwd);
			}
			 catch  (SQLException ex)
			{
				 throw   new  
			      ServletException("error connecting to database.", ex);
			}
		}
		 catch (ClassNotFoundException ex)
		{
			 throw   new  
		      ServletException("JDBC Driver not found.", ex);			
		}	
	}

	/**
	 * closes openned connection to database
	 * @throws ServletException
	 */
	 public   void  disconnect()
	   			 throws  ServletException	
	{
		 try 
		{
			dbConn.close();
		}
		 catch  (SQLException ex)
		{
			 throw   new  
		      ServletException("error disconnecting from database.", ex);
		}		
	}
	
	/**
	 * Returns connection descriptor for openned connection
	 * @return Connection descriptor
	 */
	 public  Connection getConn()
					   throws  ServletException
	{
		 if (dbConn ==  null )
			 throw   new  ServletException("connection not openned");
		 else 
			 return  dbConn;
	}
}


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
 package  ua.od.intes;

/**
 * Enum for simpler identification of actions to perform
 * @author 
 *
 */
 public  enum eActions {
	GET_TYPES,
	GET_CATEGORIES,
	GET_HOMEPAGE_DATA,
	GET_SEARCH_RES
}
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34663990
ТимоН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я бы разнес логику по разным классам. Советую почитать про MVC, DAO шаблоны.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664064
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да тут комментировать и комментировать.
1) Коменты в импортах не нужны.
2) Исползовать /*..*/ в методах вместо // не красиво, тем более для однострочных коментариев
3) if(strAction == "homepage_data") -- ха-ха. А intern я что-то не вижу.
4) Все строки критичные для логики крайне желательно выность в константы с понятными именами.
5) Нет единого стиля в расстановке скобок. А ведь для этого достаточно настроить IDE и попросить её отформатировать код.
6) out.close(); наверное стоило бы поместить в finally
7) getStaticData - плохое имя для метода. Совершенно ни о чем не говорит.
Работа с базой вообще не кудышняя.
8) Параметры базы должны быть в конфиге
9) Пул соединений какой-то странный. Для томката и пр серверов достаточно было бы настроить DataSource. Тут какая-то ядерная смесь самостоятельного создания физических соединений и работой с DataSource. Я даже с ходу не пойму что из этих двоих таки реально используется. В общем этот момент показывает полное незнание JDBC. Судя по всему даже лень было прочитать туториалы по теме.
10) SQL запросы в коде не красиво. Нужно выносить в текстовый файл для удобной модификации, либо использовать фреймверки.
11) Отсутствует логирование.
12) Соединения и стейтменты не закрываются.
13) Ну и дизайн в виде лесенки if...else, тоже выдает отсутствие знаний в ООП.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664111
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
14) "not implemented yet " лучше делать в виде UnsupportedOperationException
15) SELECT id as id, name as name - а для чего такие алиасы?
16) Ошибки в английском(connection polling - голосование за соединение?), небрежное отношение к сообщенийм об ошибках.
17) С коментариями вообще... они есть там где не надо и отсутствуют там где надо.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664187
krot-s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Blazkowicz:
спасибо большое за помощь! тол.ко я что-то не понял по поводу 13-го пункта. В getStaticData (действительно надо переименовать) наверное enum можно привестив int и юзать switch, тока я не знаю как :(. Или Вы что-то другое имели в виду?
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664263
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krot-s2 Blazkowicz:
спасибо большое за помощь! тол.ко я что-то не понял по поводу 13-го пункта. В getStaticData (действительно надо переименовать) наверное enum можно привестив int и юзать switch, тока я не знаю как :(. Или Вы что-то другое имели в виду?

Нет, switch это тоже самое. мало чем лучше.
Вот смотри. Для начала нужно оценить какая вероятность роста количества твоих Action. Судя по всему довольно большая. Теперь подумай. При создании каждого нового action тебе придется менять метод сервлета и метод работы с базой. А когда проект выростет количество Action вообщен может вырости до нескольких десятков, в результате у тебя будет лесенка if...else, на несколько экранов. А для того чтобы внести изменения в один любой action придется перекомпилирвать как работу с базой так и сервлет.

Решается это применением GoF паттерна Action/Command или его урезаным вариантом.
В кратце, тебе на каждый Action нужно завести отдельный класс. Кстати, строки типа "get_connection" можно поместить в enum. Читай доку по энумам.

Потом тебе надо реализовать механизм который по имени Action вытянет нужный экземпляр класса обработчика. И вызвать метод этого обработчика. Этот механизм можно реализовать кучей способов. Через HashMap, reflection, и даже через твой enum. Ведь в enum-е можно определять методы для каждого элемента. Поиск на rsdn к сожалению сломался. Так бы я нашел тебе пример.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664270
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczКстати, строки типа "get_connection" можно поместить в enum.
Опечатался. Имелось в виду - get_categories
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664422
Фотография fixxer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz
Решается это применением GoF паттерна Action/Command или его урезаным вариантом.
В кратце, тебе на каждый Action нужно завести отдельный класс.


У меня почему-то стойкое ощущение, что это State/Strategy. Возможно ошибочное.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664531
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В принципе, да. Скорее стратегия. У меня просто от struts устойчивая ассоциация action и command.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664606
krot-s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а ткните меня носом в простенький пример с этими шаблонами или дайте линк на хороший туториал плз. (мне это надо сегодня до 12-и ночи сделать)
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664647
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krot-sа ткните меня носом в простенький пример с этими шаблонами или дайте линк на хороший туториал плз. (мне это надо сегодня до 12-и ночи сделать)
Гугл в помощь. Я бы на твоем месте поступил так. За оставшееся время нормально переработал работу с базой. А по поводу №13, там где у тебя несколько if..else пишешь камент:

//TODO:[krot-s] Refactor to replace if..else chain with separate classes for better expansibility

Потому что за JDBC тебя побъют гораздо больше чем за это.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664680
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я бы еще за табуляции вместо пробелов больно бил по почкам :)
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664756
krot-s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Timmя бы еще за табуляции вместо пробелов больно бил по почкам :)
ну а табуляция чем не догодила-то?
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664763
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krot-s Timmя бы еще за табуляции вместо пробелов больно бил по почкам :)
ну а табуляция чем не догодила-то?
Раздражает. Смотреть исходники в разных средах неудобно.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664777
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Timm wrote:

>> ну а табуляция чем не догодила-то?
> Раздражает. Смотреть исходники в разных средах неудобно.

Да ну ладно, в сравнении с тем, как сделано в "родных" сорцах (4
пробела, потом табуляция, потом табуляция и 4 пробела и т.д.)- это
ничего, это легко правится. А вот за смесь и того и того- точно убивать.

--
Алексей
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664778
y3u
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Timmя бы еще за табуляции вместо пробелов больно бил по почкам :)

а я бы за еще за скобочки на новой строке, а еще за throw new на одной строке, а Exception на другой...
Вобщем надло пользоваться автоматическим форматированием, как уже говорили, обычно в нормальных IDE темплейты форматирования соответствуют общепринятым стандартам
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664806
Фотография Penkov Vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
идея при нажатии на home ставит курсор в начало строки <--> текста в
строке, так что без разницы, есть там табы или нет
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34664931
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
y3uа я бы за еще за скобочки на новой строке
А вот этого не надо. Такой стиль удобнее для чтения. Об этом даже в Bitter Java написано.
Меня после полу-года C# все 4 года явы воротит от явовского стиля скобки на той же строке.

Вообще обсуждения табики vs пробелы и куда ставить скобки это древние флеймы. На rsdn несколько лет назад обсуждались. А вывод только один. Ставить можно как угодно. Только надо быть увереным, что все в одном стиле.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34665262
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz y3uа я бы за еще за скобочки на новой строке
А вот этого не надо.
+1. мне так удобно :)
Deadyидея при нажатии на home ставит курсор в начало строки <--> текста в
строке, так что без разницы, есть там табы или нет
среда != IDE в общем случае.
хоть блокнот.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34665470
y3u
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz y3uа я бы за еще за скобочки на новой строке
А вот этого не надо. Такой стиль удобнее для чтения. Об этом даже в Bitter Java написано.

во-первых я сказал "я бы" :), тем более у нас в компании такой стандарт, мы используем смешаный стиль, для "короткого" кода и для длинного... Мало ли что написано в горькой джаве, не стоит канонизировать и превращать в религию простые здравые взгляды на код, к которым нормальный девелопер, если он не конченый раздолбай, приходит самостоятельно примерно через 2 года усиленной работы с кодом и самообразования...
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34665553
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
y3uво-первых я сказал "я бы" :), тем более у нас в компании такой стандарт, мы используем смешаный стиль, для "короткого" кода и для длинного... Мало ли что написано в горькой джаве, не стоит канонизировать и превращать в религию простые здравые взгляды на код, к которым нормальный девелопер, если он не конченый раздолбай, приходит самостоятельно примерно через 2 года усиленной работы с кодом и самообразования...
Не надо канонизировать стандарт своей компании. О религии ты тут первый заговорил. У меня, позиция простая
- стиль должен быть единым на проект, все равно каким.
- скобка на новой строке облегчает чтение.

Как ты тут религию с канонами разглядел, не понятно.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34665566
swt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczНе надо канонизировать стандарт своей компании.ну да.. лучше канонизировать стандарт самого себя, как ты это очень неплохо показал в этом топике.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34665605
krot-s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
учел я замечания Blazkowicz и сделал все в отдельных классах с рефлексией. Может еще раз код выложить, чтобы вы его похаяли (для меня это будет оч. полезно)?
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34665627
someone1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выложи- самому интересно поучиться
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34665635
y3u
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz
- скобка на новой строке облегчает чтение.


ура, давайте флудить!

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
 if  (a == b) 
{
     return  a;
}
 else 
{
     return  b;
}

мне не легче читается, чем

Код: plaintext
1.
2.
3.
4.
5.
 if  (a == b) {
     return  a;
}  else  {
     return  b;
}

по крайней мере на моем монике на 3 строчки полезного кода больше влазит...
Лично я делаю скобку на новой строке только в лучае, если получается какая-то длинная строка, но это бывает очень редко, т.к. я в таких случаях делаю экстракт метод :)
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34665650
y3u Blazkowicz
- скобка на новой строке облегчает чтение.


ура, давайте флудить!

давайте.
Код: plaintext
1.
2.
3.
4.
 if  (somethingRotten.isThisFuckinCaseWillBeMine(iKnowItWill) && somethingElse) {
     return   new  AndWhatAboutReadability( new  NothingWillPreventMeFromDoingIt());
}  else  {
     return   new  ReadabilityIsNothing( new  RocknRollIsNotDeadBaby());
}
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 if  (somethingRotten.isThisFuckinCaseWillBeMine(iKnowItWill) && somethingElse)
{
     return   new  AndWhatAboutReadability( new  NothingWillPreventMeFromDoingIt());
}
 else 
{
     return   new  ReadabilityIsNothing( new  RocknRollIsNotDeadBaby());
}
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34665677
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
swtну да.. лучше канонизировать стандарт самого себя, как ты это очень неплохо показал в этом топике.
Лучше обсудить собеседника, чем сказать что-то умное?
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34665681
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
y3uмне не легче читается, чем
Ну просто железный, аргумент. С чем тут спорить. Мнение таких экспертов как Тейт, конечно же ерунда. Да, кто он такой. "Мне не легче" и это главное.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34665686
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krot-sучел я замечания Blazkowicz и сделал все в отдельных классах с рефлексией. Может еще раз код выложить, чтобы вы его похаяли (для меня это будет оч. полезно)?
Интересно, а к чему был этот вопрос? Выложил - давно бы уже обсудили. Можно начать с того что использование рефлекии скорее всего не обосновано в данном случае. Лично я бы предпочел использовать рефлексию в последнюю очередь.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34665810
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
давайте пофлудим wrote:

> давайте.

На мой взгляд на одной строчке должна быть одна конструкция.
И если она помещается на одной строчке- она должна быть на одной.

if(...){ - одно по сути
...
}else{ - другое
...
} - третье.

Увы, модный C-like синтаксис...
А языках идущих от синтаксиса algol-68 всё понятнее (на примере Ada)

if ... then
...
else
...
end if;

Лучше уж писать на Java как на языках с нормальным синтаксисом :)

--
Алексей
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34665981
smbdy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34666257
krot-s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну вот новая версия. Только с исключениями я перемудрил. что-то не могу по-человечески сделать. может подскажете как лучше всего их обрабатывать? К примеру: приходит запрос на получение каких-то данных из базы. Сначала подгружается соответствующий класс, потом в том классе создается объект для подключения и при подключении возникает exception. Как лучше всего "выплюнуть" это исключение на самый верх для обработки, а то у меня это как-то коряво вышло...

Код: plaintext
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.
 import  java.io.*;
 import  javax.servlet.*;
 import  javax.servlet.http.*;
 import  ua.od.intes.*;
 import  java.lang.reflect.*;
/**
 * Main servlet class. Gets request from client, loades proper class, responsible for 
 * that request and returns answer in json format. 
 * @author Krot Vyacheslav
 *
 */
 public   class  CBackEnd  extends  HttpServlet 
{
	 public   void  doGet(HttpServletRequest request,
					  HttpServletResponse response)
					   throws  ServletException, IOException
	{	
		// always return data in json format
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		// check whitch action user requests. Action is proveded by dojo frontend
		String strAction = request.getParameter("action");
		String strParams = request.getParameter("params");
		 if (strAction ==  null )
		{
			// no action specified. return error.
			out.write(CUtils.jsonError("No action specified in request"));
			out.close();
			 return ;
		}

		// load proper class and invoke single method returning required data in json format
		// all data to function is passed as single json string 
		 try 
		{
			// load class
			 Class  requestHandler =  Class .forName("ua.od.intes." + strAction);
			// parameters list for method to invoke
			 Class  [] paramTypes = {String. class };  
			Method handlerMethod = requestHandler.getMethod("getData", paramTypes);
			// create new instance of class
			Object handlerInstance = requestHandler.newInstance();
				
			// fill params
			Object[] parameters = { strParams };
			// invoke method
			Object retobj = handlerMethod.invoke(handlerInstance, parameters);
			out.write(retobj.toString());
		}
		 catch (ClassNotFoundException ex)
		{
			out.write(CUtils.jsonError("Internal error: Class for required action not found"));
		}
		 catch (Exception ex)
		{
			out.write(CUtils.jsonError("Internal error:" + ex.getCause().getMessage()));
			ex.printStackTrace();
		}
		 finally 
		{
			out.close();
		}
	}	
}


// класс подключения к базе
Код: plaintext
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.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
 package  ua.od.intes;

 import  java.sql.*;
 import  javax.sql.DataSource;
 import  javax.naming.*;
 import  java.io.File;
 import  java.util.*;
 import  javax.xml.parsers.DocumentBuilder;
 import  javax.xml.parsers.DocumentBuilderFactory;
 import  org.w3c.dom.Document;
 import  org.w3c.dom.Element;
 import  org.w3c.dom.Node;
 import  org.w3c.dom.NodeList;

/**
 *	Establishes connection to database and provides connection descriptor. 
 *	Supports connection pooling. 
 *	@author		Krot Vyacheslav
 *  @version	0.1
 */ 
 public   class  CDBConn 
{
	// connection descriptor
	 private  Connection dbConn;

	// file with connection parameters
	 private  String configFileName = "webapps\\test_3\\config\\config.xml";
	
	/**
	 * Openes new connection to database
	 * @param withConnectionPooling Determines wheather to use or not connection pooling
	 * @throws Exception If an error occures it's description is returned in Exception
	 */
	 public   void  connect( boolean  withConnectionPooling)
				 throws  Exception
	{
		 try 
		{
			// load proper class for mysql jdbc driver at runtime
			 Class .forName("org.gjt.mm.mysql.Driver");			
			 try 
			{			
				 if (withConnectionPooling == true)
				{
					// connection pooling
					 try  
					{	
						// Create a JNDI Initial context to be able to lookup  the DataSource
						InitialContext ctx =  new  InitialContext();
						// Lookup the DataSource
						DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/conversion");
						dbConn = ds.getConnection();
					}
					 catch  (NamingException ex)
					{
						 throw   new  Exception(
						        "Cannot retrieve java:comp/env/jdbc/conversion", ex);
					}
				}
				 else 
				{
					HashMap connParams = readConfig(configFileName);
					dbConn = DriverManager.getConnection(
							"jdbc:mysql://" + connParams.get("hostname") + "/" + connParams.get("db_name") + "?" + 
							"user=" + connParams.get("username") + "&password=" + connParams.get("passwd"));					
				}
			}
			 catch  (SQLException ex)
			{
				 throw   new  
			      Exception("Error connecting to database", ex);
			}
		}
		 catch (ClassNotFoundException ex)
		{
			 throw   new  
		      Exception("Error conneting to database: JDBC driver not found", ex);			
		}	
	}
	

	/**
	 * Closes openned connection to database
	 * @throws Exception
	 */
	 public   void  disconnect()
	   			 throws  Exception	
	{
		 if (dbConn ==  null )
		{
			 throw   new  
		      Exception("Failed to close connection: connection not openned");			
		}
		 try 
		{				
			dbConn.close();
			dbConn =  null ;
		}
		 catch  (SQLException ex)
		{
			 throw   new  
		      Exception("Failed to close connection", ex);
		}		
	}
	
	/**
	 * Returns connection descriptor for openned connection
	 * @return Connection descriptor
	 * @throws Exception
	 */
	 public  Connection getConn()
					   throws  Exception
	{
		 if (dbConn ==  null )
			 throw   new  Exception("Failed to return connection: connection not openned");
		 else 
			 return  dbConn;
	}
	
	/**
	 * Reades parameters of connection from specified XML file. Format of file is strongly defined
	 * @param filename
	 * @return HashMap with corresponding parameters
	 * @throws ServletException
	 */
	 public  HashMap readConfig(String filename)
				 throws  Exception
	{
		// returned results
		HashMap<String,String> map =  new  HashMap();
		 try  
		{
			// open file with XML config
			File file =  new  File(filename);
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(file);
			doc.getDocumentElement().normalize();
			NodeList nodeLst = doc.getElementsByTagName("db_config");
			 if (nodeLst.getLength() !=  1 )
			{
				 throw   new  Exception("Failed to loading config file: invalid format",  new  java.lang.Throwable());
			}			
			// read data from node
			Node cNode = nodeLst.item( 0 );
			 if  (cNode.getNodeType() == Node.ELEMENT_NODE) 
			{
				Element fstElmnt = (Element) cNode;
				NodeList lstNmElmntLst = fstElmnt.getElementsByTagName("username");
				Element lstNmElmnt = (Element) lstNmElmntLst.item( 0 );
				NodeList lstNm = lstNmElmnt.getChildNodes();
				map.put("username", ((Node) lstNm.item( 0 )).getNodeValue());
				
				lstNmElmntLst = fstElmnt.getElementsByTagName("passwd");
				lstNmElmnt = (Element) lstNmElmntLst.item( 0 );
				lstNm = lstNmElmnt.getChildNodes();
				map.put("passwd", ((Node) lstNm.item( 0 )).getNodeValue());
				
				lstNmElmntLst = fstElmnt.getElementsByTagName("hostname");
				lstNmElmnt = (Element) lstNmElmntLst.item( 0 );
				lstNm = lstNmElmnt.getChildNodes();
				map.put("hostname", ((Node) lstNm.item( 0 )).getNodeValue());

				lstNmElmntLst = fstElmnt.getElementsByTagName("db_name");
				lstNmElmnt = (Element) lstNmElmntLst.item( 0 );
				lstNm = lstNmElmnt.getChildNodes();
				map.put("db_name", ((Node) lstNm.item( 0 )).getNodeValue());
			}
			 else 
			{
				 throw   new  Exception("Failed to load configuration file: invalid format");
			}
			
		} 
		 catch  (Exception ex) 
		{
			 throw   new  Exception("Failed to load configuration file", ex);
		}	
		
		 return  map;
	}	
}

// класс обработки запрошеного действия
Код: plaintext
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.
 package  ua.od.intes;

 import  java.sql.*;

 import  org.json.*;

/**
 * Gets list of types from database
 * @author Krot Vyacheslav
 *
 */
 public   class  GetTypes 
{
	 public  String getData(String strParams)
				   throws  Exception
	{
		// local variables requiered to get data from database
		Connection dbConn =  null ;
		PreparedStatement stmt =  null ;
		ResultSet results =  null ;
	
		// open new connection
		CDBConn conn =  new  CDBConn();
		conn.connect(true);
		dbConn = conn.getConn();
		
		// json object for returning data	
		org.json.JSONArray pData =  new  org.json.JSONArray();	
		 try 
		{
			stmt = dbConn.prepareStatement("SELECT id, name FROM types");

			// execute query and put results in json object
			results = stmt.executeQuery();
			ResultSetMetaData metaData = results.getMetaData();
			 while (results.next())
			{		
				JSONArray pSubData =  new  JSONArray();
				// put all returned fields into array
				 for ( int  i =  0 ; i < metaData.getColumnCount(); i++)
				{					
					pSubData.put(results.getString(i+ 1 ));
				}
				pData.put(pSubData);					
			}
		}
		 catch (SQLException ex)
		{
			 throw   new  
				Exception("Error reading data from database", ex);
		}
		 finally 
		{
			// close connection and statement
			 try 
			{
				results.close();
				results =  null ;
				stmt.close();
				stmt =  null ;
			}
			 catch (Exception ex)
			{  
				// nothing could be done about it
			}
			conn.disconnect();
		}
		 return  pData.toString();
	}
}
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34666497
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, понеслась по новой.
1) На счет reflection и поиска Action по имени. По хорошему нужно чтобы каждый класс Action реализовывал интерфейс с методом getData. Тогда перед тем как делать getData можно было бы проверить найденый класс реализует этот интерфейс или нет. И вообще можно было бы обойтись без reflection. У тебя был очень хороший enum. С каждым элементом энума можно ассоциировать поля. На твоем бы месте я именно там хранил имя класса-экшна и имя самого экшна. И в энуме был бы метод который по имени экшна возвращал элемент перечисления. А из элемента можно было бы получить класс. (А по хорошему туда можно сразу сложить экземпляры классов, чтобы не делать Class.forName())
2) Класса работы с базой я вообще не понял. Зачем тебе вариант там где нет datasource?
Вот этого "java:comp/env/jdbc/conversion" и вот этого "jdbc:mysql://" не должно быть в коде. Это конфигурационные данные. Вообще нет смысла собирать строку соединения в коде. Обычно она целиком прописывается в конфиге. Имя и пароль не обязательно засовывать в строку соединения. Для них есть второй метод getConnection
3)
Код: plaintext
1.
2.
3.
results.close();
results = null;
stmt.close();
stmt = null;
Если results.close(); выкенет исключение, то stmt.close(); не произойдет. Это конечно очень маловероятное событие. Но все же. Присваивать null здесь совсем не обязательно. Пахнет какой-то параноей.
4)В хорошем коде обычный Exception никогда не ловится и никогда не прокидывается. Надо ловить только ожидаемые исключения, а не все подря. Надо прокидывать свои бизнес-исключения.
Beware the dangers of generic Exceptions - Java World
5) Зачем для конфига использовать DOM когда с классом Properties было бы гораздо меньше кода?
6)
throw new Exception("Failed to loading config file: invalid format", new java.lang.Throwable());
На кой здесь new java.lang.Throwable()? Ты доки по классам когда-нибудь читаешь? И как всегда английский - "Failed to load"
7) При работе с datasource строка Class.forName("org.gjt.mm.mysql.Driver") не нужна. Почему она тогда вне условия?
8) "text/html" разве подходящий MIME тип для JSON? JSON ведь совсем не HTML
9) Над Coding Convention надо ещё поработать. Почему некоторые классы имеют приставку C, а некоторые - нет. Именование переменных и методов не всегда удачное. Экономить букавы в именах не вседа полезно. Чем ближе код к английскому языку тем легче он читается.
10) Для чего иногда используется полное имя класса включающее пакет?
11) Сдвиг для строк какой-то большой, обычно используется 4 пробела. У тебя сколько? Или это парсер так нарисовал?
12) Когда ты работаешь только с интерфейсом Map нет никакого смысла объявлять переменные и возвращаемые типы как HashMap. Мне кажется хорошим стилем использовать наиболее общий интерфейс. Поэтому HashMap достаточно только при создании экземпляра.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34666602
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz
11) Сдвиг для строк какой-то большой, обычно используется 4 пробела. У тебя сколько? Или это парсер так нарисовал?

Это как раз дебильный side-effect табуляции. На форуме 1 tab = 8 spaces.
smbdyимхо, аргументы аля "мне так удобней" не совсем корректны. Не нужно забывать, что обычно люди работают в комманде. Да и не факт что через пару лет кому то не прийдеца его сапортить.
Это был не аргумент, а констатация факта. Впрочем в компании так принято, как раз из-за удобства.
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34666626
krot-s
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz
1) На счет reflection и поиска Action по имени. По хорошему нужно чтобы каждый класс Action реализовывал интерфейс с методом getData. Тогда перед тем как делать getData можно было бы проверить найденый класс реализует этот интерфейс или нет. И вообще можно было бы обойтись без reflection. У тебя был очень хороший enum. С каждым элементом энума можно ассоциировать поля. На твоем бы месте я именно там хранил имя класса-экшна и имя самого экшна. И в энуме был бы метод который по имени экшна возвращал элемент перечисления. А из элемента можно было бы получить класс. (А по хорошему туда можно сразу сложить экземпляры классов, чтобы не делать Class.forName())

вот это я вообще не понял... :(

Blazkowicz
5) Зачем для конфига использовать DOM когда с классом Properties было бы гораздо меньше кода?

А можно подробней, а то я вчера быстренько пример разбора XML нашел, его и впихнул?

Blazkowicz
11) Сдвиг для строк какой-то большой, обычно используется 4 пробела. У тебя сколько? Или это парсер так нарисовал?

у меня вообще табуляции везде, а не пробелы. Так что это парсер.

p.s. еще раз спасибо за помощь. если какими-либо судьбами занесет в Одессу - с меня пиво (мыло в профиле)
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34666711
zalexaka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krot-s
А можно подробней, а то я вчера быстренько пример разбора XML нашел, его и впихнул? для чтения конфигов обычно использую Digester
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34666830
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krot-s
вот это я вообще не понял... :(

http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html

Смотри внизу пример с Planet и думай.

krot-s
А можно подробней, а то я вчера быстренько пример разбора XML нашел, его и впихнул?

http://www.exampledepot.com/egs/java.util/Props.html
Начиная с Java 5 может работать с XML
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34667117
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, и вот все вспоминаю и забываю вписать. В коде отсутствует логирование.
По хорошему на уровне логгера DEBUG надо в лог валить и запросы, и результаты в виде JSON.
Ну и вообще правильно логировать на всех уровнях ERROR/WARN/INFO/DEBUG
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34667289
newj
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczДа тут комментировать и комментировать.
10) SQL запросы в коде не красиво. Нужно выносить в текстовый файл для удобной модификации, либо использовать фреймверки.


а если благодоря "службам безопасности" работа приложения с текстовыми файлами у заказчика не возможна (реальный случай имелся) или запрос формируется динамически в зависимости от каких-то условий, что тогда делать?)
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34667511
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
newjа если благодоря "службам безопасности" работа приложения с текстовыми файлами у заказчика не возможна (реальный случай имелся) или запрос формируется динамически в зависимости от каких-то условий, что тогда делать?)

Текстовые файлы находятся не где-то там на диске, а где-то внутри приоложения, рядом с классами, запакованые в jar. Какие тут ещё безопасности? Может и JVM запускать нельзя? Она столько всяких файлов читает аж страшно.

Когда запрос формируется динамически, то используются шаблоны. Смотри, например, iBatis и подобные. Зависит конечно от ситуации. Но как минимум имена таблиц и колонок могут изменится. Запросы можно оптимизировать. И выходит для этого всегда придется пересобирать проект (еже ли запросы в коде хранить)?
...
Рейтинг: 0 / 0
покритикуйте код и может чего посоветуйте чего?
    #34668955
newj
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz newjа если благодоря "службам безопасности" работа приложения с текстовыми файлами у заказчика не возможна (реальный случай имелся) или запрос формируется динамически в зависимости от каких-то условий, что тогда делать?)

Текстовые файлы находятся не где-то там на диске, а где-то внутри приоложения, рядом с классами, запакованые в jar. Какие тут ещё безопасности? Может и JVM запускать нельзя? Она столько всяких файлов читает аж страшно.

не знаю какие там безапасности, но текстовый файл был не где то там , а как раз в приложении.
при попытке чтения был посыл в... о чем сообщал WAS своими логами и его админ.

Когда запрос формируется динамически, то используются шаблоны. Смотри, например, iBatis и подобные. Зависит конечно от ситуации. Но как минимум имена таблиц и колонок могут изменится. Запросы можно оптимизировать. И выходит для этого всегда придется пересобирать проект (еже ли запросы в коде хранить)?
спасибо, надо глянуть.
...
Рейтинг: 0 / 0
41 сообщений из 41, показаны все 2 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / покритикуйте код и может чего посоветуйте чего?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]