我正在尝试从java applet访问servlet,并在applet的文本字段中设置servlet的响应。 我正在使用tomcat 7.0,我的jre / jdk已完全更新。 从浏览器调用时,servlet运行正常(在浏览器中输出正确)为localhost:8080 / hello / hello?query = select * from Airports
(其中机场是数据库的名称)
然而,当我在appletviewer中运行applet时,我会抛出格式错误的URL异常..
Applet代码:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
/*
<applet code="lab101" width=500 height=270>
</applet>
*/
public class lab101 extends Applet implements ActionListener{
TextArea t;
Panel p,q,r;
CheckboxGroup c;
Checkbox ins,dis,del,update; //Checkboxes are included just for testing purposes.
TextField f;
Label l1;
Button b;
public void init(){
setLayout(new FlowLayout());
b=new Button("Run");
l1=new Label("Query:");
c=new CheckboxGroup();
t=new TextArea("",10,50);
p=new Panel();
q=new Panel();
r=new Panel();
p.add(t);
ins=new Checkbox("Insert",c,false);
dis=new Checkbox("Display",c,true);
del=new Checkbox("Delete",c,false);
update=new Checkbox("Update",c,false);
f=new TextField(50);
q.add(ins);
q.add(dis);
q.add(del);
q.add(update);
r.add(l1);
r.add(f);
r.add(b);
b.addActionListener(this);
add(p);
add(q);
add(r);
try{
URL url=new URL("127.0.0.1:8080/hello/hello?query=select * from airports");
URLConnection servletconnection=url.openConnection();
servletconnection.setDoInput(true);
InputStream in=servletconnection.getInputStream();
String s="";
int ch;
loop:while(1>0){
ch=in.read();
if(ch==-1) break loop;
else s+=(char)ch;
}
t.setText(s);
}//try close
catch(MalformedURLException e){
t.setText("Malformed URL Exception occured.");}
catch(IOException e){
t.setText("IO exception occured");}
}
public void actionPerformed(ActionEvent ae){
}
public void start(){
}
public void paint(Graphics g){
}
}//class ends
servlet代码:
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.sql.*;
public class hello extends HttpServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
response.setContentType("text/plain");
PrintWriter out=response.getWriter();
String query=request.getParameter("query");
Connection link=null;
Statement statement=null;
ResultSet results=null;
try{
Class.forName("org.postgresql.Driver");
String url = "jdbc:postgresql://localhost:5432/test";
link=DriverManager.getConnection(url,"postgres","hooligan");
out.println("Successful connection");
}
catch(ClassNotFoundException e){
out.println("Unable to load driver");
}
catch(SQLException e){
out.println("Cannot connect to database");
}
try{
statement=link.createStatement();
//String select="select * from airports";
results=statement.executeQuery(query);
}
catch(SQLException e){
out.println("Cannot execute query");
e.printStackTrace();
}
try{
out.println();
while(results.next()){
out.println("Name: " + results.getString(1));
out.println("Location: " + results.getString(2));
//System.out.println("Account no: " + results.getInt(3));
System.out.println();}
}
catch(SQLException e){
out.println("Error retrieving data");
}
try{
link.close();}
catch(SQLException e){
out.println("Unable to disconnect");}
out.close();
out.flush();
}}
有什么想法吗?
P.S。我还注意到如果我使用localhost而不是127.0.0.1我会抛出一个安全异常(可能是因为applet是无符号的?)
答案 0 :(得分:2)
有2个(实际上是3个)问题:
首先,只允许applet在准确的URL基础上触发HTTP请求,就像applet的服务位置一样。您可以通过Applet#getCodeBase()
获取它,需要按如下方式使用:
URL url = new URL(getCodeBase(), "hello?query=select * from airports");
URLConnection connection = url.openConnection();
// ...
其次,您的查询字符串包含在URL(空格,星号)中使用的非法字符。您需要使用URLEncoder#encode()
对查询字符串进行URL编码。
String query = URLEncoder.encode("select * from airports", "UTF-8");
URL url = new URL(getCodeBase(), "hello?query=" + query);
URLConnection connection = url.openConnection();
// ...
您还需要确保在浏览器中使用与servlet运行位置相同的基本URL打开HTML / JSP页面。例如。 http://localhost:8080/hello/pagewithapplet.html因此不是来自命令行或appletviewer或其他东西。小程序确实需要从与servlet运行位置相同的Web服务器提供。
与问题中所述的具体问题无关,您的第三个问题是发送一个简单的SQL语句作为请求参数是非常坏主意。如果黑客反编译您的applet并计算applet-servlet通信是如何完成的,然后将SQL语句修改为其他内容,例如delete from airports
,该怎么办?
不要在applet中执行SQL,只在servlet中执行,并让applet仅发送特定命令,例如hello?query=list_airports
(实际上仍然可以进行进一步优化,想到REST Web服务,但这是由你做的一项练习。)
答案 1 :(得分:0)
URL url=new URL("127.0.0.1:8080/hello/hello?query=select * from airports")
不是有效的网址。