Spring Boot ไม่แสดงเนื้อหาคงที่


173

ฉันไม่สามารถรับ Spring-boot project เพื่อแสดงเนื้อหาแบบคงที่ได้

ผมเคยวางโฟลเดอร์ชื่อภายใต้static ข้างในฉันมีโฟลเดอร์ชื่อsrc/main/resources imagesเมื่อฉันจัดทำแอพและเรียกใช้มันไม่สามารถค้นหารูปภาพที่ฉันวางไว้ในโฟลเดอร์นั้นได้

ฉันได้พยายามที่จะนำไฟล์คงในpublic, resourcesและMETA-INF/resourcesแต่ผลงานอะไร

ถ้าฉัน jar -tvf app.jar ฉันเห็นว่าไฟล์นั้นอยู่ใน jar ในโฟลเดอร์ด้านขวา: /static/images/head.pngตัวอย่างเช่น แต่เรียก: http://localhost:8080/images/head.pngสิ่งที่ฉันได้รับคือ404

แนวคิดใดที่ว่าทำไมสปริงบูตไม่พบสิ่งนี้? (ฉันใช้ 1.1.4 BTW)


6
การจัดการทรัพยากรเริ่มต้นแม็พกับ / ** ฉันตรวจสอบอีกครั้งว่าเปิดใช้งานแล้ว หากเป็นเช่นนั้นคุณจะเห็นบรรทัดที่ลงท้ายด้วย "เส้นทาง URL ที่ถูกแมป [/ **] ไปยังตัวจัดการประเภท [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]" ในผลลัพธ์เมื่อคุณเริ่มแอปของคุณ ความเป็นไปได้อีกอย่างคือตัวควบคุมของคุณเองที่ถูกแมปไปยัง / ** และมีความสำคัญเหนือกว่าตัวจัดการทรัพยากร การโพสต์ผลลัพธ์ของการเริ่มต้นแอพของคุณจะทำให้เราเห็นว่าเกิดอะไรขึ้นได้ง่ายขึ้น
Andy Wilkinson

12
ฉันคาดเดาว่าคุณมี@EnableWebMvc(หรือเทียบเท่า) ในแอปของคุณ ที่จะปิดการกำหนดค่า Boot MVC เริ่มต้น
Dave Syer

1
ไม่ฉันไม่มี @EnableWebMvc ที่ไหนก็ได้ ฉันไม่ได้รับสิ่งนี้ ตอนนี้มันเกิดขึ้นกับแม่แบบเช่นกัน เทมเพลตของฉัน (freemarker) ใด ๆ ถูกพบโดย classloader ของ spring boot
Vinicius Carvalho

2
ฉันพบปัญหาที่คล้ายกันและไม่มีโชคกับวิธีแก้ปัญหาที่แนะนำใด ๆ หากใครบางคนใจดีที่จะมองและชี้ให้เห็นอย่างชัดเจนว่ามันคืออะไรฉันทำผิดมันจะได้รับการชื่นชมมาก !!! github.com/kylebober/kbss
Kyle S. Bober

3
ฉันพบว่าถ้าฉันมีไฟล์ src / main / resources / public / style.css ดังนั้น URL สำหรับที่เป็น /style.css และไม่ใช่ /public/style.css ตามที่คาดไว้
เดฟ

คำตอบ:


179

เพื่อไม่ให้คนตายฟื้นขึ้นหลังจากผ่านไปหนึ่งปี แต่คำตอบก่อนหน้านี้ทั้งหมดพลาดจุดสำคัญบางอย่าง:

  1. @EnableWebMvcorg.springframework.boot.autoconfigure.web.WebMvcAutoConfigurationในชั้นเรียนของคุณจะปิดการใช้งาน ไม่เป็นไรถ้าคุณต้องการการควบคุมที่สมบูรณ์ แต่อย่างอื่นมันเป็นปัญหา
  2. ไม่จำเป็นต้องเขียนโค้ดใด ๆ เพื่อเพิ่มตำแหน่งอื่นสำหรับทรัพยากรแบบคงที่เพิ่มเติมจากสิ่งที่ให้ไว้แล้ว มองไปที่org.springframework.boot.autoconfigure.web.ResourcePropertiesจาก v1.3.0.RELEASE ผมเห็นช่องที่สามารถกำหนดค่าในstaticLocations application.propertiesนี่เป็นตัวอย่างข้อมูลจากแหล่งที่มา:

    /**
     * Locations of static resources. Defaults to classpath:[/META-INF/resources/,
     * /resources/, /static/, /public/] plus context:/ (the root of the servlet context).
     */
    private String[] staticLocations = RESOURCE_LOCATIONS;
  3. ดังที่ได้กล่าวไว้ก่อนหน้า URL คำขอจะได้รับการแก้ไขเมื่อเทียบกับตำแหน่งเหล่านี้ ดังนั้นsrc/main/resources/static/index.htmlจะทำหน้าที่เมื่อ URL /index.htmlคำขอเป็น ระดับที่เป็นผู้รับผิดชอบในการแก้ไขเส้นทางที่เป็นของฤดูใบไม้ผลิ 4.1 org.springframework.web.servlet.resource.PathResourceResolverเป็น

  4. คำต่อท้ายจับคู่รูปแบบถูกเปิดใช้งานโดยค่าเริ่มต้นซึ่งหมายถึงการ URL ที่ร้องขอฤดูใบไม้ผลิจะไปดูสำหรับตัวจัดการที่สอดคล้องกับ/index.html /index.htmlนี่เป็นปัญหาหากความตั้งใจที่จะให้บริการเนื้อหาคงที่ หากต้องการปิดใช้งานให้ขยายWebMvcConfigurerAdapter(แต่ไม่ใช้@EnableWebMvc) และแทนที่configurePathMatchตามที่แสดงด้านล่าง:

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        super.configurePathMatch(configurer);
    
        configurer.setUseSuffixPatternMatch(false);
    }

IMHO วิธีเดียวที่จะมีข้อบกพร่องในรหัสของคุณน้อยลงคือไม่ต้องเขียนโค้ดทุกครั้งที่ทำได้ ใช้สิ่งที่มีอยู่แล้วแม้ว่าจะต้องใช้การวิจัยบ้างผลตอบแทนก็คุ้มค่า


3
คำตอบนี้แน่นอนหลังจากการวิจัยมาก หนึ่งที่ดีในการอ่าน
Ekansh Rastogi

2
ถ้าฉันเป็นการพิจาณาฉันจะใช้คำตอบนี้และใส่ไว้ในเอกสารประกอบการบูตฤดูใบไม้ผลิ
aliopi

2
@Abhijit Sarkar ฉันหมายถึง บริษัทPivotalขออภัยในความรู้สึกที่ไม่ดี แต่มันไม่ได้ตั้งใจ Pivotal เป็นเจ้าของ Spring ถ้าฉันถูกต้อง ฉันสามารถบันทึกได้ แต่พวกเขามีคนที่ได้รับเงินสำหรับสิ่งนี้ดังนั้นพวกเขาควรทำ: P
aliopi

1
@aliopi Spring เป็นโครงการโอเพ่นซอร์ส
Abhijit Sarkar

3
วิธีเดียวที่จะมีข้อผิดพลาดน้อยลงในรหัสของคุณไม่ได้เขียนรหัส [... ]เช่นนี้
Clijsters

78

ซึ่งแตกต่างจากสิ่งที่รัฐ Spring-boot เพื่อให้ได้ jar-boot ฤดูใบไม้ผลิของฉันเพื่อให้บริการเนื้อหา: ฉันต้องเพิ่มการลงทะเบียนเนื้อหา src / main / resources / static ของฉันโดยเฉพาะผ่านคลาส config นี้:

@Configuration
public class StaticResourceConfiguration implements WebMvcConfigurer {

    private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
            "classpath:/META-INF/resources/", "classpath:/resources/",
            "classpath:/static/", "classpath:/public/" };

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
            .addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
    }
}

3
ฉันมีปัญหาเดียวกันกับ Spring Boot รุ่นเดียวกัน แต่สิ่งนี้ไม่ได้ผลสำหรับฉัน
greyfox

แก้ไขปัญหาของฉันในเวอร์ชัน 1.2.5 !! ขอบคุณมาก .. โหวตสิ่งนี้ !!
mrclrchtr

แฮ็คนี้ใช้งานได้ ... แปลกที่การกำหนดค่าอัตโนมัติล้มเหลว
Allan Vital

น่าเสียดายที่แฮ็คนี้ใช้ไม่ได้กับฉันซึ่งน่าละอายเนื่องจากความสง่างาม ฉันไม่แน่ใจว่าสาเหตุที่แท้จริงนั้นเป็นเส้นทางไปยังทรัพยากรหรือไม่ อาจเป็นเพราะฉันใช้งานใน windows พวกเขาจำเป็นต้องฟอร์แมตต่างกันหรือไม่
acarlstein

50

ฉันมีปัญหาที่คล้ายกันและปรากฎว่าโซลูชันง่าย ๆ คือการขยายระดับการกำหนดค่าของฉันWebMvcAutoConfiguration:

@Configuration
@EnableWebMvc
@ComponentScan
public class ServerConfiguration extends WebMvcAutoConfiguration{
}

ฉันไม่ต้องการรหัสอื่นใดเพื่อให้เนื้อหาแบบสแตติกของฉันสามารถให้บริการได้อย่างไรก็ตามฉันได้วางไดเรกทอรีที่เรียกใช้publicภายใต้src/main/webappและกำหนดค่า maven ให้ชี้ไปsrc/main/webappที่ไดเรกทอรีทรัพยากร ซึ่งหมายความว่าpublicจะถูกคัดลอกtarget/classesและดังนั้นจึงเป็น classpath ที่รันไทม์สำหรับ spring-boot / tomcat เพื่อค้นหา


ด้วยวิธีนี้ทรัพยากรสแตติกไม่ทำงานในโปรไฟล์อื่น เช่นฉันมีโปรไฟล์สำหรับการเปิดตัวที่ใช้ที่อยู่ IP อื่น ฉันได้รับข้อผิดพลาด 404 สำหรับทรัพยากรทั้งหมดของฉัน
มาห์ดี

24

ค้นหาตัวควบคุมที่แมปกับ "/" หรือไม่มีการแมปเส้นทาง

ฉันมีปัญหาเช่นนี้รับ 405 ข้อผิดพลาดและกระแทกหัวอย่างหนักเป็นเวลาหลายวัน ปัญหากลายเป็น@RestControllerตัวควบคุมคำอธิบายประกอบที่ฉันลืมที่จะใส่คำอธิบายประกอบด้วย@RequestMappingคำอธิบายประกอบ ฉันเดาเส้นทางที่แมปนี้เป็นค่าเริ่มต้นเป็น "/" และบล็อกการแมปทรัพยากรเนื้อหาแบบคงที่


1
แก้ไขได้สำหรับฉัน! ฉันมีตัวควบคุมที่มีคำอธิบายประกอบด้วย @RestController ("/ blubb") ซึ่งผิดปกติ แต่บางครั้งคุณไม่เห็นไม้สำหรับต้นไม้ เปลี่ยนเป็น @RestController @RequestMapping ("/ blubb") แก้ไขมันแล้ว
krinklesaurus

ฉันดีใจที่จะช่วยและขบขันโดยความคิดที่ว่าสำนวนที่ว่า "ไม่สามารถมองเห็นป่าสำหรับต้นไม้ทุกคน" ที่มีอยู่ในเยอรมันเช่นเดียวกับสวีเดน :)
โยฮันเน

2
คุณยังสามารถเพิ่ม @RequestMapping ("/") ได้อย่างชัดเจนหากเจตนาคือให้บริการเนื้อหาแบบคงที่และมีตัวจัดการแบบไดนามิกสำหรับคำขอรูท
mjj1409

1
ว้าว .... ใช้เวลา 2 วันในนี้ แอปพลิเคชัน spring boot mvc ของฉันใช้ความปลอดภัยแบบสปริงและไม่เห็นไฟล์ styles.css ฉันเชื่อว่าระบบความปลอดภัยไม่อนุญาตให้. jsp เข้าถึงไฟล์ styles.css ฉันมี @RequestMapping ({"", "/", "/ home"}) ในตัวควบคุมของฉัน เอา "" และ "/" และ MVC ของฉันเริ่มทำงานได้อย่างสมบูรณ์แบบ ... แปลกมาก
skmansfield

3
@Shafiul ไม่เพิ่มทั้ง EnableAutoConfiguration และ SpringBootApplication ซ้ำซ้อน! "@SpringBootApplication" มี "@EnableAutoConfiguration"
Dehan de Croos

19

การกำหนดค่าสามารถทำได้ดังนี้:

@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcAutoConfigurationAdapter {

// specific project configuration

}

สิ่งสำคัญในที่นี้คือว่าคุณWebMvcConfig อาจแทนที่addResourceHandlersวิธีการและดังนั้นคุณต้องเรียกใช้อย่างชัดเจนsuper.addResourceHandlers(registry)(เป็นความจริงที่ว่าถ้าคุณพอใจกับตำแหน่งทรัพยากรเริ่มต้นคุณไม่จำเป็นต้องแทนที่วิธีการใด ๆ )

อีกสิ่งหนึ่งที่จะต้องให้ความเห็นที่นี่เป็นที่บรรดาสถานที่ทรัพยากรเริ่มต้น ( /static, /public, /resourcesและ/META-INF/resources) /**จะได้รับการลงทะเบียนเท่านั้นถ้าไม่มีแล้วจัดการทรัพยากรแมปไป

นับจากนี้เป็นต้นไปหากคุณมีรูปภาพที่มีsrc/main/resources/static/imagesชื่อimage.jpgเป็นต้นคุณสามารถเข้าถึงได้โดยใช้ URL ต่อไปนี้: http://localhost:8080/images/image.jpg(เริ่มจากเซิร์ฟเวอร์ที่พอร์ต 8080 และแอปพลิเคชันที่ปรับใช้กับบริบทรูท)


อาจเป็นสิ่งสำคัญที่จะต้องแสดงความคิดเห็นว่าแม้ว่าคุณ / สามารถ / แทนที่ addResourceHandlers คุณไม่จำเป็นต้องแก้ไขปัญหาของ OP จริง ๆ
วิศวกรซอฟต์แวร์

@EngineerDollery ขอบคุณสำหรับความคิดเห็นนั่นเป็นความตั้งใจของฉัน แต่ฉันได้เพิ่มคำอธิบายอย่างชัดเจน
Francisco Spaeth

ฉันย้าย css / js ไปยังโฟลเดอร์ src / main / resources / static และข้อผิดพลาดไม่อยู่ที่นั่นอีกต่อไป แต่ฉันยังคงไม่สามารถรับ css เพื่อแสดงในหน้าของฉัน
Hatem Jaber

เพื่อนฉันเดินทางลึกของอินเทอร์เน็ตเพื่อหาวิธีแก้ปัญหาการทำงานนี้ ดูเหมือนว่าที่สำคัญคือการรวมกันของและ@EnableWebMvc WebMvcAutoConfigurationAdapterขอบคุณครั้งใหญ่!
เอียนนิวแลนด์

มันไม่ได้ผลนอกกรอบสำหรับฉันเช่นกัน ฉันต้องเพิ่มสิ่งนี้ด้วย ฉันแค่เพิ่มความเห็นของฉันที่นี่เพราะฉันมีสองปัญหา ฉันยังมีคอนโทรลเลอร์ที่แมป "/" ตามที่ @Jannann กล่าวถึง การทำเช่นนี้และลบตัวควบคุม "/" ของฉันแก้ไขปัญหาของฉันได้
LoyaltyBrown

11

คุณตรวจสอบเอกสารอ้างอิง Spring Boot แล้วหรือยัง

โดยค่าเริ่มต้น Spring Boot จะให้บริการเนื้อหาคงที่จากโฟลเดอร์ที่เรียกว่า/static(หรือ/publicหรือ/resourcesหรือ/META-INF/resources) ใน classpath หรือจากรูทของ ServletContext

นอกจากนี้คุณยังสามารถเปรียบเทียบโครงการของคุณกับคู่มือการให้บริการเนื้อหาเว็บที่มีฤดูใบไม้ผลิ MVCหรือตรวจสอบรหัสแหล่งที่มาของฤดูใบไม้ผลิบูตตัวอย่างเว็บ UIโครงการ


2
ใช่ฉันทำแล้วสถานที่เหล่านั้นคือสถานที่ที่ฉันพยายามเช่นเดียวกับที่เอกสารแนะนำ แต่ไม่มีอะไรทำงาน ฉันไม่เข้าใจว่าทำไมไม่พบทรัพยากรเลย ฉันพยายามตรวจสอบตัวอย่างแปลก ๆ ไม่มีตัวอย่างที่ใช้โครงสร้างที่เสนอโดยเอกสาร สิ่งที่คุณเพิ่งวางใช้โฟลเดอร์เทมเพลตฉันคิดว่านั่นคือสำหรับการกำหนดค่าไทม์ลีฟหรือความเร็ว
Vinicius Carvalho

ตัวอย่าง Web UI ( github.com/spring-projects/spring-boot/tree/v1.1.3.RELEASE/… ) ให้บริการเนื้อหาแบบคงที่
Andy Wilkinson

ฉันเห็นด้วยกับ @ViniciusCarvalho ฉันได้ลองชุดค่าผสมทุกตัวที่เป็นไปได้เพื่อให้ได้ CSS / js ในตำแหน่งที่ถูกต้องและดูเหมือนจะไม่สามารถทำได้ แม้ว่าฉันจะไปที่ localhost: 8089 / css / styles.css ฉันไม่เห็นอะไรเลย ฉันมีกฎเดียวเท่านั้นที่จะเปลี่ยนสีของร่างกาย
Hatem Jaber

10

ฉันมีปัญหาตรงนี้จากนั้นก็รู้ว่าฉันได้กำหนดไว้ในใบสมัครของฉันคุณสมบัติ:

spring.resources.static-locations=file:/var/www/static

ซึ่งเอาชนะทุกสิ่งอื่นที่ฉันได้ลอง ในกรณีของฉันฉันต้องการเก็บทั้งสองไว้ดังนั้นฉันจึงเก็บทรัพย์สินและเพิ่ม:

spring.resources.static-locations=file:/var/www/static,classpath:static

ไฟล์ใดที่ให้บริการจาก src / main / resources / static เป็น localhost: {port} /file.html

ข้อยกเว้นข้างต้นไม่ได้ผลสำหรับฉันเพราะไม่มีใครพูดถึงคุณสมบัติเล็ก ๆ น้อย ๆ ที่สามารถคัดลอกได้ง่ายจากออนไลน์เพื่อตอบสนองวัตถุประสงค์ที่แตกต่างกัน)

หวังว่ามันจะช่วย! คิดว่ามันจะพอดีกับคำตอบยาว ๆ สำหรับผู้ที่มีปัญหานี้


ฉันใช้ Spring Boot 2.0.5 ปล่อยและใส่spring.resources.static-locations=file:/var/www/static,classpath:staticเข้าไปใน application.properties ของฉัน แต่มันไม่ทำงานสำหรับฉัน ฉันกำลังใช้@EnableWebMvcกับคลาสการกำหนดค่าของฉัน
N. Ngo

นี่คือสิ่งที่แก้ไขปัญหาของฉัน พร้อมกับsecurity.ignoredและsecurity.publicPaths
JoSSte

5

ฉันคิดว่าคำตอบก่อนหน้าตอบหัวข้อได้ดีมาก อย่างไรก็ตามฉันขอเพิ่มไว้ในกรณีหนึ่งเมื่อคุณเปิดใช้งานการรักษาความปลอดภัยของสปริงในแอปพลิเคชันของคุณคุณอาจต้องบอกให้สปริงอนุญาตการร้องขอไปยังไดเรกทอรีทรัพยากรคงที่อื่น ๆ เช่น"/ static / fonts"โดยเฉพาะ

ในกรณีของฉันฉันมี "/ static / css", "/ static / js", "/ static / images" ที่ได้รับอนุญาตตามค่าเริ่มต้น แต่ / static / fonts / ** ถูกบล็อกโดยการใช้งาน Spring Security ของฉัน

ด้านล่างเป็นตัวอย่างของวิธีที่ฉันแก้ไขสิ่งนี้

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.....
    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/", "/fonts/**").permitAll().
        //other security configuration rules
    }
.....
}

5

เพิ่งเพิ่มอีกหนึ่งคำตอบสำหรับคำถามเก่า ... ผู้คนได้กล่าวถึง@EnableWebMvcจะป้องกันไม่ให้WebMvcAutoConfigurationโหลดซึ่งเป็นรหัสที่รับผิดชอบในการสร้างตัวจัดการทรัพยากรแบบคงที่ มีเงื่อนไขอื่น ๆ ที่จะป้องกันไม่ให้WebMvcAutoConfigurationโหลดเช่นกัน วิธีที่ชัดเจนที่สุดในการดูสิ่งนี้คือดูแหล่งที่มา:

https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ WebMvcAutoConfiguration.java # L139-L141

ในกรณีของฉันฉันรวมไลบรารีที่มีคลาสที่ขยายจากWebMvcConfigurationSupportซึ่งเป็นเงื่อนไขที่จะป้องกันการกำหนดค่าอัตโนมัติ:

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

มันเป็นสิ่งสำคัญที่จะไม่WebMvcConfigurationSupportขยายจาก WebMvcConfigurerAdapterแต่เพิ่มขึ้นจาก

ปรับปรุง: วิธีที่เหมาะสมในการทำเช่นนี้ใน 5.x คือการใช้ WebMvcConfigurer


WebMvcConfigurerAdapter เลิกใช้แล้วใน Spring Boot 5.0 Googling ปรากฎสิ่งนี้ใน Javadocs สำหรับคลาสนั้น: "ณ 5.0 WebMvcConfigurer มีวิธีการเริ่มต้น (ทำโดย Java 8 พื้นฐาน) และสามารถนำไปใช้โดยตรงโดยไม่จำเป็นต้องใช้อะแดปเตอร์นี้" ดังนั้นฉันจึงคิดว่าจะใช้ WebMvcConfigurer ในตอนนี้
Marvo

@Marvo ที่ถูกต้องแน่นอน วิธีการที่เหมาะสมที่จะทำเช่นนี้ใน 5.x WebMvcConfigurerคือการดำเนินการ
บาล

4

วิธีนี้ใช้ได้ผลสำหรับฉัน:

ก่อนอื่นให้วางโฟลเดอร์ทรัพยากรไว้ใต้ webapp / WEB-INF ตามโครงสร้าง

-- src
  -- main
    -- webapp
      -- WEB-INF
        -- resources
          -- css
          -- image
          -- js
          -- ...

ประการที่สองในไฟล์ config ฤดูใบไม้ผลิ

@Configuration
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter{

    @Bean
    public ViewResolver getViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".html");
        return resolver;
    }

    @Override
    public void configureDefaultServletHandling(
            DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resource/**").addResourceLocations("WEB-INF/resources/");
    }
}

จากนั้นคุณสามารถเข้าถึงเนื้อหาทรัพยากรของคุณเช่น http: // localhost: 8080 / resource / image / yourimage.jpg


3

มี 2 ​​สิ่งที่ควรพิจารณา (Spring Boot v1.5.2.RELEASE) - 1) ตรวจสอบคลาสควบคุมทั้งหมดสำหรับคำอธิบายประกอบ @EnableWebMvc ให้ลบออกหากมี 2) ตรวจสอบคลาสควบคุมที่ใช้คำอธิบายประกอบ - @RestController หรือ @Controller . อย่าผสมพฤติกรรม Rest API และ MVC ในหนึ่งคลาส สำหรับ MVC ให้ใช้ @Controller และสำหรับ REST API ให้ใช้ @RestController

การดำเนินการด้านบน 2 ข้อช่วยแก้ไขปัญหาของฉันได้ ตอนนี้สปริงบูตของฉันกำลังโหลดทรัพยากรแบบสแตติกโดยไม่มีปัญหาใด ๆ @Controller => load index.html => โหลดไฟล์สแตติก

@Controller
public class WelcomeController {

    // inject via application.properties
    @Value("${welcome.message:Hello}")
    private String message = "Hello World";

    @RequestMapping("/")
    public String home(Map<String, Object> model) {
        model.put("message", this.message);
        return "index";
    }

}

index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>index</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />


    <link rel="stylesheet/less" th:href="@{/webapp/assets/theme.siberia.less}"/>

    <!-- The app's logic -->
    <script type="text/javascript" data-main="/webapp/app" th:src="@{/webapp/libs/require.js}"></script>
    <script type="text/javascript">
        require.config({
            paths: { text:"/webapp/libs/text" }
        });
    </script>



   <!-- Development only -->
     <script type="text/javascript" th:src="@{/webapp/libs/less.min.js}"></script>


</head>
<body>

</body>
</html>

การลบ @EnableWebMvc ทำเพื่อฉัน! ขอบคุณ
turboemu

3

วางทรัพยากรแบบคงที่ภายใต้ไดเรกทอรี:

/src/main/resources/static

เพิ่มคุณสมบัตินี้ในไฟล์ application.properties

server.servlet.context-path=/pdx

คุณสามารถเข้าถึงได้จากhttp: // localhost: 8080 / pdx / images / image.jpg

ป้อนคำอธิบายรูปภาพที่นี่


1
ฉันไม่รู้จะพูดยังไงขอบคุณคุณ พี่ชายคุณยอดเยี่ยม ฉันพยายามแก้ไขเกือบทั้งหมดข้างต้น แต่นี่เป็นวิธีที่ดีที่สุดและสั้นที่สุด
user12061795

2

ในกรณีที่ปัญหาเกิดขึ้นเมื่อเรียกใช้แอปพลิเคชันจากภายใน IDE (เช่นเริ่มจาก Eclipse หรือ IntelliJ Idea) และการใช้ Maven กุญแจสู่การแก้ปัญหาอยู่ในเอกสารเริ่มต้นใช้งาน Spring-boot :

หากคุณใช้ Maven ให้ดำเนินการดังนี้

mvn package && java -jar target/gs-spring-boot-0.1.0.jar

ส่วนที่สำคัญคือการเพิ่มpackageเป้าหมายที่จะเรียกใช้ก่อนที่แอปพลิเคชันจะเริ่มขึ้นจริง (ความคิด: RunเมนูEdit Configrations..., AddและมีการเลือกRun Maven Goalและระบุpackageเป้าหมายในสนาม)


1

ฉันใช้ 1.3.5 และโฮสต์บริการ REST ผ่านการใช้ Jersey ใช้งานได้ดีจนกระทั่งฉันตัดสินใจเพิ่มไฟล์ HTML + js สองสามรายการ ไม่มีคำตอบในฟอรัมนี้ที่ช่วยฉันได้ อย่างไรก็ตามเมื่อฉันเพิ่มการติดตามต่อไปนี้ใน pom.xml เนื้อหาทั้งหมดในsrc / main / resources / staticในที่สุดก็แสดงผ่านเบราว์เซอร์:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<dependency>

ดูเหมือนว่า spring-web / spring-webmvc เป็นการพึ่งพาผ่านทางสกรรมกริยาสำคัญซึ่งทำให้การกำหนดค่าเริ่มต้นอัตโนมัติของ boot boot เปิด


1

FYI:ฉันยังสังเกตเห็นว่าฉันสามารถเลอะแอพการบูทบูทที่ทำงานได้อย่างสมบูรณ์และป้องกันไม่ให้บริการเนื้อหาจากโฟลเดอร์แบบสแตติกถ้าฉันเพิ่มตัวควบคุมส่วนที่เหลือที่ไม่ดีเช่นนั้น

 @RestController
public class BadController {
    @RequestMapping(method= RequestMethod.POST)
    public String someMethod(@RequestParam(value="date", required=false)String dateString, Model model){
        return "foo";
    }
}

ในตัวอย่างนี้หลังจากเพิ่มตัวควบคุมที่ไม่ดีลงในโครงการเมื่อเบราว์เซอร์ถามหาไฟล์ที่มีอยู่ในโฟลเดอร์คงที่การตอบสนองข้อผิดพลาดคือ ' 405 วิธีการไม่อนุญาต '

เส้นทางสังเกตุจะไม่ถูกแมปในตัวอย่างคอนโทรลเลอร์ที่ไม่ดี


1

ฉันกำลังเผชิญปัญหาเดียวกันในฤดูใบไม้ผลิบูต 2.1.3 บอกว่าทรัพยากรที่ไม่พบ 404 ฉันออกจากด้านล่างapplicatiion.properties

#spring.resources.add-mappings=true
#spring.resources.static-locations=classpath:static
#spring.mvc.static-path-pattern=/**,

ลบ @enableWebMVCและลบ WebMvcConfigurer ใด ๆ ที่แทนที่

// @ EnableWebMvc

ตรวจสอบให้แน่ใจด้วยว่าคุณมี@EnableAutoConfigurationในการกำหนดค่าของคุณ

และใส่ทรัพยากรสแตติกทั้งหมดลงในsrc / main / resources / staticและมันก็ทำงานเหมือนเวทมนตร์ในที่สุด ..


เวอร์ชั่นฤดูใบไม้ผลิของฉันใน 2.2.6 และฉันมี @EnableAutoConfiguration และไฟล์ภายใต้ src / main / resources / static แต่มันใช้งานไม่ได้และมีค่าใช้จ่ายถึง 500
shivani thakur

1

ใช้ spring boot 2. * ฉันมีคอนโทรลเลอร์ที่แมปเส้นทางGetMapping({"/{var}", "/{var1}/{var2}", "/{var1}/{var2}/{var3}"})และบูมแอปของฉันหยุดให้บริการทรัพยากร

ฉันรู้ว่าไม่แนะนำให้มีเส้นทางดังกล่าว แต่ทุกอย่างขึ้นอยู่กับแอพที่คุณกำลังสร้าง (ในกรณีของฉันฉันไม่มีทางเลือกนอกจากต้องมีเส้นทางดังกล่าว)

ดังนั้นนี่คือแฮ็คของฉันเพื่อให้แน่ใจว่าแอพของฉันให้บริการทรัพยากรอีกครั้ง ฉันมีตัวควบคุมที่แมปกับทรัพยากรของฉัน ตั้งแต่ฤดูใบไม้ผลิจะจับคู่กับเส้นทางตรงก่อนหน้าใด ๆ ที่มีตัวแปรฉันตัดสินใจที่จะเพิ่มวิธีการควบคุมที่แมป/imgaes/{name}และทำซ้ำเหมือนกันสำหรับทรัพยากรอื่น ๆ

@GetMapping(value = "/images/{image}", produces = {MediaType.IMAGE_GIF_VALUE, MediaType.IMAGE_JPEG_VALUE, MediaType.IMAGE_PNG_VALUE})
    public @ResponseBody
    byte[] getImage(@PathVariable String image) {
        ClassPathResource file = new ClassPathResource("static/images/" + image);
        byte[] bytes;
        try {
            bytes = StreamUtils.copyToByteArray(file.getInputStream());
        } catch (IOException e) {
            throw new ResourceNotFoundException("file not found: " + image);
        }
        return bytes;
    }

และนี่ช่วยแก้ไขปัญหาของฉันได้


0

มีปัญหาเดียวกันโดยใช้ gradle และ eclipse และใช้เวลาพยายามคิด

ไม่จำเป็นต้องมีการเข้ารหัสเคล็ดลับคือคุณต้องใช้ตัวเลือกเมนู New-> โฟลเดอร์ต้นทาง (ไม่ใช่ใหม่ -> โฟลเดอร์) เพื่อสร้างโฟลเดอร์แบบคงที่ภายใต้ src / main / resources ไม่ทราบว่าเหตุใดจึงใช้งานได้ แต่สร้างโฟลเดอร์ใหม่ -> ซอร์สแล้วฉันตั้งชื่อโฟลเดอร์ให้คงที่ (จากนั้นกล่องโต้ตอบโฟลเดอร์ต้นทางจะมีข้อผิดพลาดซึ่งคุณต้องตรวจสอบ: อัปเดตตัวกรองการยกเว้นในโฟลเดอร์แหล่งอื่น ๆ โฟลเดอร์คงใหม่ของฉันฉันเพิ่ม index.html และตอนนี้ก็ใช้งานได้


0

บางครั้งก็มีค่าที่จะตรวจสอบว่าคุณแทนที่การแมปทั่วโลกโดยตัวควบคุมส่วนที่เหลือ ตัวอย่างข้อผิดพลาดง่ายๆ (kotlin):

@RestController("/foo")
class TrainingController {

    @PostMapping
    fun bazz(@RequestBody newBody: CommandDto): CommandDto = return commandDto

}

ในกรณีข้างต้นคุณจะได้รับเมื่อคุณขอทรัพยากรแบบคงที่:

{
    title: "Method Not Allowed",
    status: 405,
    detail: "Request method 'GET' not supported",
    path: "/index.html"
}

เหตุผลที่มันอาจเป็นได้ว่าคุณต้องการที่จะ map @PostMappingไป/fooแต่ลืมเกี่ยวกับ@RequestMappingคำอธิบายประกอบใน@RestControllerระดับ ในกรณีนี้คำขอทั้งหมดจะถูกแมปPOSTและคุณจะไม่ได้รับเนื้อหาสแตติกในกรณีนี้


0

ได้รับทรัพยากรภายใต้ src / main / resources / static ถ้าคุณเพิ่มรหัสนี้แล้วเนื้อหาคงที่ทั้งหมดจาก src / main / resources / static จะสามารถใช้ได้ภายใต้ "/":

@Configuration
public class StaticResourcesConfigurer implements WebMvcConfigurer {
    public void addResourceHandlers(final ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/resources/static/");
    }
}

0

ในกรณีของฉันไฟล์สแตติกบางไฟล์ไม่ได้ให้บริการเช่นฟอนต์. woff และรูปภาพบางรูป แต่ css และ js ทำงานได้ดี

อัปเดต: วิธีแก้ปัญหาที่ดีกว่าในการทำให้ Spring Boot ให้บริการฟอนต์ woff ได้อย่างถูกต้องคือการกำหนดค่าการกรองทรัพยากรที่ระบุไว้ในคำตอบนี้ (โปรดทราบว่าคุณต้องการทั้งการรวมและไม่รวม):

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <excludes>
            <exclude>static/aui/fonts/**</exclude>
        </excludes>
    </resource>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>false</filtering>
        <includes>
            <include>static/aui/fonts/**</include>
        </includes>
    </resource>
</resources>

----- โซลูชั่นเก่า (ทำงานได้ แต่จะทำให้แบบอักษรเสียหาย) -----

อีกวิธีคือการปิดการใช้งานการจับคู่รูปแบบคำต่อท้ายด้วย setUseSuffixPatternMatch(false)

@Configuration
public class StaticResourceConfig implements WebMvcConfigurer {
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        // disable suffix matching to serve .woff, images, etc.
        configurer.setUseSuffixPatternMatch(false);
    }
}

เครดิต: @Abhiji ชี้ให้ฉันเป็น 4 ในทิศทางที่ถูกต้อง!


0

การร้องขอไปยัง / ** จะถูกประเมินเป็นตำแหน่งคงที่ที่กำหนดค่าใน resourceProperties resourceProperties

การเพิ่มสิ่งต่อไปนี้บน application.properties อาจเป็นสิ่งเดียวที่คุณต้องทำ ...

spring.resources.static-locations=classpath:/myresources/

สิ่งนี้จะเขียนทับตำแหน่งคงที่ที่เป็นค่าเริ่มต้นซึ่งคือ:

ResourceProperties.CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
        "classpath:/resources/", "classpath:/static/", "classpath:/public/" };

คุณอาจไม่ต้องการทำเช่นนั้นและตรวจสอบให้แน่ใจว่าทรัพยากรของคุณอยู่ในโฟลเดอร์เริ่มต้นหนึ่งในนั้น

การดำเนินการตามคำขอ: หากฉันต้องการเก็บ example.html ไว้ใน /public/example.html ฉันจะเข้าร่วมแบบนี้:

<host>/<context-path?if you have one>/example.html

หากฉันต้องการ<host>/<context-path>/magico/*ไฟล์uri อื่นที่ต้องการไฟล์ใน classpath: / magicofiles / * คุณต้องปรับแต่งเพิ่มอีกเล็กน้อย

@Configuration
class MyConfigClass implements WebMvcConfigurer

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/magico/**").addResourceLocations("/magicofiles/");
}

-1

ดังที่กล่าวไว้ข้างต้นไฟล์ควรอยู่ใน$ClassPath/static/images/name.png(/ static หรือ / public หรือ / resources หรือ / META-INF / resources) $ ClassPath นี้หมายถึงmain/resourcesหรือmain/javadir

หากไฟล์ของคุณไม่อยู่ในมาตรฐาน dirs คุณสามารถเพิ่มการกำหนดค่าต่อไปนี้:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/lib/**"); // like this
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        // ... etc.
}
...

}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.