在HTML中上传pdf并反序列化json文件 [英] Upload pdf in HTML and Deserialize json file

查看:143
本文介绍了在HTML中上传pdf并反序列化json文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用html上传文件,然后通过restangular发送给我的数据库。
我的前端是角色与打字稿的组合,但上传是一种形式。

 < form enctype =多部分/格式数据> 
< fieldset class =form-groupng-repeat =$ ctrl.metadata.fields中的字段>
< label ng-if =field.inputType!=='hidden'for ={{field.propertyKey}}>< strong> {{field.name}}< / strong> ;< /标签>
< input ng-if =field.inputType!=='select'&& field.inputType!=='file'class =form-controltype ={{field.inputType }}name ={{field.propertyKey}}id ={{field.propertyKey}}ng-model =$ ctrl.data [field.propertyKey]/>
< input ng-if =field.inputType ==='file'class =form-controlngf-select type ={{field.inputType}}name ={{field。 propertyKey}}id ={{field.propertyKey}}ng-model =$ ctrl.data [field.propertyKey]/>
< sp-dropdown ng-if =field.inputType ==='select'value =$ ctrl.data [field.propertyKey]api-domain =field.linkedObjectApiDomainlinked-object- NAME = field.linkedObjectName >< / SP-下拉>
< / fieldset>
< button class =btn btn-primaryng-click =$ ctrl.save({item:$ ctrl.data})>保存< / button>
< button ng-if =$ ctrl.metadata.buttons.hasOpenclass =btn btn-primaryng-click =$ ctrl.open()>打开< /按钮>
< / form>

我使用

保存后我们输入这个打字稿保存方法。

p>

  public save(item:any):any {
console.log(item is save is,item);
console.log(关系是,item [关系]); (item.id ===未定义){

this.restService.save(this.metadata.apiDomain,item).then((addedItem:any)=> {
toastr.success(`$ {addedItem.naam}成功创建.`,`Overzicht Dossiers Created`);
});
} else {
this.restService.update(this.metadata.apiDomain,item).then((updatedItem:any)=> {
toastr.success(`$ {updatedItem。 naam}已成功更新.`,`Overzicht Dossiers Updated`);
});


$ / code>

文件的第二个日志给出了json:

 
lastModified:1463402787393
lastModifiedDate:Mon May 16 2016 14:46:27 GMT + 0200(Romance(zomertijd))
name:Rapport.pdf
size:83605
类型:application / pdf
上传:Promise
webkitRelativePath:
__proto __:File

在服务器端我使用了一个我自己没有设置的spring项目,但重要的文件是我的类,它应该存储这个数据
档案

/ *
*要更改此许可证标题,请在项目属性中选择许可证标题。
*要更改此模板文件,请选择工具|模板
*并在编辑器中打开模板。
* /
包be.ugent.lca.data.entities;

  import be.ugent。 sherpa.entity.BaseEntity; 
import java.sql.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
$ b / **
*
* @author Sam
* /
@Entity
// @ JsonDeserialize(using = DossierDeserializer.class )
// @ JsonSerialize(using = DossierSerializer.class)
public class Dossier extends BaseEntity {
private String externDossierNr;
private String internDossierNr;
私人日期数据;
私有布尔doc;
私人日期refKlantDatum;
私人字符串refKlantVerwijzing;
私人字符串verantw;


@OneToOne(fetch = FetchType.LAZY,mappedBy =dossier)
private Offerte offerte;

私人字符串状态;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name =persoon)
private Persoon persoon;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name =OrganisatieFirma)
private OrganisatieFirma organisatieFirma;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name =OrganisatieIntern)$​​ b $ b private OrganisatieIntern organisatieIntern;

@Lob
@Column(长度= 100000)
私人字节[]融洽;

public Offerte getOfferte(){
return offerte;
}

public void setOfferte(Offerte offerte){
this.offerte = offerte;
}

public byte [] getRapport(){
return rapport;
}

public void setRapport(byte [] rapport){
this.rapport = rapport;
}

public OrganisatieFirma getOrganisatieFirma(){
return organisatieFirma;
}

public String getExternDossierNr(){
return externDossierNr;
}

public void setExternDossierNr(String externDossierNr){
this.externDossierNr = externDossierNr;
}

public String getInternDossierNr(){
return internDossierNr;
}

public void setInternDossierNr(String internDossierNr){
this.internDossierNr = internDossierNr;
}

public void setOrganisatieFirma(OrganisatieFirma organisatieFirma){
this.organisatieFirma = organisatieFirma;
}

public OrganisatieIntern getOrganisatieIntern(){
return organisatieIntern;
}

public void setOrganisatieIntern(OrganisatieIntern organisatieIntern){
this.organisatieIntern = organisatieIntern;
}

public Persoon getPersoon(){
return persoon;
}

public void setPersoon(Persoon persoon){
this.persoon = persoon;
}

public String getStatus(){
return status;
}

public void setStatus(String status){
this.status = status;
}

public Date getDatum(){
return datum;
}

public void setDatum(Da​​te datum){
this.datum = datum;
}

public Date getRefKlantDatum(){
return refKlantDatum;
}

public void setRefKlantDatum(Da​​te refKlantDatum){
this.refKlantDatum = refKlantDatum;
}

public String getRefKlantVerwijzing(){
return refKlantVerwijzing;
}

public void setRefKlantVerwijzing(String refKlantVerwijzing){
this.refKlantVerwijzing = refKlantVerwijzing;
}

public String getVerantw(){
return verantw;
}

public void setVerantw(String verantw){
this.verantw = verantw;
}

public Boolean getDoc(){
return doc;
}

public void setDoc(Boolean doc){
this.doc = doc;
}

}



和我的这个课程的资料库

  / * 
*要更改此许可证标题,请在项目属性中选择许可证标题。
*要更改此模板文件,请选择工具|模板
*并在编辑器中打开模板。
* /
包be.ugent.lca.data.repository;

导入be.ugent.lca.data.entities.Dossier;
导入be.ugent.lca.data.query.DossierQuery;
导入be.ugent.sherpa.repository.RestRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
/ **
*
* @author Sam
* /
@RepositoryRestResource(collectionResourceRel =dossiers,path =dossiers)
public接口DossierRepository扩展了RestRepository< Dossier,DossierQuery>> {

}

当试图将文件保存到我的数据库时,服务器发出这个异常
引起:com.fasterxml.jackson.databind.JsonMappingException:无法将字节[]的实例反序列化为START_OBJECT标记



这让我相信我必须为Dossier
编写我自己的反序列化器因此:

 包be.ugent.lca.data.entities.deserializers; 


导入be.ugent.lca.data.entities.Dossier;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;

public class DossierDeserializer extends JsonDeserializer {
@Override
public Dossier deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext)throws IOException {
ObjectCodec oc = jsonParser。 getCodec();
JsonNode root = oc.readTree(jsonParser);
档案档案=新档案();

dossier.setExternDossierNr(root.get(externDossierNr)。asText());
dossier.setInternDossierNr(root.get(internDossierNr)。asText());

归还卷宗;
}
}

但我的问题是我不知道如何完全反序列化json文件,因为写出root.get(rapport)会返回一个空字符串。



任何帮助都将非常感谢。

解决方案

我已经完成了文件上传。



首先,从我的其余数据中上传文件,所以我不必重写自动反序列化的一切工作。

  this.restService.save(this.metadata.apiDomain,item).then((addedItem:any)=> {
toastr.success(`$ {addedItem.naam} successfully created .`,`Overzicht Dossiers Created `);
console.log(created item,addedItem);
var fd = new FormData();
fd.append(rapport,item [rapport]) ;

this.restService.one('dossiers /'+ addedItem.id +'/rapport').withHttpConfig({transformRequest: angular.identity})。customPOST(fd ,'',undefined,{'Content-Type':undefined})。然后(
(addedDossier:any)=> {
console.log(贴出的档案,addedDossier);
}
);
});

在我正常保存的回调中,我将自定义帖子发送到 dossiers / {id} /关系为此我需要一个自定义控制器。

  @BasePathAwareController 
@RequestMapping(/ dossiers / {id})
@ExposesResourceFor(Dossier.class)
public class DossierController {

BasePathAwawareController确保所有自动生成的路径不会被覆盖保留。

  @Autowired 
private DossierRepository dossierRepository;

通过这个,我注入我的资源库以连接到我的数据库。

  @RequestMapping(path =/ rapport,method = RequestMethod.POST)//,headers =content-type = multipart / form-data)
public @ResponseBody String postRapport(@PathVariable(id)Long id,@ RequestParam(rapport)MultipartFile文件){
String name =rapport;
System.out.println(使用ID输入自定义文件上传+ id);
if(!file.isEmpty()){
try {
byte [] bytes = file.getBytes();
档案档案= dossierRepository.findOne(id);
dossier.setRapport(bytes);

dossierRepository.save(dossier);
return您成功上传了+ name +到+ name +-uploaded!;
} catch(Exception e){
return您未能上传+ name +=>+ e.getMessage();
}
} else {
return由于文件为空,因此未能上传+ name +。




$ b $ p
$ b

像这样,我可以成功上传我的文件。


I'm trying to upload a file in html and then send it to my database via restangular. My frontend is a combination of angular with typescript but the upload is a form.

<form enctype="multipart/form-data">
    <fieldset class="form-group" ng-repeat="field in $ctrl.metadata.fields">
        <label ng-if="field.inputType !== 'hidden'" for="{{field.propertyKey}}"><strong>{{field.name}}</strong></label>
        <input ng-if="field.inputType !== 'select' && field.inputType !== 'file'" class="form-control" type="{{field.inputType}}" name="{{field.propertyKey}}" id="{{field.propertyKey}}" ng-model="$ctrl.data[field.propertyKey]"/>
        <input ng-if="field.inputType === 'file'" class="form-control" ngf-select type="{{field.inputType}}" name="{{field.propertyKey}}" id="{{field.propertyKey}}" ng-model="$ctrl.data[field.propertyKey]"/>
        <sp-dropdown ng-if="field.inputType === 'select'" value="$ctrl.data[field.propertyKey]" api-domain="field.linkedObjectApiDomain" linked-object-name="field.linkedObjectName"></sp-dropdown>
    </fieldset>
    <button class="btn btn-primary" ng-click="$ctrl.save({item: $ctrl.data})">Save</button>
    <button ng-if="$ctrl.metadata.buttons.hasOpen" class="btn btn-primary" ng-click="$ctrl.open()">Open</button>
</form>

I did the databinding of the file with ng-file-upload.

Upon saving we enter this typescript save method.

public save(item: any): any  {
    console.log("item to save is ", item);
    console.log("rapport is ", item["rapport"]);

    if (item.id === undefined) {
        this.restService.save(this.metadata.apiDomain, item).then((addedItem: any) => {
            toastr.success(`${addedItem.naam} successfully created.`, `Overzicht Dossiers Created`);
        });
    } else {
        this.restService.update(this.metadata.apiDomain, item).then((updatedItem: any) => {
            toastr.success(`${updatedItem.naam} successfully updated.`, `Overzicht Dossiers Updated`);
        });
    }
}

The second log with the file gives the json:

    lastModified:1463402787393
    lastModifiedDate:Mon May 16 2016 14:46:27 GMT+0200 (Romance (zomertijd))
    name:"Rapport.pdf"
    size:83605
    type:"application/pdf"
    upload:Promise
    webkitRelativePath:""
    __proto__:File

On server side I'm using a spring project which I didn't set up myself but the important files are my class which should store this data Dossier /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package be.ugent.lca.data.entities;

import be.ugent.sherpa.entity.BaseEntity;
import java.sql.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;

/**
 *
 * @author Sam
 */
@Entity
//@JsonDeserialize(using = DossierDeserializer.class) 
//@JsonSerialize(using = DossierSerializer.class) 
public class Dossier extends BaseEntity{
    private String externDossierNr;
    private String internDossierNr;
    private Date datum;
    private Boolean doc;
    private Date refKlantDatum;
    private String refKlantVerwijzing;
    private String verantw;


    @OneToOne(fetch=FetchType.LAZY, mappedBy="dossier")
    private Offerte offerte;

    private String status;

    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name = "persoon")
    private Persoon persoon;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "OrganisatieFirma")
    private OrganisatieFirma organisatieFirma;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "OrganisatieIntern")
    private OrganisatieIntern organisatieIntern;

    @Lob
    @Column(length=100000)
    private byte[] rapport;

    public Offerte getOfferte() {
        return offerte;
    }

    public void setOfferte(Offerte offerte) {
        this.offerte = offerte;
    }

    public byte[] getRapport() {
        return rapport;
    }

    public void setRapport(byte[] rapport) {
        this.rapport = rapport;
    }

    public OrganisatieFirma getOrganisatieFirma() {
        return organisatieFirma;
    }

    public String getExternDossierNr() {
        return externDossierNr;
    }

    public void setExternDossierNr(String externDossierNr) {
        this.externDossierNr = externDossierNr;
    }

    public String getInternDossierNr() {
        return internDossierNr;
    }

    public void setInternDossierNr(String internDossierNr) {
        this.internDossierNr = internDossierNr;
    }

    public void setOrganisatieFirma(OrganisatieFirma organisatieFirma) {
        this.organisatieFirma = organisatieFirma;
    }

    public OrganisatieIntern getOrganisatieIntern() {
        return organisatieIntern;
    }

    public void setOrganisatieIntern(OrganisatieIntern organisatieIntern) {
        this.organisatieIntern = organisatieIntern;
    }

    public Persoon getPersoon() {
        return persoon;
    }

    public void setPersoon(Persoon persoon) {
        this.persoon = persoon;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Date getDatum() {
        return datum;
    }

    public void setDatum(Date datum) {
        this.datum = datum;
    }

    public Date getRefKlantDatum() {
        return refKlantDatum;
    }

    public void setRefKlantDatum(Date refKlantDatum) {
        this.refKlantDatum = refKlantDatum;
    }

    public String getRefKlantVerwijzing() {
        return refKlantVerwijzing;
    }

    public void setRefKlantVerwijzing(String refKlantVerwijzing) {
        this.refKlantVerwijzing = refKlantVerwijzing;
    }

    public String getVerantw() {
        return verantw;
    }

    public void setVerantw(String verantw) {
        this.verantw = verantw;
    }

    public Boolean getDoc() {
        return doc;
    }

    public void setDoc(Boolean doc) {
        this.doc = doc;
    }

}

and my repository for this class

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package be.ugent.lca.data.repository;

import be.ugent.lca.data.entities.Dossier;
import be.ugent.lca.data.query.DossierQuery;
import be.ugent.sherpa.repository.RestRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
/**
 *
 * @author Sam
 */
@RepositoryRestResource(collectionResourceRel = "dossiers", path = "dossiers")
public interface DossierRepository extends RestRepository<Dossier, DossierQuery<?>>{

}

When trying to save a file to my database the server gives this exception Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of byte[] out of START_OBJECT token

This led me to believe that I have to write my own deserializer for Dossier Thus:

package be.ugent.lca.data.entities.deserializers;


import be.ugent.lca.data.entities.Dossier;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;

public class DossierDeserializer extends JsonDeserializer {
    @Override
    public Dossier deserialize(JsonParser jsonParser,
            DeserializationContext deserializationContext) throws IOException {
        ObjectCodec oc = jsonParser.getCodec();
        JsonNode root = oc.readTree(jsonParser);
        Dossier dossier = new Dossier();

        dossier.setExternDossierNr(root.get("externDossierNr").asText());
        dossier.setInternDossierNr(root.get("internDossierNr").asText());

        return dossier;
    }
}

But my problem is that I don't know how exactly to deserialize the file json, since writing out root.get("rapport") gives back an empty string.

Any help would be much appreciated.

解决方案

I've worked out the file upload.

First of all I split the file upload from the rest of my data so I won't have to rewrite the automatic deserialization for everything that does work.

this.restService.save(this.metadata.apiDomain, item).then((addedItem: any) => {
    toastr.success(`${addedItem.naam} successfully created.`, `Overzicht Dossiers Created`);
    console.log("created item ", addedItem);
    var fd = new FormData();
    fd.append("rapport", item["rapport"]);

    this.restService.one('dossiers/' + addedItem.id + '/rapport').withHttpConfig({transformRequest: angular.identity}).customPOST(fd, '', undefined, {'Content-Type': undefined}).then(
        (addedDossier: any) => {
            console.log("posted dossier ", addedDossier);
        }
    );
});

In the callback of my normal save I do the custom post to dossiers/{id}/rapport for this I need a custom controller.

@BasePathAwareController
@RequestMapping("/dossiers/{id}")
@ExposesResourceFor(Dossier.class)
public class DossierController {

The BasePathAwawareController makes sure that all automatically generated paths that you don't override keep existing.

@Autowired
private DossierRepository dossierRepository;

With this I inject my repository to connect to my database.

@RequestMapping(path = "/rapport", method = RequestMethod.POST)//,headers = "content-type=multipart/form-data") 
public @ResponseBody String postRapport(@PathVariable("id") Long id,@RequestParam("rapport") MultipartFile file) {
    String name = "rapport";
    System.out.println("Entered custom file upload with id " + id);
    if (!file.isEmpty()) {
        try {
            byte[] bytes = file.getBytes();
            Dossier dossier = dossierRepository.findOne(id);
            dossier.setRapport(bytes);

            dossierRepository.save(dossier);
            return "You successfully uploaded " + name + " into " + name + "-uploaded !";
        } catch (Exception e) {
            return "You failed to upload " + name + " => " + e.getMessage();
        }
    } else {
        return "You failed to upload " + name + " because the file was empty.";
    }
}

Like this I'm able to successfully upload my file.

这篇关于在HTML中上传pdf并反序列化json文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆