关于使用servlet的正确方式的问题



我想创建一个servlet,允许我将图像文件从客户端上传到服务器。我正在帮助自己完成我在apache网站上找到的教程:http://commons.apache.org/fileupload/using.html

在我的路上,我发现了一些复杂和怀疑:

问题1

我希望我的servlet准备一个包含请求中所有值的对象(包括byte[]形式的图像),并将其传递给@EJB,后者将所有值插入数据库中。这可能吗?您能给出一些伪代码提示,说明如何改进我当前的servlet来做到这一点吗?

@WebServlet(name="uploadServlet")
public class FileUpload extends HttpServlet {
    @EJB
    private DBAccessEJB ejb;
    private static final long serialVersionUID = -1062753489906645120L;
    // Will be triggered when a post method is sent by the user(Example: Form
    // submit)
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // Check if the request is multipart
        boolean isMultipart = ServletFileUpload.isMultipartContent(req);
           // Create the object that willBe passed to the EJB 
              Thing thing = new Thing();
        if (isMultipart) {
            // If it is multipart, save the items in a FileItemfactory
            FileItemFactory factory = new DiskFileItemFactory();
            // Create an upload handler
            ServletFileUpload upload = new ServletFileUpload(factory);
            try {
                // Get the files out of the request
                List items = upload.parseRequest(req);
                Iterator iterator = items.iterator();
                while (iterator.hasNext()) {
                    // Get each of the items inside the items list
                    FileItem item = (FileItem) iterator.next();
                    // If the item does not come from a field
                    if (!item.isFormField()) {
                       //transform the uploaded images to byte[]
                                       //setTheImageValues of the object
                    }
                                    else {
                                       //set the text values of the object
                                    }
                }
                          //Pass the prepared object to the EJB to be inserted in DB
                          ejb.save(thing)
            } catch (FileUploadException fue) {
                fue.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

问题2

我想过通过管理bean而不是从JSF页面将请求传递给servlet,但我真的不知道该怎么做。你能给我一些提示吗?我也不知道如何以正常的方式来做,从页面上看,你认为什么是最好的方式?到目前为止,这就是我对托管bean所做的:

public void save() {
        FacesContext fc = FacesContext.getCurrentInstance();
        HttpServletRequest req = (HttpServletRequest)fc.getExternalContext().getRequest();

//我还需要什么才能将请求传递到服务器
}

这将出现在一个多部分表单中的页面上:

<h:commandButton value="Submit" action="myBackingBean.save"/>

问题3

在我的JSF页面中,我或多或少有10个值——几乎都是字符串。我从JSF中获取它们,并将它们临时存储在JSF页面中。如果servlet可以从请求中获取所有值,那么在backingbean中就不需要这些属性了。你认为这样做是件好事吗?这将是流程交易的安全性,还是存在任何风险?

怀疑#1:

看起来您在这里使用EJB作为服务层,其中包含用EJB注释注释的DAO,使其成为会话bean。我不喜欢这种方法,您会遇到EJB世界和HTTP请求世界的差异所引起的问题。

需要注意的是,使用EJB的最大原因之一是管理事务,并且事务必须保持短时间(以毫秒为单位)。这有很多原因,例如数据库上的锁。但是,当处理带有上载的http请求时,这将不再有效。

从另一个角度来看,服务层应该表示数据库模型的抽象,并且应该从用户的角度展示您可以对模型做什么。用户不想将图像保存到数据库中,用户想将肖像添加到他的个人资料中。

而不是

ejb.save(thing)

我更喜欢这样的功能

profileService.addPortrait(uid, byte[] image);

这明确说明了它的作用,也满足了短交易的要求。这意味着配置文件实体可用于其他可能同时出现的请求(如某些状态图像或收件箱状态…)

怀疑#2:

入乡随俗…

从学习一些基本的语言开始。在本例中,从一些教程中学习JSF。

怀疑#3:

拦截浏览器和JSF组件之间的请求参数会破坏组件架构和数据隐藏原则。它还将绕过JSF组件的服务器端部分中实现的任何安全措施和验证。

如果您使用JSF组件框架,那么只从组件而不是从请求本身询问值是有意义的。

从你的三个疑虑中,我觉得你有一个更大的疑虑:我应该使用JSF吗?

如果这是你的雇主强制要求的:接受它,开始记录。。。了解JSF和EJB解决了哪些问题,并根据这些问题构建工作框架。

如果你可以自由选择:选择一个更轻的框架,例如Spring+SpringMVC。你会积累经验,并按照自己的节奏遇到这些问题。

问题1-

当然,你的文件需要唯一标识符,但如果你按照日期/用户名等将文件存储在文件夹中,这就不那么复杂了

以下是您可以使用的程序的基本工作流程,基于您迄今为止所展示的内容:

客户端计算机->FileUploadServlet(利用Apache Commons文件上传)

一旦进入FileUploadServlet:

a) 通过EJB将请求中的信息保存到数据库中,包括文件名、Mime类型、信息等

b) 当仍然在servlet中时,将文件上传到服务器,或者如果需要,使用商业解决方案,如Amazon S3或Google Storage(通过Java API,如JetS3t)

之后,将任何必要的信息返回给客户。

问题2-

您通过Bean请求的理由是什么?为什么不让Servlet作为操作,并从请求中收集信息呢?我不会让Bean的保存方法在JSF上可用,因为这听起来不安全并且没有经过身份验证。

问题3-

和上面一样,当信息在其他地方可用时,为什么要存储信息,即使是暂时的?

相关内容

  • 没有找到相关文章

最新更新