Supercharge Your Local LLM: Web-Aware Chat with Spring AI, Ollama, and Jsoup
How I used Spring Boot, Ollama, and Jsoup to build a private chatbot that can actually browse the web.
Supercharge Your Local LLM: Web-Aware Chat with Spring AI, Ollama, and Jsoup
How I used Spring Boot, Ollama, and Jsoup to build a private chatbot that can actually browse the web.
I love running LLMs locally. Setting up Ollama with a model like Llama 3 or Qwen is great — fast, private, and fully under your control. But like all local LLMs, there’s one annoying limitation: they don’t know what’s happening right now. Ask about a new library version or the latest news, and you get the usual: “My knowledge cutoff is…” Ugh.
I got tired of that limitation, so I thought: what if I could give my AI “eyes”? Let it check the live web without losing the privacy I get from running it locally.
Turns out, it’s easier than I expected. The trick? A bit of Spring Boot, the new Spring AI framework, and a trusty friend: Jsoup.
My Setup: 100% Local, 0% Cloud APIs
Here’s the setup — and the best part? You can run all of it yourself. No API keys, no pay-per-token — just your local machine doing the work.
- Spring Boot (3.5.7): Our rock-solid API foundation.
- Spring AI (1.1.0): It makes calling Ollama from Java really easy.
- Jsoup (1.17.2): A super simple library for scraping web pages.
The whole idea follows a simple MCP (Model-Context-Prompt) pattern:
- Model: The Ollama LLM you want to use (Llama 3, Qwen, etc.).
- Context: Grab fresh data from the web with Jsoup.
- Prompt: Combine that context with the user’s question and system instructions so the model can generate an answer.
By wiring these pieces together, a local LLM suddenly becomes more than a static chatbot. It can pull fresh data, summarize news, track GitHub activity, or answer questions about any page you point it to — all running privately on your own machine.
Step 1: Fetch Web Content
Use a WebContentService to grab either a specific page or top search results. Truncate content so it fits within the model’s token window.
// In WebContentService.java
public String fetchWebContent(String url) {
try {
Document doc = Jsoup.connect(url)
.timeout(10000)
.userAgent("Mozilla/5.0 (compatible; SpringAI-Bot/1.0)")
.get();
String title = doc.title();
String bodyText = doc.body().text();
// Truncate to keep context manageable
if (bodyText.length() > 2000) {
bodyText = bodyText.substring(0, 2000) + "...";
}
return String.format("Title: %s\n\nContent: %s", title, bodyText);
} catch (IOException e) {
return "Error: Unable to fetch content.";
}
}
How do you do a web search without an API key? You scrape one! I used DuckDuckGo’s simple HTML version. It’s lightweight, easy to parse, and perfect for grabbing the top few results — title, snippet, and URL.
// In WebContentService.java
public String searchAndFetch(String query) {
String searchUrl = "https://html.duckduckgo.com/html/?q=" + query.replace(" ", "+");
// Connect and parse search results...
Document doc = Jsoup.connect(searchUrl).get();
// ... My logic to extract top 3 results ...
return results.toString();
}
Step 2: Combine Context with User Query
This is where the magic happens. We use Spring AI’s OllamaChatModel, but we wrap it in our own WebEnhancedChatService. This service is the conductor. When I send it a request (like ‘summarize this URL’), it:
- Calls my
WebContentServiceto get the raw text. - Creates a
SystemMessageto tell the AI how to behave ("You are an assistant... use this content..."). - It literally just stuffs the web content and my question into one big prompt. It’s that simple.
// In WebEnhancedChatService.java
public String replyWithWebContext(String userQuery, String url) {
// 1. Retrieve
String webContent = webContentService.fetchWebContent(url);
// 2. Set the rules
SystemMessage systemMessage = new SystemMessage(
"You are a helpful assistant. Use the provided web content to answer the user's question..."
);
// 3. Augment
String enhancedQuery = String.format(
"Web Content:\n%s\n\nUser Question: %s",
webContent, userQuery
);
// 4. Generate
UserMessage userMessage = new UserMessage(enhancedQuery);
Prompt chatPrompt = new Prompt(List.of(systemMessage, userMessage));
ChatResponse response = chatModel.call(chatPrompt);
return response.getResult().getOutput().getText();
}
I use the exact same pattern for the web search, just changing the system prompt to “Synthesize these search results…”.
Step 3: Hooking it Up to an API
Last step, we just need to hook this logic up to an API so we can actually use it. A standard WebChatController does the trick.
@RestController
@RequestMapping("/api/web-chat")
@AllArgsConstructor
public class WebChatController {
private final WebEnhancedChatService webEnhancedChatService;
@GetMapping("/with-url")
public String chatWithUrl(
@RequestParam String message,
@RequestParam String url) {
return webEnhancedChatService.replyWithWebContext(message, url);
}
@GetMapping("/with-search")
public String chatWithSearch(@RequestParam String query) {
return webEnhancedChatService.replyWithWebSearch(query);
}
}
And… That’s It! Now for the fun part. We can hit our API with curl and ask it about the real world.
Ask it to summarize a page:
curl -G "http://localhost:8080/api/web-chat/with-url" \
--data-urlencode "message=Summarize the key points" \
--data-urlencode "url=https://spring.io/projects/spring-ai"
Ask it a current question:
curl -G "http://localhost:8080/api/web-chat/with-search" \
--data-urlencode "query=What are the latest features in Java 21?"
By combining Jsoup and Ollama with Spring AI, we’ve built something stronger than the sum of its parts. It’s not just a static chatbot — it’s a dynamic chat assistant. You could turn this into a personal news summarizer, a bot that watches GitHub repos, or anything else — all running privately on your own machine.
Project Source: The complete code for this project is available on GitHub: https://github.com/taninme/spring-boot-ollama-sample
메타데이터
- post_id
- 86a0d522b1ee
- slug
- supercharge-your-local-llm-web-aware-chat-with-spring-ai-ollama-and-jsoup-86a0d522b1ee
- url
- https://medium.com/@aferdousahmed/supercharge-your-local-llm-web-aware-chat-with-spring-ai-ollama-and-jsoup-86a0d522b1ee
- canonical_url
- https://medium.com/@aferdousahmed/supercharge-your-local-llm-web-aware-chat-with-spring-ai-ollama-and-jsoup-86a0d522b1ee
- author_url
- https://medium.com/@aferdousahmed
- status
- ok
- fetched_at
- 2026-07-15 08:22:34